1/* 2 * linux/arch/arm/kernel/head-armv.S 3 * 4 * Copyright (C) 1994-1999 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * 32-bit kernel startup code for all architectures 11 */ 12#include <linux/config.h> 13#include <linux/linkage.h> 14 15#include <asm/assembler.h> 16#include <asm/mach-types.h> 17#include <asm/mach/arch.h> 18 19#define K(a,b,c) ((a) << 24 | (b) << 12 | (c)) 20 21/* 22 * We place the page tables 16K below TEXTADDR. Therefore, we must make sure 23 * that TEXTADDR is correctly set. Currently, we expect the least significant 24 * "short" to be 0x8000, but we could probably relax this restriction to 25 * TEXTADDR > PAGE_OFFSET + 0x4000 26 * 27 * Note that swapper_pg_dir is the virtual address of the page tables, and 28 * pgtbl gives us a position-independent reference to these tables. We can 29 * do this because stext == TEXTADDR 30 * 31 * swapper_pg_dir, pgtbl and krnladr are all closely related. 32 */ 33#if (TEXTADDR & 0xffff) != 0x8000 34#error TEXTADDR must start at 0xXXXX8000 35#endif 36 37 .globl SYMBOL_NAME(swapper_pg_dir) 38 .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000 39 40 .macro pgtbl, reg, rambase 41 adr \reg, stext 42 sub \reg, \reg, #0x4000 43 .endm 44 45/* 46 * Since the page table is closely related to the kernel start address, we 47 * can convert the page table base address to the base address of the section 48 * containing both. 49 */ 50 .macro krnladr, rd, pgtable, rambase 51 bic \rd, \pgtable, #0x000ff000 52 .endm 53 54/* 55 * Kernel startup entry point. 56 * --------------------------- 57 * 58 * This is normally called from the decompressor code. The requirements 59 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, 60 * r1 = machine nr. 61 * 62 * This code is mostly position independent, so if you link the kernel at 63 * 0xc0008000, you call this at __pa(0xc0008000). 64 * 65 * See linux/arch/arm/tools/mach-types for the complete list of machine 66 * numbers for r1. 67 * 68 * We're trying to keep crap to a minimum; DO NOT add any machine specific 69 * crap here - that's what the boot loader (or in extreme, well justified 70 * circumstances, zImage) is for. 71 */ 72 .section ".text.init",#alloc,#execinstr 73 .type stext, #function 74ENTRY(stext) 75 mov r12, r0 76/* 77 * NOTE! Any code which is placed here should be done for one of 78 * the following reasons: 79 * 80 * 1. Compatability with old production boot firmware (ie, users 81 * actually have and are booting the kernel with the old firmware) 82 * and therefore will be eventually removed. 83 * 2. Cover the case when there is no boot firmware. This is not 84 * ideal, but in this case, it should ONLY set r0 and r1 to the 85 * appropriate value. 86 */ 87#if defined(CONFIG_ARCH_NETWINDER) 88/* 89 * Compatability cruft for old NetWinder NeTTroms. This 90 * code is currently scheduled for destruction in 2.5.xx 91 */ 92 .rept 8 93 mov r0, r0 94 .endr 95 96 adr r2, 1f 97 ldmdb r2, {r7, r8} 98 and r3, r2, #0xc000 99 teq r3, #0x8000 100 beq __entry 101 bic r3, r2, #0xc000 102 orr r3, r3, #0x8000 103 mov r0, r3 104 mov r4, #64 105 sub r5, r8, r7 106 b 1f 107 108 .word _stext 109 .word __bss_start 110 1111: 112 .rept 4 113 ldmia r2!, {r6, r7, r8, r9} 114 stmia r3!, {r6, r7, r8, r9} 115 .endr 116 subs r4, r4, #64 117 bcs 1b 118 movs r4, r5 119 mov r5, #0 120 movne pc, r0 121 122 mov r1, #MACH_TYPE_NETWINDER @ (will go in 2.5) 123 mov r12, #2 << 24 @ scheduled for removal in 2.5.xx 124 orr r12, r12, #5 << 12 125__entry: 126#endif 127#if defined(CONFIG_ARCH_L7200) 128/* 129 * FIXME - No bootloader, so manually set 'r1' with our architecture number. 130 */ 131 mov r1, #MACH_TYPE_L7200 132#endif 133 134 mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode 135 msr cpsr_c, r0 @ and all irqs disabled 136 bl __lookup_processor_type 137 teq r10, #0 @ invalid processor? 138 moveq r0, #'p' @ yes, error 'p' 139 beq __error 140 bl __lookup_architecture_type 141 teq r7, #0 @ invalid architecture? 142 moveq r0, #'a' @ yes, error 'a' 143 beq __error 144 bl __create_page_tables 145 adr lr, __ret @ return address 146 add pc, r10, #12 @ initialise processor 147 @ (return control reg) 148 149 .type __switch_data, %object 150__switch_data: .long __mmap_switched 151 .long SYMBOL_NAME(__bss_start) 152 .long SYMBOL_NAME(_end) 153 .long SYMBOL_NAME(processor_id) 154 .long SYMBOL_NAME(__machine_arch_type) 155 .long SYMBOL_NAME(cr_alignment) 156 .long SYMBOL_NAME(init_task_union)+8192 157 158/* 159 * Enable the MMU. This completely changes the structure of the visible 160 * memory space. You will not be able to trace execution through this. 161 * If you have an enquiry about this, *please* check the linux-arm-kernel 162 * mailing list archives BEFORE sending another post to the list. 163 */ 164 .type __ret, %function 165__ret: ldr lr, __switch_data 166 mcr p15, 0, r0, c1, c0 167 mrc p15, 0, r0, c1, c0, 0 @ read it back. 168 mov r0, r0 169 mov r0, r0 170 mov pc, lr 171 172/* 173 * The following fragment of code is executed with the MMU on, and uses 174 * absolute addresses; this is not position independent. 175 * 176 * r0 = processor control register 177 * r1 = machine ID 178 * r9 = processor ID 179 */ 180 .align 5 181__mmap_switched: 182 adr r3, __switch_data + 4 183 ldmia r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat 184 @ sp = stack pointer 185 186 mov fp, #0 @ Clear BSS (and zero fp) 1871: cmp r4, r5 188 strcc fp, [r4],#4 189 bcc 1b 190 191 str r9, [r6] @ Save processor ID 192 str r1, [r7] @ Save machine type 193#ifdef CONFIG_ALIGNMENT_TRAP 194 orr r0, r0, #2 @ ...........A. 195#endif 196 bic r2, r0, #2 @ Clear 'A' bit 197 stmia r8, {r0, r2} @ Save control register values 198 b SYMBOL_NAME(start_kernel) 199 200 201 202/* 203 * Setup the initial page tables. We only setup the barest 204 * amount which are required to get the kernel running, which 205 * generally means mapping in the kernel code. 206 * 207 * We only map in 4MB of RAM, which should be sufficient in 208 * all cases. 209 * 210 * r5 = physical address of start of RAM 211 * r6 = physical IO address 212 * r7 = byte offset into page tables for IO 213 * r8 = page table flags 214 */ 215__create_page_tables: 216 pgtbl r4, r5 @ page table address 217 218 /* 219 * Clear the 16K level 1 swapper page table 220 */ 221 mov r0, r4 222 mov r3, #0 223 add r2, r0, #0x4000 2241: str r3, [r0], #4 225 str r3, [r0], #4 226 str r3, [r0], #4 227 str r3, [r0], #4 228 teq r0, r2 229 bne 1b 230 231 /* 232 * Create identity mapping for first MB of kernel to 233 * cater for the MMU enable. This identity mapping 234 * will be removed by paging_init() 235 */ 236 krnladr r2, r4, r5 @ start of kernel 237 add r3, r8, r2 @ flags + kernel base 238 str r3, [r4, r2, lsr #18] @ identity mapping 239 240 /* 241 * Now setup the pagetables for our kernel direct 242 * mapped region. We round TEXTADDR down to the 243 * nearest megabyte boundary. 244 */ 245 add r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel 246 bic r2, r3, #0x00f00000 247 str r2, [r0] @ PAGE_OFFSET + 0MB 248 add r0, r0, #(TEXTADDR & 0x00f00000) >> 18 249 str r3, [r0], #4 @ KERNEL + 0MB 250 add r3, r3, #1 << 20 251 str r3, [r0], #4 @ KERNEL + 1MB 252 add r3, r3, #1 << 20 253 str r3, [r0], #4 @ KERNEL + 2MB 254 add r3, r3, #1 << 20 255 str r3, [r0], #4 @ KERNEL + 3MB 256 257 /* 258 * Ensure that the first section of RAM is present. 259 * we assume that: 260 * 1. the RAM is aligned to a 32MB boundary 261 * 2. the kernel is executing in the same 32MB chunk 262 * as the start of RAM. 263 */ 264 bic r0, r0, #0x01f00000 >> 18 @ round down 265 and r2, r5, #0xfe000000 @ round down 266 add r3, r8, r2 @ flags + rambase 267 str r3, [r0] 268 269 bic r8, r8, #0x0c @ turn off cacheable 270 @ and bufferable bits 271#ifdef CONFIG_DEBUG_LL 272 /* 273 * Map in IO space for serial debugging. 274 * This allows debug messages to be output 275 * via a serial console before paging_init. 276 */ 277 add r0, r4, r7 278 rsb r3, r7, #0x4000 @ PTRS_PER_PGD*sizeof(long) 279 cmp r3, #0x0800 280 addge r2, r0, #0x0800 281 addlt r2, r0, r3 282 orr r3, r6, r8 2831: str r3, [r0], #4 284 add r3, r3, #1 << 20 285 teq r0, r2 286 bne 1b 287#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) 288 /* 289 * If we're using the NetWinder, we need to map in 290 * the 16550-type serial port for the debug messages 291 */ 292 teq r1, #MACH_TYPE_NETWINDER 293 teqne r1, #MACH_TYPE_CATS 294 bne 1f 295 add r0, r4, #0x3fc0 296 mov r3, #0x7c000000 297 orr r3, r3, r8 298 str r3, [r0], #4 299 add r3, r3, #1 << 20 300 str r3, [r0], #4 3011: 302#endif 303#endif 304#ifdef CONFIG_ARCH_RPC 305 /* 306 * Map in screen at 0x02000000 & SCREEN2_BASE 307 * Similar reasons here - for debug. This is 308 * only for Acorn RiscPC architectures. 309 */ 310 add r0, r4, #0x80 @ 02000000 311 mov r3, #0x02000000 312 orr r3, r3, r8 313 str r3, [r0] 314 add r0, r4, #0x3600 @ d8000000 315 str r3, [r0] 316#endif 317 mov pc, lr 318 319 320 321/* 322 * Exception handling. Something went wrong and we can't 323 * proceed. We ought to tell the user, but since we 324 * don't have any guarantee that we're even running on 325 * the right architecture, we do virtually nothing. 326 * r0 = ascii error character: 327 * a = invalid architecture 328 * p = invalid processor 329 * i = invalid calling convention 330 * 331 * Generally, only serious errors cause this. 332 */ 333__error: 334#ifdef CONFIG_DEBUG_LL 335 mov r8, r0 @ preserve r0 336 adr r0, err_str 337 bl printascii 338 mov r0, r8 339 bl printch 340#endif 341#ifdef CONFIG_ARCH_RPC 342/* 343 * Turn the screen red on a error - RiscPC only. 344 */ 345 mov r0, #0x02000000 346 mov r3, #0x11 347 orr r3, r3, r3, lsl #8 348 orr r3, r3, r3, lsl #16 349 str r3, [r0], #4 350 str r3, [r0], #4 351 str r3, [r0], #4 352 str r3, [r0], #4 353#endif 3541: mov r0, r0 355 b 1b 356 357#ifdef CONFIG_DEBUG_LL 358err_str: .asciz "\nError: " 359 .align 360#endif 361 362/* 363 * Read processor ID register (CP#15, CR0), and look up in the linker-built 364 * supported processor list. Note that we can't use the absolute addresses 365 * for the __proc_info lists since we aren't running with the MMU on 366 * (and therefore, we are not in the correct address space). We have to 367 * calculate the offset. 368 * 369 * Returns: 370 * r5, r6, r7 corrupted 371 * r8 = page table flags 372 * r9 = processor ID 373 * r10 = pointer to processor structure 374 */ 375__lookup_processor_type: 376 adr r5, 2f 377 ldmia r5, {r7, r9, r10} 378 sub r5, r5, r10 @ convert addresses 379 add r7, r7, r5 @ to our address space 380 add r10, r9, r5 381 mrc p15, 0, r9, c0, c0 @ get processor id 3821: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags 383 and r6, r6, r9 @ mask wanted bits 384 teq r5, r6 385 moveq pc, lr 386 add r10, r10, #36 @ sizeof(proc_info_list) 387 cmp r10, r7 388 blt 1b 389 mov r10, #0 @ unknown processor 390 mov pc, lr 391 392/* 393 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for 394 * more information about the __proc_info and __arch_info structures. 395 */ 3962: .long __proc_info_end 397 .long __proc_info_begin 398 .long 2b 399 .long __arch_info_begin 400 .long __arch_info_end 401 402/* 403 * Lookup machine architecture in the linker-build list of architectures. 404 * Note that we can't use the absolute addresses for the __arch_info 405 * lists since we aren't running with the MMU on (and therefore, we are 406 * not in the correct address space). We have to calculate the offset. 407 * 408 * r1 = machine architecture number 409 * Returns: 410 * r2, r3, r4 corrupted 411 * r5 = physical start address of RAM 412 * r6 = physical address of IO 413 * r7 = byte offset into page tables for IO 414 */ 415__lookup_architecture_type: 416 adr r4, 2b 417 ldmia r4, {r2, r3, r5, r6, r7} @ throw away r2, r3 418 sub r5, r4, r5 @ convert addresses 419 add r4, r6, r5 @ to our address space 420 add r7, r7, r5 4211: ldr r5, [r4] @ get machine type 422 teq r5, r1 423 beq 2f 424 add r4, r4, #SIZEOF_MACHINE_DESC 425 cmp r4, r7 426 blt 1b 427 mov r7, #0 @ unknown architecture 428 mov pc, lr 4292: ldmib r4, {r5, r6, r7} @ found, get results 430 mov pc, lr 431