-\r
-.macro CPWAIT Rd\r
- MRC P15, 0, \Rd, C2, C0, 0 @ arbitrary read of CP15 into register Rd\r
- MOV \Rd, \Rd @ wait for it (foward dependency)\r
- SUB PC, PC, #4 @ branch to next instruction\r
-.endm\r
-\r
- \r
-.macro ALLOCATE Rd\r
- MCR P15, 0, \Rd, C7, C2, 5 @ perform line allocation based on Rd\r
-.endm\r
-@@@@@@@@@@@@@@@@@@@@@@@@@\r
-@ to create an assembly function that confirms to AAPCS (or so I think ;o)\r
-@ .func function name\r
-@ STMFD R13!, {R4 - R12, LR}..alternatively STMFD R13!, {registers used, LR}\r
-@ {function body}\r
-@ LDMFD R13!, {R4 - R12, PC}...must match above with LR replaced by PC\r
-@ .endfunc\r
-@@@@@@@@@@@@@@@@@@@@@@@@@@\r
-\r
-@whether WT or WB is used is determined in mmu_table.s \r
- .extern MMUTable \r
- \r
- .equ MEMORY_CONFIG_BASE,(0x48000000) \r
- .equ FLASH_SYNC_value, (0x25C3<<1) @ Value to set flash into burst 16 sync mode\r
- @.equ FLASH_SYNC_value, (0x25C2<<1) @ Value to set flash into burst 8 sync mode\r
- .equ FLASH_WRITE,(0x0060) @ Code for writing to flash\r
- .equ FLASH_READSTATUS,(0x0070) @ Code for reading status\r
- .equ FLASH_WCONF,(0x0003) @ Code to confirm write to flash \r
- .equ FLASH_READ,(0x00FF) @ Code to place flash in read mode \r
- .equ SXCNFG_sync_value,(0x7011) @ SXCNFG value for burst16 sync flash operation\r
- @ .equ SXCNFG_sync_value,(0x6011) @ SXCNFG value for burst8 sync flash operation \r
- .equ SXCNFG_offset,(0x1c) \r
-\r
- .global initMMU\r
- .global initSyncFlash\r
- .global enableICache \r
- .global enableDCache\r
- .global disableDCache \r
- .global invalidateDCache\r
- .global cleanDCache\r
- .global globalCleanAndInvalidateDCache\r
- \r
-initSyncFlash:\r
- @this function MUST be called after the ICACHE is initialized to work correctly!!!\r
- @also, the DCache being on in WB mode will possibly cause this to randomly FAIL!\r
-.func initSyncFlash\r
- STMFD R13!, {R4 - R7, LR}\r
- ldr r1, =MEMORY_CONFIG_BASE @ Memory config register base\r
- ldr r2, =FLASH_SYNC_value @ Value to set into flash RCR register\r
- ldr r3, =FLASH_WRITE @ Write to flash instruction\r
- ldr r4, =FLASH_WCONF @ Write to flash confirm instruction\r
- ldr r5, =FLASH_READ @ Load "read array" mode command\r
- ldr r6, =0x0 @ Boot ROM Flash Base address\r
- ldr r7, =SXCNFG_sync_value @ SXCNFG Magic number for now\r
- b goSyncFlash\r
-\r
-@align on cache line so that we fetch the next 8 instructions... \r
-.align 5\r
-goSyncFlash: \r
- @ Now program everything into the Flash and SXCNFG registers\r
- str r7, [r1, #SXCNFG_offset] @ Update PXA27x SXCNFG register\r
- strh r3, [r2] @ Yes, the data is on the address bus!\r
- strh r4, [r2] @ Confirm the write to the RCR\r
- strh r5, [r6] @ Place flash back in read mode\r
- ldrh r5, [r6] @ Create a data dependency stall to guarantee write\r
- nop @ go to the end of the cache line\r
- nop\r
- nop\r
- LDMFD R13!, {R4 - R7, PC}\r
-.endfunc\r
-\r
- @assembly routine to init our MMU\r
-initMMU:\r
-.func initMMU\r
- MRC P15,0,R0,C3,C0,0 @read the domain register into R0\r
- ORR R0, R0, #0xFF @make sure that we completely enable domain 0\r
- MCR P15,0,R0,C3,C0,0 @write the domain register\r
- CPWAIT R0 @be anal and make sure it completes\r
-\r
- @time to setup the page table base register\r
- @LDR R0, =MMUTable @move the table we want into R0\r
- MCR P15, 0, R0, C2, C0 @save it \r
- CPWAIT R0 @wait it\r
-\r
- @time to enable the MMU!\r
- MRC P15,0,R0,C1,C0,0 @get CP15 register 1\r
- ORR R0, R0, #0x1 @set the MMU enable bit\r
- MCR P15,0,R0,C1,C0,0 @save it\r
- CPWAIT R0 @wait it\r
- MOV PC, LR\r
-.endfunc\r
-\r
-enableICache: \r
-.func enableICache\r
- @icache section\r
- @globally unlock the icache\r
- MCR P15, 0, R0, C9, C1, 1\r
- CPWAIT R0\r
-\r
- @globally unlock the itlb\r
- MCR P15, 0, R0, C10, C4, 1\r
- CPWAIT R0\r
- \r
- @invalidate just the icache and BTB....write to P15 C7, C5, 0\r
- MCR P15, 0, R0, C7, C5, 0\r
- CPWAIT R0\r
- \r
- @invalidate the iTLB...write to P15 C8, C5, 0\r
- MCR P15, 0, R0, c8, c5, 0 @save it\r
- CPWAIT R0 @wait it\r
- \r
- @Enable instruction cache \r
- MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1\r
- ORR R0, R0, #0x1000 @set the icache bit\r
- MCR P15, 0, R0, C1, C0, 0 @wait it\r
- CPWAIT R0\r
- \r
- @enable the BTB\r
- MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1\r
- ORR R0, R0, #0x800 @set the btb enable bit\r
- MCR P15, 0, R0, C1, C0, 0 @save it \r
- CPWAIT R0 @wait it \r
- MOV PC, LR\r
-.endfunc\r
-\r
-\r
-enableDCache:\r
-.func enableDCache\r
- @globally unlock the dtlb\r
- MCR P15, 0, R0, c10, c8, 1\r
- CPWAIT R0\r
- \r
- @globally unlock the dcache\r
- MCR P15, 0, R0, C9, c2, 1\r
- CPWAIT R0\r
- \r
- @first invalidate dcache and mini-dcache\r
- MCR P15, 0, R0, C7, C6, 0\r
- CPWAIT R0\r
-\r
- @invalidate the dTLB...write to P15 C8, C6, 0\r
- MCR P15, 0, R0, C8, C6, 0 @save it\r
- CPWAIT R0 @wait it\r
-\r
- \r
- @ now, enable data cache \r
- MCR P15, 0, R0, C7, C10, 4 @drain write buffer\r
- MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1\r
- ORR R0, R0, #0x4 @set the dcache enable bit\r
- MCR P15, 0, R0, C1, C0, 0 @save it\r
- CPWAIT R0 @wait it\r
- MOV PC, LR\r
-.endfunc\r
-\r
-disableDCache:\r
-.func disableDCache\r
-@since caching might be WB or WT for a given line, need to invalidate/flush dcache to ensure coherency\r
- @globally unlock the dcache\r
- STMFD R13!, {R0, LR}\r
- MCR P15, 0, R0, C9, c2, 1\r
- CPWAIT R0\r
-\r
- @globally clean and invalidate the cache\r
- bl globalCleanAndInvalidateDCache\r
- \r
- @ now, disable data cache \r
- MCR P15, 0, R0, C7, C10, 4 @drain write buffer\r
- MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1\r
- BIC R0, R0, #0x4 @clear the dcache enable bit\r
- MCR P15, 0, R0, C1, C0, 0 @save it\r
- CPWAIT R0 @wait it\r
- LDMFD R13!, {R0, LR}\r
-.endfunc\r
-\r
-@function to invalidate the DCCache for a given Buffer\r
-@funtion take 2 parameters\r
-@R0 = base virtual address to evict\r
-@R1 = number of bytes to evict...cache line is 32 bytes\r
-invalidateDCache: \r
-.func invalidateDCache\r
- CMPS R1,#0 @check that we're greater than 0\r
- MOVLE PC, LR @return if not\r
-invalidateDCacheLoop: \r
- MCR P15, 0, R0, C7, C6, 1 @invalidate this line\r
- SUBS R1, R1, #32 @subtract out 32 w/CPSR update\r
- ADD R0, R0, #32 @add 32 to the address w/o CPSR update\r
- BGT invalidateDCacheLoop @rerun if subtract is greater than\r
- MOV PC, LR\r
-.endfunc\r
-\r
-@function to clean the DCCache for a given Buffer\r
-@if a line is dirty, it will be cleaned...i.e. written back to memory in WB mode\r
-@funtion take 2 parameters\r
-@R0 = base virtual address to evict\r
-@R1 = number of bytes to evict...cache line is 32 bytes\r
-cleanDCache: \r
-.func cleanDCache\r
- CMPS R1,#0 @check that we're greater than 0\r
- MOVLE PC, LR @return if not\r
-cleanDCacheLoop: \r
- MCR P15, 0, R0, C7, C10, 1 @clean this line\r
- SUBS R1, R1, #32 @subtract out 32 w/CPSR update\r
- ADD R0, R0, #32 @add 32 to the address w/o CPSR update\r
- BGT cleanDCacheLoop @rerun if subtract is greater than\r
- MCR P15, 0, R0, C7, C10, 4 @drain write buffer\r
- CPWAIT R0 @wait it\r
- MOV PC, LR\r
-.endfunc\r
-\r
-\r
-@Global Clean/Invalidate THE DATA CACHE\r
-@R1 contains the virtual address of a region of cacheable memory reserved for\r
-@this clean operation\r
-@R0 is the loop count; Iterate 1024 times which is the number of lines in the\r
-@data cache\r
- \r
-globalCleanAndInvalidateDCache:\r
-.func globalCleanAndInvalidateDCache\r
- @note, this function assumes that we will NEVER have anything physical at\r
- @address 0x04000000 corresponds to static chip select 1\r
- STMFD R13!, {R0 - R3, LR}\r
- LDR R1, =0x04000000 \r
- MOV R0, #1024\r
-LOOP1:\r
- \r
- ALLOCATE R1 @ Allocate a line at the virtual address\r
- @ specified by R1.\r
- SUBS R0, R0, #1 @ Decrement loop count\r
- ADD R1, R1, #32 @ Increment the address in R1 to the next cache line\r
- BNE LOOP1\r
- \r
- @Clean the Mini-data Cache\r
- @ Can\92t use line-allocate command, so cycle 2KB of unused data through.\r
- @ R2 contains the virtual address of a region of cacheable memory reserved for\r
- @ cleaning the Mini-data Cache\r
- @ R0 is the loop count; Iterate 64 times which is the number of lines in the\r
- @ Mini-data Cache.\r
-\r
- @note, this function assumes that we will NEVER have anything physical at\r
- @address 0x05000000 corresponds to static chip select 1\r
- LDR R2, =0x05000000 \r
- MOV R0, #64\r
-LOOP2:\r
- SUBS R0, R0, #1 @ Decrement loop count\r
- LDR R3,[R2],#32 @ Load and increment to next cache line\r
- BNE LOOP2\r
- \r
- @ Invalidate the data cache and mini-data cache\r
- MCR P15, 0, R0, C7, C6, 0\r
- LDMFD R13!, {R0 - R3, PC}\r
-.endfunc\r
- \r
-.end\r
+
+.macro CPWAIT Rd
+ MRC P15, 0, \Rd, C2, C0, 0 @ arbitrary read of CP15 into register Rd
+ MOV \Rd, \Rd @ wait for it (foward dependency)
+ SUB PC, PC, #4 @ branch to next instruction
+.endm
+
+
+.macro ALLOCATE Rd
+ MCR P15, 0, \Rd, C7, C2, 5 @ perform line allocation based on Rd
+.endm
+@@@@@@@@@@@@@@@@@@@@@@@@@
+@ to create an assembly function that confirms to AAPCS (or so I think ;o)
+@ .func function name
+@ STMFD R13!, {R4 - R12, LR}..alternatively STMFD R13!, {registers used, LR}
+@ {function body}
+@ LDMFD R13!, {R4 - R12, PC}...must match above with LR replaced by PC
+@ .endfunc
+@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+@whether WT or WB is used is determined in mmu_table.s
+ .extern MMUTable
+
+ .equ MEMORY_CONFIG_BASE,(0x48000000)
+ .equ FLASH_SYNC_value, (0x25C3<<1) @ Value to set flash into burst 16 sync mode
+ @.equ FLASH_SYNC_value, (0x25C2<<1) @ Value to set flash into burst 8 sync mode
+ .equ FLASH_WRITE,(0x0060) @ Code for writing to flash
+ .equ FLASH_READSTATUS,(0x0070) @ Code for reading status
+ .equ FLASH_WCONF,(0x0003) @ Code to confirm write to flash
+ .equ FLASH_READ,(0x00FF) @ Code to place flash in read mode
+ .equ SXCNFG_sync_value,(0x7011) @ SXCNFG value for burst16 sync flash operation
+ @ .equ SXCNFG_sync_value,(0x6011) @ SXCNFG value for burst8 sync flash operation
+ .equ SXCNFG_offset,(0x1c)
+
+ .global initMMU
+ .global initSyncFlash
+ .global enableICache
+ .global enableDCache
+ .global disableDCache
+ .global invalidateDCache
+ .global cleanDCache
+ .global globalCleanAndInvalidateDCache
+
+initSyncFlash:
+ @this function MUST be called after the ICACHE is initialized to work correctly!!!
+ @also, the DCache being on in WB mode will possibly cause this to randomly FAIL!
+.func initSyncFlash
+ STMFD R13!, {R4 - R7, LR}
+ ldr r1, =MEMORY_CONFIG_BASE @ Memory config register base
+ ldr r2, =FLASH_SYNC_value @ Value to set into flash RCR register
+ ldr r3, =FLASH_WRITE @ Write to flash instruction
+ ldr r4, =FLASH_WCONF @ Write to flash confirm instruction
+ ldr r5, =FLASH_READ @ Load "read array" mode command
+ ldr r6, =0x0 @ Boot ROM Flash Base address
+ ldr r7, =SXCNFG_sync_value @ SXCNFG Magic number for now
+ b goSyncFlash
+
+@align on cache line so that we fetch the next 8 instructions...
+.align 5
+goSyncFlash:
+ @ Now program everything into the Flash and SXCNFG registers
+ str r7, [r1, #SXCNFG_offset] @ Update PXA27x SXCNFG register
+ strh r3, [r2] @ Yes, the data is on the address bus!
+ strh r4, [r2] @ Confirm the write to the RCR
+ strh r5, [r6] @ Place flash back in read mode
+ ldrh r5, [r6] @ Create a data dependency stall to guarantee write
+ nop @ go to the end of the cache line
+ nop
+ nop
+ LDMFD R13!, {R4 - R7, PC}
+.endfunc
+
+ @assembly routine to init our MMU
+initMMU:
+.func initMMU
+ MRC P15,0,R0,C3,C0,0 @read the domain register into R0
+ ORR R0, R0, #0xFF @make sure that we completely enable domain 0
+ MCR P15,0,R0,C3,C0,0 @write the domain register
+ CPWAIT R0 @be anal and make sure it completes
+
+ @time to setup the page table base register
+ @LDR R0, =MMUTable @move the table we want into R0
+ MCR P15, 0, R0, C2, C0 @save it
+ CPWAIT R0 @wait it
+
+ @time to enable the MMU!
+ MRC P15,0,R0,C1,C0,0 @get CP15 register 1
+ ORR R0, R0, #0x1 @set the MMU enable bit
+ MCR P15,0,R0,C1,C0,0 @save it
+ CPWAIT R0 @wait it
+ MOV PC, LR
+.endfunc
+
+enableICache:
+.func enableICache
+ @icache section
+ @globally unlock the icache
+ MCR P15, 0, R0, C9, C1, 1
+ CPWAIT R0
+
+ @globally unlock the itlb
+ MCR P15, 0, R0, C10, C4, 1
+ CPWAIT R0
+
+ @invalidate just the icache and BTB....write to P15 C7, C5, 0
+ MCR P15, 0, R0, C7, C5, 0
+ CPWAIT R0
+
+ @invalidate the iTLB...write to P15 C8, C5, 0
+ MCR P15, 0, R0, c8, c5, 0 @save it
+ CPWAIT R0 @wait it
+
+ @Enable instruction cache
+ MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1
+ ORR R0, R0, #0x1000 @set the icache bit
+ MCR P15, 0, R0, C1, C0, 0 @wait it
+ CPWAIT R0
+
+ @enable the BTB
+ MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1
+ ORR R0, R0, #0x800 @set the btb enable bit
+ MCR P15, 0, R0, C1, C0, 0 @save it
+ CPWAIT R0 @wait it
+ MOV PC, LR
+.endfunc
+
+
+enableDCache:
+.func enableDCache
+ @globally unlock the dtlb
+ MCR P15, 0, R0, c10, c8, 1
+ CPWAIT R0
+
+ @globally unlock the dcache
+ MCR P15, 0, R0, C9, c2, 1
+ CPWAIT R0
+
+ @first invalidate dcache and mini-dcache
+ MCR P15, 0, R0, C7, C6, 0
+ CPWAIT R0
+
+ @invalidate the dTLB...write to P15 C8, C6, 0
+ MCR P15, 0, R0, C8, C6, 0 @save it
+ CPWAIT R0 @wait it
+
+
+ @ now, enable data cache
+ MCR P15, 0, R0, C7, C10, 4 @drain write buffer
+ MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1
+ ORR R0, R0, #0x4 @set the dcache enable bit
+ MCR P15, 0, R0, C1, C0, 0 @save it
+ CPWAIT R0 @wait it
+ MOV PC, LR
+.endfunc
+
+disableDCache:
+.func disableDCache
+@since caching might be WB or WT for a given line, need to invalidate/flush dcache to ensure coherency
+ @globally unlock the dcache
+ STMFD R13!, {R0, LR}
+ MCR P15, 0, R0, C9, c2, 1
+ CPWAIT R0
+
+ @globally clean and invalidate the cache
+ bl globalCleanAndInvalidateDCache
+
+ @ now, disable data cache
+ MCR P15, 0, R0, C7, C10, 4 @drain write buffer
+ MRC P15, 0, R0, C1, C0, 0 @get CP15 register 1
+ BIC R0, R0, #0x4 @clear the dcache enable bit
+ MCR P15, 0, R0, C1, C0, 0 @save it
+ CPWAIT R0 @wait it
+ LDMFD R13!, {R0, LR}
+.endfunc
+
+@function to invalidate the DCCache for a given Buffer
+@funtion take 2 parameters
+@R0 = base virtual address to evict
+@R1 = number of bytes to evict...cache line is 32 bytes
+invalidateDCache:
+.func invalidateDCache
+ CMPS R1,#0 @check that we're greater than 0
+ MOVLE PC, LR @return if not
+invalidateDCacheLoop:
+ MCR P15, 0, R0, C7, C6, 1 @invalidate this line
+ SUBS R1, R1, #32 @subtract out 32 w/CPSR update
+ ADD R0, R0, #32 @add 32 to the address w/o CPSR update
+ BGT invalidateDCacheLoop @rerun if subtract is greater than
+ MOV PC, LR
+.endfunc
+
+@function to clean the DCCache for a given Buffer
+@if a line is dirty, it will be cleaned...i.e. written back to memory in WB mode
+@funtion take 2 parameters
+@R0 = base virtual address to evict
+@R1 = number of bytes to evict...cache line is 32 bytes
+cleanDCache:
+.func cleanDCache
+ CMPS R1,#0 @check that we're greater than 0
+ MOVLE PC, LR @return if not
+cleanDCacheLoop:
+ MCR P15, 0, R0, C7, C10, 1 @clean this line
+ SUBS R1, R1, #32 @subtract out 32 w/CPSR update
+ ADD R0, R0, #32 @add 32 to the address w/o CPSR update
+ BGT cleanDCacheLoop @rerun if subtract is greater than
+ MCR P15, 0, R0, C7, C10, 4 @drain write buffer
+ CPWAIT R0 @wait it
+ MOV PC, LR
+.endfunc
+
+
+@Global Clean/Invalidate THE DATA CACHE
+@R1 contains the virtual address of a region of cacheable memory reserved for
+@this clean operation
+@R0 is the loop count; Iterate 1024 times which is the number of lines in the
+@data cache
+
+globalCleanAndInvalidateDCache:
+.func globalCleanAndInvalidateDCache
+ @note, this function assumes that we will NEVER have anything physical at
+ @address 0x04000000 corresponds to static chip select 1
+ STMFD R13!, {R0 - R3, LR}
+ LDR R1, =0x04000000
+ MOV R0, #1024
+LOOP1:
+
+ ALLOCATE R1 @ Allocate a line at the virtual address
+ @ specified by R1.
+ SUBS R0, R0, #1 @ Decrement loop count
+ ADD R1, R1, #32 @ Increment the address in R1 to the next cache line
+ BNE LOOP1
+
+ @Clean the Mini-data Cache
+ @ CanÆt use line-allocate command, so cycle 2KB of unused data through.
+ @ R2 contains the virtual address of a region of cacheable memory reserved for
+ @ cleaning the Mini-data Cache
+ @ R0 is the loop count; Iterate 64 times which is the number of lines in the
+ @ Mini-data Cache.
+
+ @note, this function assumes that we will NEVER have anything physical at
+ @address 0x05000000 corresponds to static chip select 1
+ LDR R2, =0x05000000
+ MOV R0, #64
+LOOP2:
+ SUBS R0, R0, #1 @ Decrement loop count
+ LDR R3,[R2],#32 @ Load and increment to next cache line
+ BNE LOOP2
+
+ @ Invalidate the data cache and mini-data cache
+ MCR P15, 0, R0, C7, C6, 0
+ LDMFD R13!, {R0 - R3, PC}
+.endfunc
+
+.end
\ No newline at end of file