some audio problems fixed, missing files added
[picodrive.git] / platform / gp2x / code940 / 940init.s
1 @ vim:filetype=armasm:\r
2 \r
3 \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
6 \r
7 \r
8 @ exception table:\r
9 .global code940\r
10 code940:\r
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
40     mov     sp, #0x100000       @ reset stack\r
41     sub     sp, sp, #4\r
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
57 .b_fiq:\r
58     mov     r12, #7\r
59     b       .Begin\r
60 \r
61 .Begin:\r
62     mov sp, #0x100000           @ set the stack top (1M)\r
63     sub sp, sp, #4              @ minus 4\r
64 \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
69 \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
74 \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
80 \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
86 \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
92 \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
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
100     mcr p15, 0, r0, c2, c0, 0\r
101     mcr p15, 0, r0, c2, c0, 1\r
102 \r
103     @ set region 1 to be bufferable too (only data)\r
104     mov r0, #(1<<1)\r
105     mcr p15, 0, r0, c3, c0, 0\r
106 \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
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
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
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
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
142 wait_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
154 \r
155 \r
156 @ next job getter\r
157 .global wait_get_job @ int oldjob\r
158 \r
159 wait_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
164 \r
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
173 wgj_no_old:\r
174     tst     r12,r12\r
175     beq     wgj_no_jobs\r
176     mov     r0, #0\r
177 wgj_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
183 wgj_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
197 .global spend_cycles @ c\r
198 \r
199 spend_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
210 .global dcache_clean_flush\r
211 \r
212 dcache_clean_flush:\r
213     mov     r1, #0                  @ init line counter\r
214 ccf_outer_loop:\r
215     mov     r0, #0                  @ segment counter\r
216 ccf_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
219     add     r0, r0, #0x10           @ incremet segment counter\r
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
228 \r
229 @ clean-only version\r
230 .global dcache_clean\r
231 \r
232 dcache_clean:\r
233     mov     r1, #0                  @ init line counter\r
234 cf_outer_loop:\r
235     mov     r0, #0                  @ segment counter\r
236 cf_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
239     add     r0, r0, #0x10           @ incremet segment counter\r
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
248 @ drain write buffer\r
249 .global drain_wb\r
250 \r
251 drain_wb:\r
252     mov     r0, #0\r
253     mcr     p15, 0, r0, c7, c10, 4\r
254     bx      lr\r
255 \r
256 \r
257 .global set_if_not_changed @ int *val, int oldval, int newval\r
258 \r
259 set_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
266 \r
267 \r
268 @ pad the protected region.\r
269 .rept 1024\r
270 .long 0\r
271 .endr\r
272 \r