summaryrefslogtreecommitdiff
path: root/arch/arm26/kernel/head.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm26/kernel/head.S
downloadconfigs-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/arm26/kernel/head.S')
-rw-r--r--arch/arm26/kernel/head.S113
1 files changed, 113 insertions, 0 deletions
diff --git a/arch/arm26/kernel/head.S b/arch/arm26/kernel/head.S
new file mode 100644
index 00000000000..8bfc62539ba
--- /dev/null
+++ b/arch/arm26/kernel/head.S
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm26/kernel/head.S
+ *
+ * Copyright (C) 1994-2000 Russell King
+ * Copyright (C) 2003 Ian Molton
+ *
+ * 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.
+ *
+ * 26-bit kernel startup code
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+ .globl swapper_pg_dir
+ .equ swapper_pg_dir, 0x0207d000
+
+/*
+ * Entry point.
+ */
+ .section ".init.text",#alloc,#execinstr
+ENTRY(stext)
+
+__entry:
+ cmp pc, #0x02000000
+ ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000
+ teq r0, #0 @ Check for old calling method
+ blne oldparams @ Move page if old
+
+ adr r0, LC0
+ ldmib r0, {r2-r5, sp} @ Setup stack (and fetch other values)
+
+ mov r0, #0 @ Clear BSS
+1: cmp r2, r3
+ strcc r0, [r2], #4
+ bcc 1b
+
+ bl detect_proc_type
+ str r0, [r4]
+ bl detect_arch_type
+ str r0, [r5]
+
+#ifdef CONFIG_XIP_KERNEL
+ ldr r3, ETEXT @ data section copy
+ ldr r4, SDATA
+ ldr r5, EDATA
+1:
+ ldr r6, [r3], #4
+ str r6, [r4], #4
+ cmp r4, r5
+ blt 1b
+#endif
+ mov fp, #0
+ b start_kernel
+
+LC0: .word _stext
+ .word __bss_start @ r2
+ .word _end @ r3
+ .word processor_id @ r4
+ .word __machine_arch_type @ r5
+ .word init_thread_union+8192 @ sp
+#ifdef CONFIG_XIP_KERNEL
+ETEXT: .word _endtext
+SDATA: .word _sdata
+EDATA: .word __bss_start
+#endif
+
+arm2_id: .long 0x41560200 @ ARM2 and 250 dont have a CPUID
+arm250_id: .long 0x41560250 @ So we create some after probing for them
+ .align
+
+oldparams: mov r4, #0x02000000
+ add r3, r4, #0x00080000
+ add r4, r4, #0x0007c000
+1: ldmia r0!, {r5 - r12}
+ stmia r4!, {r5 - r12}
+ cmp r4, r3
+ blt 1b
+ mov pc, lr
+
+/*
+ * We need some way to automatically detect the difference between
+ * these two machines. Unfortunately, it is not possible to detect
+ * the presence of the SuperIO chip, because that will hang the old
+ * Archimedes machines solid.
+ */
+/* DAG: Outdated, these have been combined !!!!!!! */
+detect_arch_type:
+#if defined(CONFIG_ARCH_ARC)
+ mov r0, #MACH_TYPE_ARCHIMEDES
+#elif defined(CONFIG_ARCH_A5K)
+ mov r0, #MACH_TYPE_A5K
+#endif
+ mov pc, lr
+
+detect_proc_type:
+ mov ip, lr
+ mov r2, #0xea000000 @ Point undef instr to continuation
+ adr r0, continue - 12
+ orr r0, r2, r0, lsr #2
+ mov r1, #0
+ str r0, [r1, #4]
+ ldr r0, arm2_id
+ swp r2, r2, [r1] @ check for swp (ARM2 cant)
+ ldr r0, arm250_id
+ mrc 15, 0, r3, c0, c0 @ check for CP#15 (ARM250 cant)
+ mov r0, r3
+continue: mov r2, #0xeb000000 @ Make undef vector loop
+ sub r2, r2, #2
+ str r2, [r1, #4]
+ mov pc, ip