patch-2.2.18 linux/arch/arm/kernel/head-armv.S
Next file: linux/arch/arm/kernel/hw-ebsa285.c
Previous file: linux/arch/arm/kernel/fiq.c
Back to the patch index
Back to the overall index
- Lines: 721
- Date:
Fri Sep 15 23:28:37 2000
- Orig file:
v2.2.17/arch/arm/kernel/head-armv.S
- Orig date:
Fri Apr 21 12:45:45 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/arch/arm/kernel/head-armv.S linux/arch/arm/kernel/head-armv.S
@@ -1,157 +1,238 @@
/*
- * linux/arch/arm/kernel/head32.S
+ * linux/arch/arm/kernel/head-armv.S
*
- * Copyright (C) 1994-1998 Russell King
+ * Copyright (C) 1994-1999 Russell King
*
- * Kernel 32 bit startup code for ARM6 / ARM7 / StrongARM
+ * 32-bit kernel startup code for all architectures
*/
#include <linux/config.h>
#include <linux/linkage.h>
-#ifndef CONFIG_ARCH_VNC
+#include <asm/assembler.h>
+
#if (TEXTADDR & 0xffff) != 0x8000
#error TEXTADDR must start at 0xXXXX8000
#endif
-#else
- .text
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
- mov r0, r0
+
+#define SWAPPER_PGDIR_OFFSET 0x4000
+
+ .globl SYMBOL_NAME(swapper_pg_dir)
+ .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x8000 + SWAPPER_PGDIR_OFFSET
+
+ .section ".text.init",#alloc,#execinstr
+ENTRY(stext)
+ENTRY(_stext)
+
+#ifdef CONFIG_ARCH_NETWINDER
+/*
+ * Compatability cruft for old NetWinder NeTTroms. This
+ * code is currently scheduled for destruction in 2.5.xx
+ */
+ .rept 8
mov r0, r0
+ .endr
+
+ adr r2, 1f
+ ldmdb r2, {r7, r8}
+ and r3, r2, #0xc000
+ teq r3, #0x8000
+ beq __entry
+ bic r3, r2, #0xc000
+ orr r3, r3, #0x8000
+ mov r0, r3
+ mov r4, #64
+ sub r5, r8, r7
+ b 1f
+
+ .word _stext
+ .word __bss_start
+
+1:
+ .rept 4
+ ldmia r2!, {r6, r7, r8, r9}
+ stmia r3!, {r6, r7, r8, r9}
+ .endr
+ subs r4, r4, #64
+ bcs 1b
+ movs r4, r5
+ mov r5, #0
+ movne pc, r0
+
mov r0, #0
mov r1, #5
#endif
-#define DEBUG
+/*
+ * Entry point. Entry *must* be called with r0 == 0, with the MMU off.
+ * r1 contains the unique architecture number. See
+ * linux/arch/arm/kernel/setup.c machine_desc[] array for the complete
+ * list. If you require a new number, please follow the instructions
+ * given in Documentation/arm/README.
+ */
+__entry: teq r0, #0
+ movne r0, #'i'
+ bne __error
+ bl __lookup_processor_type
+ teq r10, #0 @ invalid processor?
+ moveq r0, #'p'
+ beq __error
+ bl __lookup_architecture_type
+ teq r7, #0 @ invalid architecture?
+ moveq r0, #'a'
+ beq __error
+ bl __create_page_tables
+ adr lr, __ret
+ add pc, r10, #12 @ flush caches (returns ctrl reg)
- .globl SYMBOL_NAME(swapper_pg_dir)
- .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
+__switch_data: .long __mmap_switched
+ .long SYMBOL_NAME(__bss_start)
+ .long SYMBOL_NAME(_end)
+ .long SYMBOL_NAME(processor_id)
+ .long SYMBOL_NAME(__machine_arch_type)
+ .long SYMBOL_NAME(cr_alignment)
+ .long SYMBOL_NAME(init_task_union)+8192
+
+__ret: ldr lr, __switch_data
+ mcr p15, 0, r0, c1, c0
+ mov r0, r0
+ mov r0, r0
+ mov r0, r0
+ mov pc, lr
+
+ /*
+ * This code follows on after the page
+ * table switch and jump above.
+ *
+ * r0 = processor control register
+ * r1 = machine ID
+ * r9 = processor ID
+ */
+ .align 5
+__mmap_switched:
+ adr r3, __switch_data + 4
+ ldmia r3, {r4, r5, r6, r7, r8, sp} @ Setup stack
+
+ mov fp, #0 @ Clear BSS
+1: cmp r4, r5
+ strcc fp, [r4],#4
+ bcc 1b
+
+ str r9, [r6] @ Save processor ID
+ str r1, [r7] @ Save machine type
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #2 @ ...........A.
+#endif
+ bic r2, r0, #2 @ Clear 'A' bit
+ stmia r8, {r0, r2} @ Save control register values
+ b SYMBOL_NAME(start_kernel)
- .text
-/*
- * Entry point and restart point. Entry *must* be called with r0 == 0,
- * MMU off. Note! These should be unique!!! Please read Documentation/ARM-README
- * for more information.
- *
- * r1 = 0 -> DEC EBSA-110
- * r1 = 1 -> Acorn RiscPC
- * r1 = 2 -> ebsit
- * r1 = 3 -> nexuspci
- * r1 = 4 -> DEC EBSA-285
- * r1 = 5 -> Corel Netwinder
- * r1 = 6 -> CATS
- * r1 = 7 -> tbox
- */
-ENTRY(stext)
-ENTRY(_stext)
-__entry: teq r0, #0 @ check for illegal entry...
- bne .Lerror @ loop indefinitely
- cmp r1, #8 @ Unknown machine architecture
- bge .Lerror
-/* First thing to do is to get the page tables set up so that we can call the kernel
- * in the correct place. This is relocatable code...
- * - Read processor ID register (CP#15, CR0).
- */
- mrc p15, 0, r9, c0, c0 @ get Processor ID
-/* Values are:
- * XX01XXXX = ARMv4 architecture (StrongARM)
- * XX00XXXX = ARMv3 architecture
- * 4156061X = ARM 610
- */
- adr r10, .LCProcTypes
-1: ldmia r10!, {r5, r6, r8} @ Get Set, Mask, MMU Flags
- teq r5, #0 @ End of list?
- beq .Lerror
- eor r5, r5, r9
- tst r5, r6
- addne r10, r10, #8
- bne 1b
- adr r4, .LCMachTypes
- add r4, r4, r1, lsl #4
- ldmia r4, {r4, r5, r6}
/*
- * r4 = page dir in physical ram
+ * Setup the initial page tables. We only setup the barest
+ * amount which are required to get the kernel running, which
+ * generally means mapping in the kernel code.
+ *
+ * We only map in 4MB of RAM, which should be sufficient in
+ * all cases.
+ *
* r5 = physical address of start of RAM
- * r6 = I/O address
+ * r6 = physical IO address
+ * r7 = byte offset into page tables for IO
+ * r8 = page table flags
*/
+__create_page_tables:
+ add r4, r5, #SWAPPER_PGDIR_OFFSET
mov r0, r4
mov r3, #0
- add r2, r0, #0x4000
-1: str r3, [r0], #4 @ Clear page table
+ add r2, r0, #0x4000 @ Clear page table
+1: str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
teq r0, r2
bne 1b
-/*
- * Add enough entries to allow the kernel to be called.
- * It will sort out the real mapping in paging_init.
- * We map in 2MB of memory into (TEXTADDR-0x8000) + 2MB
- */
- add r0, r4, #(TEXTADDR - 0x8000) >> 18
- mov r3, #0x0000000c @ SECT_CACHEABLE | SECT_BUFFERABLE
+ /*
+ * Create identity mapping for first MB of kernel.
+ * map in four sections (4MB) for kernel.
+ * these are marked cacheable and bufferable.
+ *
+ * The identity mapping will be removed by paging_init()
+ */
+ mov r3, #0x0c
orr r3, r3, r8
add r3, r3, r5
+ add r0, r4, r5, lsr #18
+ str r3, [r0]
+ add r0, r4, #(TEXTADDR - 0x8000) >> 18
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
add r3, r3, #1 << 20
-#ifdef DEBUG
-/* Map in IO space
- * This allows debug messages to be output via a serial
- * before/while paging_init.
- */
- add r0, r4, #0x3800
+ str r3, [r0], #4
+ add r3, r3, #1 << 20
+ str r3, [r0], #4
+#ifdef CONFIG_DEBUG_LL
+ /*
+ * Map in IO space for serial debugging.
+ * This allows debug messages to be output
+ * via a serial before paging_init.
+ */
+ add r0, r4, r7
+ rsb r3, r7, #0x4000 @ PTRS_PER_PGD*sizeof(long)
+ cmp r3, #0x0800
+ addge r2, r0, #0x0800
+ addlt r2, r0, r3
orr r3, r6, r8
- add r2, r0, #0x0800
1: str r3, [r0], #4
add r3, r3, #1 << 20
teq r0, r2
bne 1b
-#ifdef CONFIG_ARCH_VNC
- add r0, r4, #0x3f00
- add r0, r0, #0x00f8
+#ifdef CONFIG_ARCH_NETWINDER
+ teq r1, #5
+ bne 1f
+ add r0, r4, #0x3fc0
mov r3, #0x7c000000
orr r3, r3, r8
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
+1:
#endif
#endif
#ifdef CONFIG_ARCH_RPC
-/* Map in screen at 0x02000000 & SCREEN2_BASE
- * Similar reasons here - for debug, and when things go
- * wrong to a certain extent. This is of limited use to
- * non-Acorn RiscPC architectures though.
- */
+ /*
+ * Map in screen at 0x02000000 & SCREEN2_BASE
+ * Similar reasons here - for debug. This is
+ * only for Acorn RiscPC architectures.
+ */
teq r5, #0
- addne r0, r4, #0x80 @ 02000000
+ addne r0, r4, #0x80 @ 02000000
movne r3, #0x02000000
orrne r3, r3, r8
strne r3, [r0]
- addne r0, r4, #0x3600 @ d8000000
+ addne r0, r4, #0x3600 @ d8000000
strne r3, [r0]
#endif
-@
-@ The following should work on both v3 and v4 implementations
-@
- mov lr, pc
- mov pc, r10 @ Call processor flush (returns ctrl reg)
- adr r5, __entry
- sub r10, r10, r5 @ Make r10 PIC
- ldr lr, .Lbranch
- mcr p15, 0, r0, c1, c0 @ Enable MMU & caches. In 3 instructions
- @ we lose this page!
mov pc, lr
-.Lerror:
+
+
+/*
+ * 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.
+ * r0 = ascii error character
+ *
+ * Generally, only serious errors cause this.
+ */
+__error:
#ifdef CONFIG_ARCH_RPC
-/* Turn the screen red on a error - RiscPC only.
+/*
+ * Turn the screen red on a error - RiscPC only.
*/
-1: mov r0, #0x02000000
+ mov r0, #0x02000000
mov r3, #0x11
orr r3, r3, r3, lsl #8
orr r3, r3, r3, lsl #16
@@ -160,160 +241,157 @@
str r3, [r0], #4
str r3, [r0], #4
#endif
+1: mov r0, r0
b 1b
-.Lbranch: .long .Lalready_done_mmap @ Real address of routine
- @ DEC EBSA110 (pg dir phys, phys ram start, phys i/o)
-.LCMachTypes: .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
- .long 0 @ Address of RAM
- .long 0xe0000000 @ I/O address
+
+/*
+ * Read processor ID register (CP#15, CR0), and determine
+ * processor type.
+ *
+ * Returns:
+ * r5, r6, r7 corrupted
+ * r8 = page table flags
+ * r9 = processor ID
+ * r10 = pointer to processor structure
+ */
+__lookup_processor_type:
+ adr r5, 2f
+ ldmia r5, {r7, r9, r10}
+ sub r5, r5, r9
+ add r7, r7, r5
+ add r10, r10, r5
+ mrc p15, 0, r9, c0, c0 @ get processor id
+1: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags
+ eor r5, r5, r9
+ tst r5, r6
+ moveq pc, lr
+ add r10, r10, #36 @ sizeof(proc_info_list)
+ cmp r10, r7
+ blt 1b
+ mov r10, #0
+ mov pc, lr
+
+2: .long __proc_info_end
+ .long 2b
+ .long __proc_info_begin
+
+/*
+ * Lookup machine architecture
+ * r1 = machine architecture number
+ * Returns:
+ * r4 = unused word
+ * r5 = physical start address of RAM
+ * r6 = physical address of IO
+ * r7 = byte offset into page tables for IO
+ */
+__lookup_architecture_type:
+ cmp r1, #(__arch_types_end - __arch_types_start) / 16
+ bge 1f
+ adr r4, __arch_types_start
+ add r4, r4, r1, lsl #4
+ ldmia r4, {r4, r5, r6, r7}
+ mov r7, r7, lsr #18
+ mov pc, lr
+1: mov r7, #0
+ mov pc, lr
+
+/*
+ * Machine parameters. Each machine requires 4 words, which are:
+ *
+ * word0: unused
+ * word1: physical start address of RAM
+ * word2: physical start address of IO
+ * word3: virtual start address of IO
+ *
+ * The IO mappings entered here are used to set up mappings
+ * required for debugging information to be shown to the user.
+ * paging_init() does the real page table initialisation.
+ */
+ @ 0x00 - DEC EBSA110
+__arch_types_start:
+ .long 0
.long 0
+ .long 0xe0000000
+ .long 0xe0000000
- @ Acorn RiscPC
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x10000000
+ @ 0x01 - Acorn RiscPC
+ .long 0
.long 0x10000000
.long 0x03000000
- .long 0
+ .long 0xe0000000
- @ EBSIT ???
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000
+ @ 0x02 - Unused
.long 0
- .long 0xe0000000
.long 0
+ .long 0xe0000000
+ .long 0xe0000000
- @ NexusPCI
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x40000000
+ @ 0x03 - NexusPCI
+ .long 0
.long 0x40000000
.long 0x10000000
- .long 0
+ .long 0xe0000000
- @ DEC EBSA285
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
- .long 0 @ Address of RAM
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xFE000000)
+ @ 0x04 - DEC EBSA285
.long 0
-
- @ Corel VNC
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
- .long 0 @ Address of RAM
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
.long 0
+ .long 0x42000000
+ .long 0xfe000000
- @ CATS
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
- .long 0 @ Address of RAM
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
+ @ 0x05 - Rebel.com NetWinder
.long 0
-
- @ tbox
- .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x80000000
- .long 0x80000000 @ Address of RAM
- .long 0x00400000 @ Uart
.long 0
+ .long 0x42000000
+ .long 0xfe000000
-.LCProcTypes: @ ARM6 / 610
- .long 0x41560600
- .long 0xffffff00
- .long 0x00000c12
- b .Larmv3_flush_early @ arm v3 flush & ctrl early setup
- mov pc, lr
-
- @ ARM7
- .long 0x41007000
- .long 0xfffff000
- .long 0x00000c12
- b .Larmv3_flush_late @ arm v3 flush & ctrl late setup
- mov pc, lr
-
- @ ARM710
- .long 0x41007000
- .long 0xfff8f000 @ arm710 processors are weird
- .long 0x00000c12
- b .Larmv3_flush_late @ arm v3 flush & ctrl late setup
- mov pc, lr
+ @ 0x06 - CATS
+ .long 0
+ .long 0
+ .long 0x42000000
+ .long 0xfe000000
- @ StrongARM
- .long 0x4401a100
- .long 0xfffffff0
- .long 0x00000c02
- b .Larmv4_flush_early
- b .Lsa_fastclock
+ @ 0x07 - tbox
+ .long 0
+ .long 0x80000000
+ .long 0x00400000 @ Uart
+ .long 0xe0000000
+ @ 0x08 - DEC EBSA285 as co-processor
.long 0
- .align
+ .long 0
+ .long 0x42000000 @ Physical I/O base address
+ .long 0x7cf00000 @ Virtual I/O base address
-.Larmv3_flush_early:
- mov r0, #0
- mcr p15, 0, r0, c7, c0 @ flush caches on v3
- mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
- mov r0, #0x3d @ ....S..DPWC.M
- orr r0, r0, #0x100
- mov pc, lr
+ @ 0x09 - CL-PS7110
-.Larmv3_flush_late:
- mov r0, #0
- mcr p15, 0, r0, c7, c0 @ flush caches on v3
- mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
- mov r0, #0x7d @ ....S.LDPWC.M
- orr r0, r0, #0x100
- mov pc, lr
+ @ 0x0a - Acorn Archimedes
-.Larmv4_flush_early:
- mov r0, #0
- mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
- mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
- mrc p15, 0, r0, c1, c0 @ get control register v4
- bic r0, r0, #0x0e00
- bic r0, r0, #0x0002
- orr r0, r0, #0x003d @ I...S..DPWC.M
- orr r0, r0, #0x1100 @ v4 supports separate I cache
- mov pc, lr
+ @ 0x0b - Acorn A5000
- .section ".text.init",#alloc,#execinstr
+ @ 0x0c - Etoile
-.Lsa_fastclock: mcr p15, 0, r4, c15, c1, 2 @ Enable clock switching
- mov pc, lr
+ @ 0x0d - LaCie_NAS
-.LC0: .long SYMBOL_NAME(__entry)
- .long SYMBOL_NAME(machine_type)
- .long SYMBOL_NAME(__bss_start)
- .long SYMBOL_NAME(processor_id)
- .long SYMBOL_NAME(_end)
- .long SYMBOL_NAME(init_task_union)+8192
- .align
+ @ 0x0e - CL-PS7500
-.Lalready_done_mmap:
- adr r4, .LC0
- ldmia r4, {r3, r4, r5, r6, r8, sp} @ Setup stack
- add r10, r10, r3 @ Add base back in
- mov fp, #0
-1: cmp r5, r8 @ Clear BSS
- strcc fp, [r5],#4
- bcc 1b
+ @ 0x0f - Shark
- str r1, [r4] @ Save machine type
- str r9, [r6] @ Save processor ID
- mov lr, pc
- add pc, r10, #4 @ Call post-processor init
- mov fp, #0
- b SYMBOL_NAME(start_kernel)
+ @ 0x10 - SA1100
+
+ /*
+ * Don't add anything here unless you have an
+ * architecture number allocated - see
+ * Documentation/arm/README
+ */
+__arch_types_end:
- .text
-#ifdef DEBUG
+#ifdef CONFIG_DEBUG_LL
/*
* Some debugging routines (useful if you've got MM problems and
- * printk isn't working). For DEBUGGING ONLY!!!
+ * printk isn't working). For DEBUGGING ONLY!!! Do not leave
+ * references to these in a production kernel!
*/
#if defined(CONFIG_ARCH_RPC)
.macro addruart,rx
@@ -362,64 +440,71 @@
beq 1001b
.endm
-#elif defined(CONFIG_ARCH_EBSA285)
+#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE)
+#ifndef CONFIG_DEBUG_DC21285_PORT
+ /* For NetWinder debugging */
.macro addruart,rx
- mov \rx, #0xfe000000
+ mov \rx, #0xff000000
+ orr \rx, \rx, #0x000003f8
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #0x160] @ UARTDR
+ strb \rd, [\rx]
.endm
.macro busyuart,rd,rx
-1001: ldr \rd, [\rx, #0x178] @ UARTFLG
- tst \rd, #1 << 3
- bne 1001b
+1002: ldrb \rd, [\rx, #0x5]
+ and \rd, \rd, #0x60
+ teq \rd, #0x60
+ bne 1002b
.endm
.macro waituart,rd,rx
+1001: ldrb \rd, [\rx, #0x6]
+ tst \rd, #0x10
+ beq 1001b
.endm
+#else
+ /* For EBSA285 debugging */
+ .equ dc21285_high, ARMCSR_BASE & 0xff000000
+ .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
-#elif defined(CONFIG_ARCH_NEXUSPCI)
.macro addruart,rx
- ldr \rx, =0xfff00000
+ mov \rx, #dc21285_high
+ .if dc21285_low
+ orr \rx, \rx, #dc21285_low
+ .endif
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #0xc]
+ str \rd, [\rx, #0x160] @ UARTDR
.endm
.macro busyuart,rd,rx
-1001: ldr \rd, [\rx, #0x4]
- tst \rd, #1 << 0
+1001: ldr \rd, [\rx, #0x178] @ UARTFLG
+ tst \rd, #1 << 3
bne 1001b
.endm
.macro waituart,rd,rx
.endm
-
-#elif defined(CONFIG_ARCH_VNC)
+#endif
+#elif defined(CONFIG_ARCH_NEXUSPCI)
.macro addruart,rx
- mov \rx, #0xff000000
- orr \rx, \rx, #0x00e00000
- orr \rx, \rx, #0x000003f8
+ ldr \rx, =0xfff00000
.endm
.macro senduart,rd,rx
- strb \rd, [\rx]
+ str \rd, [\rx, #0xc]
.endm
.macro busyuart,rd,rx
-1002: ldrb \rd, [\rx, #0x5]
- and \rd, \rd, #0x60
- teq \rd, #0x60
- bne 1002b
+1001: ldr \rd, [\rx, #0x4]
+ tst \rd, #1 << 0
+ bne 1001b
.endm
.macro waituart,rd,rx
-1001: ldrb \rd, [\rx, #0x6]
- tst \rd, #0x10
- beq 1001b
.endm
#else
#error Unknown architecture
@@ -475,8 +560,6 @@
mov r1, r0
mov r0, #0
b 1b
-
- .ltorg
.bss
hexbuf: .space 16
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)