proc-arm2,3.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/mm/proc-arm2,3.S
  3.  *
  4.  *  Copyright (C) 1997-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.  *  MMU functions for ARM2,3
  11.  *
  12.  *  These are the low level assembler for performing cache
  13.  *  and memory functions on ARM2, ARM250 and ARM3 processors.
  14.  */
  15. #include <linux/linkage.h>
  16. #include <asm/assembler.h>
  17. #include <asm/constants.h>
  18. #include <asm/procinfo.h>
  19. /*
  20.  * MEMC workhorse code.  It's both a horse which things it's a pig.
  21.  */
  22. /*
  23.  * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
  24.  * Params  : pgd Page tables/MEMC mapping
  25.  *         : phys_pte physical address, or PTE
  26.  *         : addr virtual address
  27.  */
  28. ENTRY(cpu_memc_update_entry)
  29. tst r1, #PAGE_PRESENT @ is the page present
  30. orreq r1, r1, #PAGE_OLD | PAGE_CLEAN
  31. moveq r2, #0x01f00000
  32. mov r3, r1, lsr #13 @ convert to physical page nr
  33. and r3, r3, #0x3fc
  34. adr ip, memc_phys_table_32
  35. ldr r3, [ip, r3]
  36. tst r1, #PAGE_OLD | PAGE_NOT_USER
  37. biceq r3, r3, #0x200
  38. tsteq r1, #PAGE_READONLY | PAGE_CLEAN
  39. biceq r3, r3, #0x300
  40. mov r2, r2, lsr #15 @ virtual -> nr
  41. orr r3, r3, r2, lsl #15
  42. and r2, r2, #0x300
  43. orr r3, r3, r2, lsl #2
  44. and r2, r3, #255
  45. sub r0, r0, #256 * 4
  46. str r3, [r0, r2, lsl #2]
  47. strb r3, [r3]
  48. movs pc, lr
  49. /*
  50.  * Params  : r0 = preserved
  51.  *         : r1 = memc table base (preserved)
  52.  *         : r2 = page table entry
  53.  *         : r3 = preserved
  54.  *         : r4 = unused
  55.  *         : r5 = memc physical address translation table
  56.  *         : ip = virtual address (preserved)
  57.  */
  58. update_pte:
  59. mov r4, r2, lsr #13
  60. and r4, r4, #0x3fc
  61. ldr r4, [r5, r4] @ covert to MEMC page
  62. tst r2, #PAGE_OLD | PAGE_NOT_USER @ check for MEMC read
  63. biceq r4, r4, #0x200
  64. tsteq r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write
  65. biceq r4, r4, #0x300
  66. orr r4, r4, ip
  67. and r2, ip, #0x01800000
  68. orr r4, r4, r2, lsr #13
  69. and r2, r4, #255
  70. str r4, [r1, r2, lsl #2]
  71. movs pc, lr
  72. /*
  73.  * Params  : r0 = preserved
  74.  *         : r1 = memc table base (preserved)
  75.  *         : r2 = page table base
  76.  *         : r3 = preserved
  77.  *         : r4 = unused
  78.  *         : r5 = memc physical address translation table
  79.  *         : ip = virtual address (updated)
  80.  */
  81. update_pte_table:
  82. stmfd sp!, {r0, lr}
  83. bic r0, r2, #3
  84. 1: ldr r2, [r0], #4 @ get entry
  85. tst r2, #PAGE_PRESENT @ page present
  86. blne update_pte @ process pte
  87. add ip, ip, #32768 @ increment virt addr
  88. ldr r2, [r0], #4 @ get entry
  89. tst r2, #PAGE_PRESENT @ page present
  90. blne update_pte @ process pte
  91. add ip, ip, #32768 @ increment virt addr
  92. ldr r2, [r0], #4 @ get entry
  93. tst r2, #PAGE_PRESENT @ page present
  94. blne update_pte @ process pte
  95. add ip, ip, #32768 @ increment virt addr
  96. ldr r2, [r0], #4 @ get entry
  97. tst r2, #PAGE_PRESENT @ page present
  98. blne update_pte @ process pte
  99. add ip, ip, #32768 @ increment virt addr
  100. tst ip, #32768 * 31 @ finished?
  101. bne 1b
  102. ldmfd sp!, {r0, pc}^
  103. /*
  104.  * Function: cpu_memc_update_all(pgd_t *pgd)
  105.  * Params  : pgd Page tables/MEMC mapping
  106.  * Notes   : this is optimised for 32k pages
  107.  */
  108. ENTRY(cpu_memc_update_all)
  109. stmfd sp!, {r4, r5, lr}
  110. bl clear_tables
  111. sub r1, r0, #256 * 4 @ start of MEMC tables
  112. adr r5, memc_phys_table_32 @ Convert to logical page number
  113. mov ip, #0 @ virtual address
  114. 1: ldmia r0!, {r2, r3}
  115. tst r2, #PAGE_PRESENT
  116. addeq ip, ip, #1048576
  117. blne update_pte_table
  118. mov r2, r3
  119. tst r2, #PAGE_PRESENT
  120. addeq ip, ip, #1048576
  121. blne update_pte_table
  122. teq ip, #32 * 1048576
  123. bne 1b
  124. ldmfd sp!, {r4, r5, pc}^
  125. /*
  126.  * Build the table to map from physical page number to memc page number
  127.  */
  128. .type memc_phys_table_32, #object
  129. memc_phys_table_32:
  130. .irp b7, 0x00, 0x80
  131. .irp b6, 0x00, 0x02
  132. .irp b5, 0x00, 0x04
  133. .irp b4, 0x00, 0x01
  134. .irp b3, 0x00, 0x40
  135. .irp b2, 0x00, 0x20
  136. .irp b1, 0x00, 0x10
  137. .irp b0, 0x00, 0x08
  138. .long 0x03800300 + b7 + b6 + b5 + b4 + b3 + b2 + b1 + b0
  139. .endr
  140. .endr
  141. .endr
  142. .endr
  143. .endr
  144. .endr
  145. .endr
  146. .endr
  147. .size memc_phys_table_32, . - memc_phys_table_32
  148. /*
  149.  * helper for cpu_memc_update_all, this clears out all
  150.  * mappings, setting them close to the top of memory,
  151.  * and inaccessible (0x01f00000).
  152.  * Params  : r0 = page table pointer
  153.  */
  154. clear_tables: ldr r1, _arm3_set_pgd - 4
  155. ldr r2, [r1]
  156. sub r1, r0, #256 * 4 @ start of MEMC tables
  157. add r2, r1, r2, lsl #2 @ end of tables
  158. mov r3, #0x03f00000 @ Default mapping (null mapping)
  159. orr r3, r3, #0x00000f00
  160. orr r4, r3, #1
  161. orr r5, r3, #2
  162. orr ip, r3, #3
  163. 1: stmia r1!, {r3, r4, r5, ip}
  164. add r3, r3, #4
  165. add r4, r4, #4
  166. add r5, r5, #4
  167. add ip, ip, #4
  168. stmia r1!, {r3, r4, r5, ip}
  169. add r3, r3, #4
  170. add r4, r4, #4
  171. add r5, r5, #4
  172. add ip, ip, #4
  173. teq r1, r2
  174. bne 1b
  175. mov pc, lr
  176. /*
  177.  * Function: *_set_pgd(pgd_t *pgd)
  178.  * Params  : pgd New page tables/MEMC mapping
  179.  * Purpose : update MEMC hardware with new mapping
  180.  */
  181. .word SYMBOL_NAME(page_nr)
  182. _arm3_set_pgd: mcr p15, 0, r1, c1, c0, 0 @ flush cache
  183. _arm2_set_pgd: stmfd sp!, {lr}
  184. ldr r1, _arm3_set_pgd - 4
  185. ldr r2, [r1]
  186. sub r0, r0, #256 * 4 @ start of MEMC tables
  187. add r1, r0, r2, lsl #2 @ end of tables
  188. 1: ldmia r0!, {r2, r3, ip, lr}
  189. strb r2, [r2]
  190. strb r3, [r3]
  191. strb ip, [ip]
  192. strb lr, [lr]
  193. ldmia r0!, {r2, r3, ip, lr}
  194. strb r2, [r2]
  195. strb r3, [r3]
  196. strb ip, [ip]
  197. strb lr, [lr]
  198. teq r0, r1
  199. bne 1b
  200. ldmfd sp!, {pc}^
  201. /*
  202.  * Function: *_proc_init (void)
  203.  * Purpose : Initialise the cache control registers
  204.  */
  205. _arm3_proc_init:
  206. mov r0, #0x001f0000
  207. orr r0, r0, #0x0000ff00
  208. orr r0, r0, #0x000000ff
  209. mcr p15, 0, r0, c3, c0 @ ARM3 Cacheable
  210. mcr     p15, 0, r0, c4, c0 @ ARM3 Updateable
  211. mov r0, #0
  212. mcr     p15, 0, r0, c5, c0 @ ARM3 Disruptive
  213. mcr     p15, 0, r0, c1, c0 @ ARM3 Flush
  214. mov r0, #3
  215. mcr     p15, 0, r0, c2, c0 @ ARM3 Control
  216. _arm2_proc_init:
  217. movs pc, lr
  218. /*
  219.  * Function: *_proc_fin (void)
  220.  * Purpose : Finalise processor (disable caches)
  221.  */
  222. _arm3_proc_fin: mov r0, #2
  223. mcr p15, 0, r0, c2, c0
  224. _arm2_proc_fin: orrs pc, lr, #I_BIT|F_BIT
  225. /*
  226.  * Function: *_xchg_1 (int new, volatile void *ptr)
  227.  * Params  : new New value to store at...
  228.  *    : ptr pointer to byte-wide location
  229.  * Purpose : Performs an exchange operation
  230.  * Returns : Original byte data at 'ptr'
  231.  */
  232. _arm2_xchg_1: mov r2, pc
  233. orr r2, r2, #I_BIT
  234. teqp r2, #0
  235. ldrb r2, [r1]
  236. strb r0, [r1]
  237. mov r0, r2
  238. movs pc, lr
  239. _arm3_xchg_1: swpb r0, r0, [r1]
  240. movs pc, lr
  241. /*
  242.  * Function: *_xchg_4 (int new, volatile void *ptr)
  243.  * Params  : new New value to store at...
  244.  *    : ptr pointer to word-wide location
  245.  * Purpose : Performs an exchange operation
  246.  * Returns : Original word data at 'ptr'
  247.  */
  248. _arm2_xchg_4: mov r2, pc
  249. orr r2, r2, #I_BIT
  250. teqp r2, #0
  251. ldr r2, [r1]
  252. str r0, [r1]
  253. mov r0, r2
  254. movs pc, lr
  255. _arm3_xchg_4: swp r0, r0, [r1]
  256. movs pc, lr
  257. _arm2_3_check_bugs:
  258. bics pc, lr, #0x04000000 @ Clear FIQ disable bit
  259. armvlsi_name: .asciz "ARM/VLSI"
  260. _arm2_name: .asciz "ARM 2"
  261. _arm250_name: .asciz "ARM 250"
  262. _arm3_name: .asciz "ARM 3"
  263. .section ".text.init", #alloc, #execinstr
  264. /*
  265.  * Purpose : Function pointers used to access above functions - all calls
  266.  *      come through these
  267.  */
  268. .globl SYMBOL_NAME(arm2_processor_functions)
  269. SYMBOL_NAME(arm2_processor_functions):
  270. .word _arm2_3_check_bugs
  271. .word _arm2_proc_init
  272. .word _arm2_proc_fin
  273. .word _arm2_set_pgd
  274. .word _arm2_xchg_1
  275. .word _arm2_xchg_4
  276. cpu_arm2_info:
  277. .long armvlsi_name
  278. .long _arm2_name
  279. .globl SYMBOL_NAME(arm250_processor_functions)
  280. SYMBOL_NAME(arm250_processor_functions):
  281. .word _arm2_3_check_bugs
  282. .word _arm2_proc_init
  283. .word _arm2_proc_fin
  284. .word _arm2_set_pgd
  285. .word _arm3_xchg_1
  286. .word _arm3_xchg_4
  287. cpu_arm250_info:
  288. .long armvlsi_name
  289. .long _arm250_name
  290. .globl SYMBOL_NAME(arm3_processor_functions)
  291. SYMBOL_NAME(arm3_processor_functions):
  292. .word _arm2_3_check_bugs
  293. .word _arm3_proc_init
  294. .word _arm3_proc_fin
  295. .word _arm3_set_pgd
  296. .word _arm3_xchg_1
  297. .word _arm3_xchg_4
  298. cpu_arm3_info:
  299. .long armvlsi_name
  300. .long _arm3_name
  301. arm2_arch_name: .asciz "armv1"
  302. arm3_arch_name: .asciz "armv2"
  303. arm2_elf_name: .asciz "v1"
  304. arm3_elf_name: .asciz "v2"
  305. .align
  306. .section ".proc.info", #alloc, #execinstr
  307. .long 0x41560200
  308. .long 0xfffffff0
  309. .long 0
  310. mov pc, lr
  311. .long arm2_arch_name
  312. .long arm2_elf_name
  313. .long 0
  314. .long cpu_arm2_info
  315. .long SYMBOL_NAME(arm2_processor_functions)
  316. .long 0x41560250
  317. .long 0xfffffff0
  318. .long 0
  319. mov pc, lr
  320. .long arm3_arch_name
  321. .long arm3_elf_name
  322. .long 0
  323. .long cpu_arm250_info
  324. .long SYMBOL_NAME(arm250_processor_functions)
  325. .long 0x41560300
  326. .long 0xfffffff0
  327. .long 0
  328. mov pc, lr
  329. .long arm3_arch_name
  330. .long arm3_elf_name
  331. .long 0
  332. .long cpu_arm3_info
  333. .long SYMBOL_NAME(arm3_processor_functions)