forked from grate-driver/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch adds nommu version start-up code head-nommu.S. The common part of the start-up codes is moved to head-common.S. Signed-off-by: Hyok S. Choi <hyok.choi@samsung.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
- Loading branch information
Showing
4 changed files
with
302 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
Oops, something went wrong.