diff options
-rw-r--r-- | arch/arm/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/Kconfig-nommu | 44 | ||||
-rw-r--r-- | arch/arm/Makefile | 9 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 106 | ||||
-rw-r--r-- | arch/arm/kernel/head-common.S | 217 | ||||
-rw-r--r-- | arch/arm/kernel/head-nommu.S | 83 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 207 | ||||
-rw-r--r-- | arch/arm/kernel/signal.h | 2 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 9 |
9 files changed, 472 insertions, 213 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 427c72140110..1077c671256f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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" diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu new file mode 100644 index 000000000000..e1574be2ded6 --- /dev/null +++ b/arch/arm/Kconfig-nommu @@ -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. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ce3e804ea0f3..95a96275f88a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -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 diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 491c7e4c9ac6..b56f5e691d65 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -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 diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S new file mode 100644 index 000000000000..a52da0ddb43d --- /dev/null +++ b/arch/arm/kernel/head-common.S @@ -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} diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S new file mode 100644 index 000000000000..b093ab8738b5 --- /dev/null +++ b/arch/arm/kernel/head-nommu.S @@ -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" diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 53b6901f70a6..04b66a9328ef 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.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" diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h index 9991049c522d..27beece15502 100644 --- a/arch/arm/kernel/signal.h +++ b/arch/arm/kernel/signal.h @@ -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]; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index d566d5f4574d..35230a060108 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -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); } |