1 @ vim:filetype=armasm:
\r
4 .equ mmsp2_regs, (0xc0000000-0x02000000) @ assume we live @ 0x2000000 bank
\r
5 .equ shared_ctl, 0x00200000 @ this is where shared_ctl struncture is located
\r
12 b .b_undef @ undefined instructions
\r
13 b .b_swi @ software interrupt
\r
14 b .b_pabort @ prefetch abort
\r
15 b .b_dabort @ data abort
\r
16 b .b_reserved @ reserved
\r
40 mov sp, #0x100000 @ reset stack
\r
42 mov r0, #shared_ctl @ remember where we were when interrupt happened
\r
45 mov r0, #shared_ctl @ increment exception counter (for debug)
\r
53 @ we should never get here
\r
62 mov sp, #0x100000 @ set the stack top (1M)
\r
63 sub sp, sp, #4 @ minus 4
\r
65 @ set up memory region 0 -- the whole 4GB address space
\r
66 mov r0, #(0x1f<<1)|1 @ region data
\r
67 mcr p15, 0, r0, c6, c0, 0 @ opcode2 ~ data/instr
\r
68 mcr p15, 0, r0, c6, c0, 1
\r
70 @ set up region 1 which is the first 2 megabytes.
\r
71 mov r0, #(0x14<<1)|1 @ region data
\r
72 mcr p15, 0, r0, c6, c1, 0
\r
73 mcr p15, 0, r0, c6, c1, 1
\r
75 @ set up region 2: 64k 0x200000-0x210000
\r
76 mov r0, #(0x0f<<1)|1
\r
77 orr r0, r0, #0x200000
\r
78 mcr p15, 0, r0, c6, c2, 0
\r
79 mcr p15, 0, r0, c6, c2, 1
\r
81 @ set up region 3: 64k 0xbe000000-0xbe010000 (hw control registers)
\r
82 mov r0, #(0x0f<<1)|1
\r
83 orr r0, r0, #mmsp2_regs
\r
84 mcr p15, 0, r0, c6, c3, 0
\r
85 mcr p15, 0, r0, c6, c3, 1
\r
87 @ set up region 4: 16M 0x01000000-0x02000000 (mp3 area)
\r
88 mov r0, #(0x17<<1)|1
\r
89 orr r0, r0, #0x01000000
\r
90 mcr p15, 0, r0, c6, c4, 0
\r
91 mcr p15, 0, r0, c6, c4, 1
\r
93 @ region 5: 4K 0x00000000-0x00001000 (boot code protection region)
\r
94 mov r0, #(0x0b<<1)|1
\r
95 mcr p15, 0, r0, c6, c5, 0
\r
96 mcr p15, 0, r0, c6, c5, 1
\r
98 @ set regions 1, 4 and 5 to be cacheable (so the first 2M and mp3 area will be cacheable)
\r
99 mov r0, #(1<<1)|(1<<4)|(1<<5)
\r
100 mcr p15, 0, r0, c2, c0, 0
\r
101 mcr p15, 0, r0, c2, c0, 1
\r
103 @ set region 1 to be bufferable too (only data)
\r
105 mcr p15, 0, r0, c3, c0, 0
\r
107 @ set access protection
\r
108 @ data: [no, full, full, full, full, no access] for regions [5 4 3 2 1 0]
\r
109 mov r0, #(0<<10)|(3<<8)|(3<<6)|(3<<4)|(3<<2)|(0)
\r
110 mcr p15, 0, r0, c5, c0, 0
\r
111 @ instructions: [full, no access, no, no, full, no]
\r
112 mov r0, #(0<< 6)|(0<<4)|(3<<2)|(0)
\r
113 orr r0, r0, #(3<<10)|(0<<8)
\r
114 mcr p15, 0, r0, c5, c0, 1
\r
116 mrc p15, 0, r0, c1, c0, 0 @ fetch current control reg
\r
117 orr r0, r0, #1 @ 0x00000001: enable protection unit
\r
118 orr r0, r0, #4 @ 0x00000004: enable D cache
\r
119 orr r0, r0, #0x1000 @ 0x00001000: enable I cache
\r
120 @ bic r0, r0, #0xC0000000
\r
121 @ orr r0, r0, #0x40000000 @ 0x40000000: synchronous, faster?
\r
122 orr r0, r0, #0xC0000000 @ 0xC0000000: async
\r
123 mcr p15, 0, r0, c1, c0, 0 @ set control reg
\r
125 @ flush (invalidate) the cache (just in case)
\r
127 mcr p15, 0, r0, c7, c6, 0
\r
129 @ remember which exception vector we came from (increment counter for debug)
\r
130 mov r0, #shared_ctl
\r
131 add r0, r0, r12, lsl #2
\r
136 @ remember last lr (for debug)
\r
137 mov r0, #shared_ctl
\r
141 @ ready to take first job-interrupt
\r
145 msr cpsr_c, r0 @ enable interrupts
\r
148 mcr p15, 0, r0, c7, c0, 4 @ wait for IRQ
\r
149 @ mcr p15, 0, r0, c15, c8, 2
\r
157 .global wait_get_job @ int oldjob
\r
160 mov r3, #mmsp2_regs
\r
161 orr r2, r3, #0x3B00
\r
162 orr r2, r2, #0x0046 @ DUALPEND940 register
\r
170 strh r1, [r2] @ clear finished job's pending bit
\r
179 movs r12,r12,lsr #1
\r
185 orr r2, r3, #0x4500
\r
186 str r0, [r2] @ clear all pending interrupts in irq controller's SRCPND register
\r
187 orr r2, r2, #0x0010
\r
188 str r0, [r2] @ clear all pending interrupts in irq controller's INTPND register
\r
196 @ some asm utils are also defined here:
\r
197 .global spend_cycles @ c
\r
200 mov r0, r0, lsr #2 @ 4 cycles/iteration
\r
201 sub r0, r0, #2 @ entry/exit/init
\r
209 @ clean-flush function from ARM940T technical reference manual
\r
210 .global dcache_clean_flush
\r
212 dcache_clean_flush:
\r
213 mov r1, #0 @ init line counter
\r
215 mov r0, #0 @ segment counter
\r
217 orr r2, r1, r0 @ make segment and line address
\r
218 mcr p15, 0, r2, c7, c14, 2 @ clean and flush that line
\r
219 add r0, r0, #0x10 @ incremet segment counter
\r
220 cmp r0, #0x40 @ complete all 4 segments?
\r
222 add r1, r1, #0x04000000 @ increment line counter
\r
223 cmp r1, #0 @ complete all lines?
\r
229 @ clean-only version
\r
230 .global dcache_clean
\r
233 mov r1, #0 @ init line counter
\r
235 mov r0, #0 @ segment counter
\r
237 orr r2, r1, r0 @ make segment and line address
\r
238 mcr p15, 0, r2, c7, c10, 2 @ clean that line
\r
239 add r0, r0, #0x10 @ incremet segment counter
\r
240 cmp r0, #0x40 @ complete all 4 segments?
\r
242 add r1, r1, #0x04000000 @ increment line counter
\r
243 cmp r1, #0 @ complete all lines?
\r
248 @ drain write buffer
\r
253 mcr p15, 0, r0, c7, c10, 4
\r
257 .global set_if_not_changed @ int *val, int oldval, int newval
\r
259 set_if_not_changed:
\r
263 strne r3, [r0] @ restore value which was changed there by other core
\r
268 @ pad the protected region.
\r