Merge nommu tree
This commit is contained in:
commit
ae574a5d7a
|
@ -72,6 +72,14 @@ config FIQ
|
|||
config ARCH_MTD_XIP
|
||||
bool
|
||||
|
||||
config VECTORS_BASE
|
||||
hex
|
||||
default 0xffff0000 if MMU
|
||||
default DRAM_BASE if REMAP_VECTORS_TO_RAM
|
||||
default 0x00000000
|
||||
help
|
||||
The base address of exception vectors.
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
menu "System Type"
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Kconfig for uClinux(non-paged MM) depend configurations
|
||||
# Hyok S. Choi <hyok.choi@samsung.com>
|
||||
#
|
||||
|
||||
config SET_MEM_PARAM
|
||||
bool "Set flash/sdram size and base addr"
|
||||
help
|
||||
Say Y to manually set the base addresses and sizes.
|
||||
otherwise, the default values are assigned.
|
||||
|
||||
config DRAM_BASE
|
||||
hex '(S)DRAM Base Address' if SET_MEM_PARAM
|
||||
default 0x00800000
|
||||
|
||||
config DRAM_SIZE
|
||||
hex '(S)DRAM SIZE' if SET_MEM_PARAM
|
||||
default 0x00800000
|
||||
|
||||
config FLASH_MEM_BASE
|
||||
hex 'FLASH Base Address' if SET_MEM_PARAM
|
||||
default 0x00400000
|
||||
|
||||
config FLASH_SIZE
|
||||
hex 'FLASH Size' if SET_MEM_PARAM
|
||||
default 0x00400000
|
||||
|
||||
config REMAP_VECTORS_TO_RAM
|
||||
bool 'Install vectors to the begining of RAM' if DRAM_BASE
|
||||
depends on DRAM_BASE
|
||||
help
|
||||
The kernel needs to change the hardware exception vectors.
|
||||
In nommu mode, the hardware exception vectors are normally
|
||||
placed at address 0x00000000. However, this region may be
|
||||
occupied by read-only memory depending on H/W design.
|
||||
|
||||
If the region contains read-write memory, say 'n' here.
|
||||
|
||||
If your CPU provides a remap facility which allows the exception
|
||||
vectors to be mapped to writable memory, say 'n' here.
|
||||
|
||||
Otherwise, say 'y' here. In this case, the kernel will require
|
||||
external support to redirect the hardware exception vectors to
|
||||
the writable versions located at DRAM_BASE.
|
|
@ -20,6 +20,11 @@ GZFLAGS :=-9
|
|||
# Select a platform tht is kept up-to-date
|
||||
KBUILD_DEFCONFIG := versatile_defconfig
|
||||
|
||||
# defines filename extension depending memory manement type.
|
||||
ifeq ($(CONFIG_MMU),)
|
||||
MMUEXT := -nommu
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FRAME_POINTER),y)
|
||||
CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
|
||||
endif
|
||||
|
@ -73,7 +78,7 @@ AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
|
|||
CHECKFLAGS += -D__arm__
|
||||
|
||||
#Default value
|
||||
head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o
|
||||
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
|
||||
textofs-y := 0x00008000
|
||||
|
||||
machine-$(CONFIG_ARCH_RPC) := rpc
|
||||
|
@ -133,7 +138,7 @@ else
|
|||
MACHINE :=
|
||||
endif
|
||||
|
||||
export TEXT_OFFSET GZFLAGS
|
||||
export TEXT_OFFSET GZFLAGS MMUEXT
|
||||
|
||||
# Do we have FASTFPE?
|
||||
FASTFPE :=arch/arm/fastfpe
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* linux/arch/arm/boot/compressed/head.S
|
||||
*
|
||||
* Copyright (C) 1996-2002 Russell King
|
||||
* Copyright (C) 2004 Hyok S. Choi (MPU support)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -320,6 +321,62 @@ params: ldr r0, =params_phys
|
|||
cache_on: mov r3, #8 @ cache_on function
|
||||
b call_cache_fn
|
||||
|
||||
/*
|
||||
* Initialize the highest priority protection region, PR7
|
||||
* to cover all 32bit address and cacheable and bufferable.
|
||||
*/
|
||||
__armv4_mpu_cache_on:
|
||||
mov r0, #0x3f @ 4G, the whole
|
||||
mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
|
||||
mcr p15, 0, r0, c6, c7, 1
|
||||
|
||||
mov r0, #0x80 @ PR7
|
||||
mcr p15, 0, r0, c2, c0, 0 @ D-cache on
|
||||
mcr p15, 0, r0, c2, c0, 1 @ I-cache on
|
||||
mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
|
||||
|
||||
mov r0, #0xc000
|
||||
mcr p15, 0, r0, c5, c0, 1 @ I-access permission
|
||||
mcr p15, 0, r0, c5, c0, 0 @ D-access permission
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
||||
mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
|
||||
mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
@ ...I .... ..D. WC.M
|
||||
orr r0, r0, #0x002d @ .... .... ..1. 11.1
|
||||
orr r0, r0, #0x1000 @ ...1 .... .... ....
|
||||
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
|
||||
mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
|
||||
mov pc, lr
|
||||
|
||||
__armv3_mpu_cache_on:
|
||||
mov r0, #0x3f @ 4G, the whole
|
||||
mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
|
||||
|
||||
mov r0, #0x80 @ PR7
|
||||
mcr p15, 0, r0, c2, c0, 0 @ cache on
|
||||
mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
|
||||
|
||||
mov r0, #0xc000
|
||||
mcr p15, 0, r0, c5, c0, 0 @ access permission
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
@ .... .... .... WC.M
|
||||
orr r0, r0, #0x000d @ .... .... .... 11.1
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mov pc, lr
|
||||
|
||||
__setup_mmu: sub r3, r4, #16384 @ Page directory size
|
||||
bic r3, r3, #0xff @ Align the pointer
|
||||
bic r3, r3, #0x3f00
|
||||
|
@ -496,6 +553,18 @@ proc_types:
|
|||
b __armv4_mmu_cache_off
|
||||
mov pc, lr
|
||||
|
||||
.word 0x41007400 @ ARM74x
|
||||
.word 0xff00ff00
|
||||
b __armv3_mpu_cache_on
|
||||
b __armv3_mpu_cache_off
|
||||
b __armv3_mpu_cache_flush
|
||||
|
||||
.word 0x41009400 @ ARM94x
|
||||
.word 0xff00ff00
|
||||
b __armv4_mpu_cache_on
|
||||
b __armv4_mpu_cache_off
|
||||
b __armv4_mpu_cache_flush
|
||||
|
||||
.word 0x00007000 @ ARM7 IDs
|
||||
.word 0x0000f000
|
||||
mov pc, lr
|
||||
|
@ -562,6 +631,24 @@ proc_types:
|
|||
cache_off: mov r3, #12 @ cache_off function
|
||||
b call_cache_fn
|
||||
|
||||
__armv4_mpu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
||||
mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
|
||||
mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
|
||||
mov pc, lr
|
||||
|
||||
__armv3_mpu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mov pc, lr
|
||||
|
||||
__armv4_mmu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
|
@ -601,6 +688,24 @@ cache_clean_flush:
|
|||
mov r3, #16
|
||||
b call_cache_fn
|
||||
|
||||
__armv4_mpu_cache_flush:
|
||||
mov r2, #1
|
||||
mov r3, #0
|
||||
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
|
||||
mov r1, #7 << 5 @ 8 segments
|
||||
1: orr r3, r1, #63 << 26 @ 64 entries
|
||||
2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
|
||||
subs r3, r3, #1 << 26
|
||||
bcs 2b @ entries 63 to 0
|
||||
subs r1, r1, #1 << 5
|
||||
bcs 1b @ segments 7 to 0
|
||||
|
||||
teq r2, #0
|
||||
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
|
||||
mcr p15, 0, ip, c7, c10, 4 @ drain WB
|
||||
mov pc, lr
|
||||
|
||||
|
||||
__armv6_mmu_cache_flush:
|
||||
mov r1, #0
|
||||
mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
|
||||
|
@ -638,6 +743,7 @@ no_cache_id:
|
|||
mov pc, lr
|
||||
|
||||
__armv3_mmu_cache_flush:
|
||||
__armv3_mpu_cache_flush:
|
||||
mov r1, #0
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mov pc, lr
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* linux/arch/arm/kernel/head-common.S
|
||||
*
|
||||
* Copyright (C) 1994-2002 Russell King
|
||||
* Copyright (c) 2003 ARM Limited
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
.type __switch_data, %object
|
||||
__switch_data:
|
||||
.long __mmap_switched
|
||||
.long __data_loc @ r4
|
||||
.long __data_start @ r5
|
||||
.long __bss_start @ r6
|
||||
.long _end @ r7
|
||||
.long processor_id @ r4
|
||||
.long __machine_arch_type @ r5
|
||||
.long cr_alignment @ r6
|
||||
.long init_thread_union + THREAD_START_SP @ sp
|
||||
|
||||
/*
|
||||
* The following fragment of code is executed with the MMU on in MMU mode,
|
||||
* and uses absolute addresses; this is not position independent.
|
||||
*
|
||||
* r0 = cp#15 control register
|
||||
* r1 = machine ID
|
||||
* r9 = processor ID
|
||||
*/
|
||||
.type __mmap_switched, %function
|
||||
__mmap_switched:
|
||||
adr r3, __switch_data + 4
|
||||
|
||||
ldmia r3!, {r4, r5, r6, r7}
|
||||
cmp r4, r5 @ Copy data segment if needed
|
||||
1: cmpne r5, r6
|
||||
ldrne fp, [r4], #4
|
||||
strne fp, [r5], #4
|
||||
bne 1b
|
||||
|
||||
mov fp, #0 @ Clear BSS (and zero fp)
|
||||
1: cmp r6, r7
|
||||
strcc fp, [r6],#4
|
||||
bcc 1b
|
||||
|
||||
ldmia r3, {r4, r5, r6, sp}
|
||||
str r9, [r4] @ Save processor ID
|
||||
str r1, [r5] @ Save machine type
|
||||
bic r4, r0, #CR_A @ Clear 'A' bit
|
||||
stmia r6, {r0, r4} @ Save control register values
|
||||
b start_kernel
|
||||
|
||||
/*
|
||||
* Exception handling. Something went wrong and we can't proceed. We
|
||||
* ought to tell the user, but since we don't have any guarantee that
|
||||
* we're even running on the right architecture, we do virtually nothing.
|
||||
*
|
||||
* If CONFIG_DEBUG_LL is set we try to print out something about the error
|
||||
* and hope for the best (useful if bootloader fails to pass a proper
|
||||
* machine ID for example).
|
||||
*/
|
||||
|
||||
.type __error_p, %function
|
||||
__error_p:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
adr r0, str_p1
|
||||
bl printascii
|
||||
b __error
|
||||
str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error_a, %function
|
||||
__error_a:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
mov r4, r1 @ preserve machine ID
|
||||
adr r0, str_a1
|
||||
bl printascii
|
||||
mov r0, r4
|
||||
bl printhex8
|
||||
adr r0, str_a2
|
||||
bl printascii
|
||||
adr r3, 3f
|
||||
ldmia r3, {r4, r5, r6} @ get machine desc list
|
||||
sub r4, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r4 @ convert virt addresses to
|
||||
add r6, r6, r4 @ physical address space
|
||||
1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
bl printhex8
|
||||
mov r0, #'\t'
|
||||
bl printch
|
||||
ldr r0, [r5, #MACHINFO_NAME] @ get machine name
|
||||
add r0, r0, r4
|
||||
bl printascii
|
||||
mov r0, #'\n'
|
||||
bl printch
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
adr r0, str_a3
|
||||
bl printascii
|
||||
b __error
|
||||
str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
|
||||
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
|
||||
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error, %function
|
||||
__error:
|
||||
#ifdef CONFIG_ARCH_RPC
|
||||
/*
|
||||
* Turn the screen red on a error - RiscPC only.
|
||||
*/
|
||||
mov r0, #0x02000000
|
||||
mov r3, #0x11
|
||||
orr r3, r3, r3, lsl #8
|
||||
orr r3, r3, r3, lsl #16
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
#endif
|
||||
1: mov r0, r0
|
||||
b 1b
|
||||
|
||||
|
||||
/*
|
||||
* Read processor ID register (CP#15, CR0), and look up in the linker-built
|
||||
* supported processor list. Note that we can't use the absolute addresses
|
||||
* for the __proc_info lists since we aren't running with the MMU on
|
||||
* (and therefore, we are not in the correct address space). We have to
|
||||
* calculate the offset.
|
||||
*
|
||||
* r9 = cpuid
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = proc_info pointer in physical address space
|
||||
* r9 = cpuid (preserved)
|
||||
*/
|
||||
.type __lookup_processor_type, %function
|
||||
__lookup_processor_type:
|
||||
adr r3, 3f
|
||||
ldmda r3, {r5 - r7}
|
||||
sub r3, r3, r7 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldmia r5, {r3, r4} @ value, mask
|
||||
and r4, r4, r9 @ mask wanted bits
|
||||
teq r3, r4
|
||||
beq 2f
|
||||
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown processor
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_processor_type)
|
||||
stmfd sp!, {r4 - r7, r9, lr}
|
||||
mov r9, r0
|
||||
bl __lookup_processor_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r7, r9, pc}
|
||||
|
||||
/*
|
||||
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
|
||||
* more information about the __proc_info and __arch_info structures.
|
||||
*/
|
||||
.long __proc_info_begin
|
||||
.long __proc_info_end
|
||||
3: .long .
|
||||
.long __arch_info_begin
|
||||
.long __arch_info_end
|
||||
|
||||
/*
|
||||
* Lookup machine architecture in the linker-build list of architectures.
|
||||
* Note that we can't use the absolute addresses for the __arch_info
|
||||
* lists since we aren't running with the MMU on (and therefore, we are
|
||||
* not in the correct address space). We have to calculate the offset.
|
||||
*
|
||||
* r1 = machine architecture number
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = mach_info pointer in physical address space
|
||||
*/
|
||||
.type __lookup_machine_type, %function
|
||||
__lookup_machine_type:
|
||||
adr r3, 3b
|
||||
ldmia r3, {r4, r5, r6}
|
||||
sub r3, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
teq r3, r1 @ matches loader number?
|
||||
beq 2f @ found
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown machine
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_machine_type)
|
||||
stmfd sp!, {r4 - r6, lr}
|
||||
mov r1, r0
|
||||
bl __lookup_machine_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r6, pc}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* linux/arch/arm/kernel/head-nommu.S
|
||||
*
|
||||
* Copyright (C) 1994-2002 Russell King
|
||||
* Copyright (C) 2003-2006 Hyok S. Choi
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Common kernel startup code (non-paged MM)
|
||||
* for 32-bit CPUs which has a process ID register(CP15).
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/procinfo.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/constants.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define PROCINFO_INITFUNC 12
|
||||
|
||||
/*
|
||||
* Kernel startup entry point.
|
||||
* ---------------------------
|
||||
*
|
||||
* This is normally called from the decompressor code. The requirements
|
||||
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
|
||||
* r1 = machine nr.
|
||||
*
|
||||
* See linux/arch/arm/tools/mach-types for the complete list of machine
|
||||
* numbers for r1.
|
||||
*
|
||||
*/
|
||||
__INIT
|
||||
.type stext, %function
|
||||
ENTRY(stext)
|
||||
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
|
||||
@ and irqs disabled
|
||||
mrc p15, 0, r9, c0, c0 @ get processor id
|
||||
bl __lookup_processor_type @ r5=procinfo r9=cpuid
|
||||
movs r10, r5 @ invalid processor (r5=0)?
|
||||
beq __error_p @ yes, error 'p'
|
||||
bl __lookup_machine_type @ r5=machinfo
|
||||
movs r8, r5 @ invalid machine (r5=0)?
|
||||
beq __error_a @ yes, error 'a'
|
||||
|
||||
ldr r13, __switch_data @ address to jump to after
|
||||
@ the initialization is done
|
||||
adr lr, __after_proc_init @ return (PIC) address
|
||||
add pc, r10, #PROCINFO_INITFUNC
|
||||
|
||||
/*
|
||||
* Set the Control Register and Read the process ID.
|
||||
*/
|
||||
.type __after_proc_init, %function
|
||||
__after_proc_init:
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
#ifdef CONFIG_ALIGNMENT_TRAP
|
||||
orr r0, r0, #CR_A
|
||||
#else
|
||||
bic r0, r0, #CR_A
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_DCACHE_DISABLE
|
||||
bic r0, r0, #CR_C
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_BPREDICT_DISABLE
|
||||
bic r0, r0, #CR_Z
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_ICACHE_DISABLE
|
||||
bic r0, r0, #CR_I
|
||||
#endif
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
||||
mov pc, r13 @ clear the BSS and jump
|
||||
@ to start_kernel
|
||||
|
||||
#include "head-common.S"
|
|
@ -102,49 +102,6 @@ ENTRY(stext)
|
|||
adr lr, __enable_mmu @ return (PIC) address
|
||||
add pc, r10, #PROCINFO_INITFUNC
|
||||
|
||||
.type __switch_data, %object
|
||||
__switch_data:
|
||||
.long __mmap_switched
|
||||
.long __data_loc @ r4
|
||||
.long __data_start @ r5
|
||||
.long __bss_start @ r6
|
||||
.long _end @ r7
|
||||
.long processor_id @ r4
|
||||
.long __machine_arch_type @ r5
|
||||
.long cr_alignment @ r6
|
||||
.long init_thread_union + THREAD_START_SP @ sp
|
||||
|
||||
/*
|
||||
* The following fragment of code is executed with the MMU on, and uses
|
||||
* absolute addresses; this is not position independent.
|
||||
*
|
||||
* r0 = cp#15 control register
|
||||
* r1 = machine ID
|
||||
* r9 = processor ID
|
||||
*/
|
||||
.type __mmap_switched, %function
|
||||
__mmap_switched:
|
||||
adr r3, __switch_data + 4
|
||||
|
||||
ldmia r3!, {r4, r5, r6, r7}
|
||||
cmp r4, r5 @ Copy data segment if needed
|
||||
1: cmpne r5, r6
|
||||
ldrne fp, [r4], #4
|
||||
strne fp, [r5], #4
|
||||
bne 1b
|
||||
|
||||
mov fp, #0 @ Clear BSS (and zero fp)
|
||||
1: cmp r6, r7
|
||||
strcc fp, [r6],#4
|
||||
bcc 1b
|
||||
|
||||
ldmia r3, {r4, r5, r6, sp}
|
||||
str r9, [r4] @ Save processor ID
|
||||
str r1, [r5] @ Save machine type
|
||||
bic r4, r0, #CR_A @ Clear 'A' bit
|
||||
stmia r6, {r0, r4} @ Save control register values
|
||||
b start_kernel
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
.type secondary_startup, #function
|
||||
ENTRY(secondary_startup)
|
||||
|
@ -367,166 +324,4 @@ __create_page_tables:
|
|||
mov pc, lr
|
||||
.ltorg
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Exception handling. Something went wrong and we can't proceed. We
|
||||
* ought to tell the user, but since we don't have any guarantee that
|
||||
* we're even running on the right architecture, we do virtually nothing.
|
||||
*
|
||||
* If CONFIG_DEBUG_LL is set we try to print out something about the error
|
||||
* and hope for the best (useful if bootloader fails to pass a proper
|
||||
* machine ID for example).
|
||||
*/
|
||||
|
||||
.type __error_p, %function
|
||||
__error_p:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
adr r0, str_p1
|
||||
bl printascii
|
||||
b __error
|
||||
str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error_a, %function
|
||||
__error_a:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
mov r4, r1 @ preserve machine ID
|
||||
adr r0, str_a1
|
||||
bl printascii
|
||||
mov r0, r4
|
||||
bl printhex8
|
||||
adr r0, str_a2
|
||||
bl printascii
|
||||
adr r3, 3f
|
||||
ldmia r3, {r4, r5, r6} @ get machine desc list
|
||||
sub r4, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r4 @ convert virt addresses to
|
||||
add r6, r6, r4 @ physical address space
|
||||
1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
bl printhex8
|
||||
mov r0, #'\t'
|
||||
bl printch
|
||||
ldr r0, [r5, #MACHINFO_NAME] @ get machine name
|
||||
add r0, r0, r4
|
||||
bl printascii
|
||||
mov r0, #'\n'
|
||||
bl printch
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
adr r0, str_a3
|
||||
bl printascii
|
||||
b __error
|
||||
str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
|
||||
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
|
||||
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error, %function
|
||||
__error:
|
||||
#ifdef CONFIG_ARCH_RPC
|
||||
/*
|
||||
* Turn the screen red on a error - RiscPC only.
|
||||
*/
|
||||
mov r0, #0x02000000
|
||||
mov r3, #0x11
|
||||
orr r3, r3, r3, lsl #8
|
||||
orr r3, r3, r3, lsl #16
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
#endif
|
||||
1: mov r0, r0
|
||||
b 1b
|
||||
|
||||
|
||||
/*
|
||||
* Read processor ID register (CP#15, CR0), and look up in the linker-built
|
||||
* supported processor list. Note that we can't use the absolute addresses
|
||||
* for the __proc_info lists since we aren't running with the MMU on
|
||||
* (and therefore, we are not in the correct address space). We have to
|
||||
* calculate the offset.
|
||||
*
|
||||
* r9 = cpuid
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = proc_info pointer in physical address space
|
||||
* r9 = cpuid (preserved)
|
||||
*/
|
||||
.type __lookup_processor_type, %function
|
||||
__lookup_processor_type:
|
||||
adr r3, 3f
|
||||
ldmda r3, {r5 - r7}
|
||||
sub r3, r3, r7 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldmia r5, {r3, r4} @ value, mask
|
||||
and r4, r4, r9 @ mask wanted bits
|
||||
teq r3, r4
|
||||
beq 2f
|
||||
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown processor
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_processor_type)
|
||||
stmfd sp!, {r4 - r7, r9, lr}
|
||||
mov r9, r0
|
||||
bl __lookup_processor_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r7, r9, pc}
|
||||
|
||||
/*
|
||||
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
|
||||
* more information about the __proc_info and __arch_info structures.
|
||||
*/
|
||||
.long __proc_info_begin
|
||||
.long __proc_info_end
|
||||
3: .long .
|
||||
.long __arch_info_begin
|
||||
.long __arch_info_end
|
||||
|
||||
/*
|
||||
* Lookup machine architecture in the linker-build list of architectures.
|
||||
* Note that we can't use the absolute addresses for the __arch_info
|
||||
* lists since we aren't running with the MMU on (and therefore, we are
|
||||
* not in the correct address space). We have to calculate the offset.
|
||||
*
|
||||
* r1 = machine architecture number
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = mach_info pointer in physical address space
|
||||
*/
|
||||
.type __lookup_machine_type, %function
|
||||
__lookup_machine_type:
|
||||
adr r3, 3b
|
||||
ldmia r3, {r4, r5, r6}
|
||||
sub r3, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
teq r3, r1 @ matches loader number?
|
||||
beq 2f @ found
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown machine
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_machine_type)
|
||||
stmfd sp!, {r4 - r6, lr}
|
||||
mov r1, r0
|
||||
bl __lookup_machine_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r6, pc}
|
||||
#include "head-common.S"
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#define KERN_SIGRETURN_CODE 0xffff0500
|
||||
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
|
||||
|
||||
extern const unsigned long sigreturn_codes[7];
|
||||
|
|
|
@ -688,6 +688,7 @@ EXPORT_SYMBOL(abort);
|
|||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
unsigned long vectors = CONFIG_VECTORS_BASE;
|
||||
extern char __stubs_start[], __stubs_end[];
|
||||
extern char __vectors_start[], __vectors_end[];
|
||||
extern char __kuser_helper_start[], __kuser_helper_end[];
|
||||
|
@ -698,9 +699,9 @@ void __init trap_init(void)
|
|||
* into the vector page, mapped at 0xffff0000, and ensure these
|
||||
* are visible to the instruction stream.
|
||||
*/
|
||||
memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
|
||||
memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
|
||||
memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
|
||||
memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
|
||||
memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
|
||||
memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
|
||||
|
||||
/*
|
||||
* Copy signal return handlers into the vector page, and
|
||||
|
@ -709,6 +710,6 @@ void __init trap_init(void)
|
|||
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
|
||||
sizeof(sigreturn_codes));
|
||||
|
||||
flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
|
||||
flush_icache_range(vectors, vectors + PAGE_SIZE);
|
||||
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue