head-armv.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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