some audio problems fixed, missing files added
[picodrive.git] / platform / gp2x / code940 / 940init.s
CommitLineData
abe0ea43 1@ vim:filetype=armasm:\r
2\r
cc68a136 3\r
4f265db7 4.equ mmsp2_regs, (0xc0000000-0x02000000) @ assume we live @ 0x2000000 bank\r
abe0ea43 5.equ shared_ctl, 0x00200000 @ this is where shared_ctl struncture is located\r
6\r
4f265db7 7\r
abe0ea43 8@ exception table:\r
9.global code940\r
10code940:\r
cc68a136 11 b .b_reset @ reset\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
17 b .b_irq @ IRQ\r
18 b .b_fiq @ FIQ\r
19\r
20@ test\r
21.b_reset:\r
22 mov r12, #0\r
23 b .Begin\r
24.b_undef:\r
25 mov r12, #1\r
26 b .Begin\r
27.b_swi:\r
28 mov r12, #2\r
29 b .Begin\r
30.b_pabort:\r
31 mov r12, #3\r
32 b .Begin\r
33.b_dabort:\r
34 mov r12, #4\r
35 b .Begin\r
36.b_reserved:\r
37 mov r12, #5\r
38 b .Begin\r
39.b_irq:\r
b837b69b 40 mov sp, #0x100000 @ reset stack\r
41 sub sp, sp, #4\r
abe0ea43 42 mov r0, #shared_ctl @ remember where we were when interrupt happened\r
43 add r0, r0, #0x20\r
44 str lr, [r0]\r
45 mov r0, #shared_ctl @ increment exception counter (for debug)\r
46 add r0, r0, #(6*4)\r
47 ldr r1, [r0]\r
48 add r1, r1, #1\r
49 str r1, [r0]\r
50\r
51 bl Main940\r
52\r
53 @ we should never get here\r
54 b .b_reserved\r
55\r
56\r
cc68a136 57.b_fiq:\r
58 mov r12, #7\r
59 b .Begin\r
60\r
61.Begin:\r
b837b69b 62 mov sp, #0x100000 @ set the stack top (1M)\r
63 sub sp, sp, #4 @ minus 4\r
cc68a136 64\r
b837b69b 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
cc68a136 69\r
70 @ set up region 1 which is the first 2 megabytes.\r
b837b69b 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
cc68a136 74\r
75 @ set up region 2: 64k 0x200000-0x210000\r
b837b69b 76 mov r0, #(0x0f<<1)|1\r
cc68a136 77 orr r0, r0, #0x200000\r
b837b69b 78 mcr p15, 0, r0, c6, c2, 0\r
79 mcr p15, 0, r0, c6, c2, 1\r
cc68a136 80\r
b837b69b 81 @ set up region 3: 64k 0xbe000000-0xbe010000 (hw control registers)\r
82 mov r0, #(0x0f<<1)|1\r
4f265db7 83 orr r0, r0, #mmsp2_regs\r
b837b69b 84 mcr p15, 0, r0, c6, c3, 0\r
85 mcr p15, 0, r0, c6, c3, 1\r
cc68a136 86\r
42c7b147 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
92\r
abe0ea43 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
97\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
b837b69b 100 mcr p15, 0, r0, c2, c0, 0\r
101 mcr p15, 0, r0, c2, c0, 1\r
cc68a136 102\r
103 @ set region 1 to be bufferable too (only data)\r
42c7b147 104 mov r0, #(1<<1)\r
b837b69b 105 mcr p15, 0, r0, c3, c0, 0\r
cc68a136 106\r
abe0ea43 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
b837b69b 110 mcr p15, 0, r0, c5, c0, 0\r
abe0ea43 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
b837b69b 114 mcr p15, 0, r0, c5, c0, 1\r
115\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
4f265db7 120@ bic r0, r0, #0xC0000000\r
121@ orr r0, r0, #0x40000000 @ 0x40000000: synchronous, faster?\r
122 orr r0, r0, #0xC0000000 @ 0xC0000000: async\r
b837b69b 123 mcr p15, 0, r0, c1, c0, 0 @ set control reg\r
cc68a136 124\r
125 @ flush (invalidate) the cache (just in case)\r
126 mov r0, #0\r
127 mcr p15, 0, r0, c7, c6, 0\r
128\r
abe0ea43 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
132 ldr r1, [r0]\r
133 add r1, r1, #1\r
134 str r1, [r0]\r
135 \r
136 @ remember last lr (for debug)\r
137 mov r0, #shared_ctl\r
138 add r0, r0, #0x20\r
139 str lr, [r0]\r
140\r
141 @ ready to take first job-interrupt\r
142wait_for_irq:\r
143 mrs r0, cpsr\r
144 bic r0, r0, #0x80\r
145 msr cpsr_c, r0 @ enable interrupts\r
146\r
147 mov r0, #0\r
148 mcr p15, 0, r0, c7, c0, 4 @ wait for IRQ\r
149@ mcr p15, 0, r0, c15, c8, 2\r
150 nop\r
151 nop\r
152 b .b_reserved\r
153\r
cc68a136 154\r
cc68a136 155\r
abe0ea43 156@ next job getter\r
157.global wait_get_job @ int oldjob\r
cc68a136 158\r
abe0ea43 159wait_get_job:\r
160 mov r3, #mmsp2_regs\r
161 orr r2, r3, #0x3B00\r
162 orr r2, r2, #0x0046 @ DUALPEND940 register\r
163 ldrh r12,[r2]\r
cc68a136 164\r
abe0ea43 165 tst r0, r0\r
166 beq wgj_no_old\r
167 sub r0, r0, #1\r
168 mov r1, #1\r
169 mov r1, r1, lsl r0\r
170 strh r1, [r2] @ clear finished job's pending bit\r
171 bic r12,r12,r1\r
172\r
173wgj_no_old:\r
174 tst r12,r12\r
175 beq wgj_no_jobs\r
176 mov r0, #0\r
177wgj_loop:\r
178 add r0, r0, #1\r
179 movs r12,r12,lsr #1\r
180 bxcs lr\r
181 b wgj_loop\r
182\r
183wgj_no_jobs:\r
184 mvn r0, #0\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
189 b wait_for_irq\r
190\r
191.pool\r
192\r
193\r
194\r
195\r
196@ some asm utils are also defined here:\r
cc68a136 197.global spend_cycles @ c\r
198\r
199spend_cycles:\r
200 mov r0, r0, lsr #2 @ 4 cycles/iteration\r
201 sub r0, r0, #2 @ entry/exit/init\r
202.sc_loop:\r
203 subs r0, r0, #1\r
204 bpl .sc_loop\r
205\r
206 bx lr\r
207\r
208\r
209@ clean-flush function from ARM940T technical reference manual\r
abe0ea43 210.global dcache_clean_flush\r
cc68a136 211\r
abe0ea43 212dcache_clean_flush:\r
cc68a136 213 mov r1, #0 @ init line counter\r
214ccf_outer_loop:\r
215 mov r0, #0 @ segment counter\r
216ccf_inner_loop:\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
abe0ea43 219 add r0, r0, #0x10 @ incremet segment counter\r
cc68a136 220 cmp r0, #0x40 @ complete all 4 segments?\r
221 bne ccf_inner_loop\r
222 add r1, r1, #0x04000000 @ increment line counter\r
223 cmp r1, #0 @ complete all lines?\r
224 bne ccf_outer_loop\r
225 bx lr\r
226\r
227\r
abe0ea43 228\r
cc68a136 229@ clean-only version\r
abe0ea43 230.global dcache_clean\r
cc68a136 231\r
abe0ea43 232dcache_clean:\r
cc68a136 233 mov r1, #0 @ init line counter\r
234cf_outer_loop:\r
235 mov r0, #0 @ segment counter\r
236cf_inner_loop:\r
237 orr r2, r1, r0 @ make segment and line address\r
238 mcr p15, 0, r2, c7, c10, 2 @ clean that line\r
abe0ea43 239 add r0, r0, #0x10 @ incremet segment counter\r
cc68a136 240 cmp r0, #0x40 @ complete all 4 segments?\r
241 bne cf_inner_loop\r
242 add r1, r1, #0x04000000 @ increment line counter\r
243 cmp r1, #0 @ complete all lines?\r
244 bne cf_outer_loop\r
245 bx lr\r
246\r
247\r
abe0ea43 248@ drain write buffer\r
249.global drain_wb\r
cc68a136 250\r
abe0ea43 251drain_wb:\r
cc68a136 252 mov r0, #0\r
abe0ea43 253 mcr p15, 0, r0, c7, c10, 4\r
254 bx lr\r
b837b69b 255\r
51a902ae 256\r
257.global set_if_not_changed @ int *val, int oldval, int newval\r
258\r
259set_if_not_changed:\r
260 swp r3, r2, [r0]\r
261 cmp r1, r3\r
262 bxeq lr\r
263 strne r3, [r0] @ restore value which was changed there by other core\r
264 bx lr\r
265\r
abe0ea43 266\r
267\r
268@ pad the protected region.\r
269.rept 1024\r
270.long 0\r
271.endr\r
272\r