PCM sound, refactored code940
[picodrive.git] / platform / gp2x / code940 / 940init.s
... / ...
CommitLineData
1.global code940\r
2\r
3.equ mmsp2_regs, (0xc0000000-0x02000000) @ assume we live @ 0x2000000 bank\r
4\r
5code940: @ interrupt table:\r
6 b .b_reset @ reset\r
7 b .b_undef @ undefined instructions\r
8 b .b_swi @ software interrupt\r
9 b .b_pabort @ prefetch abort\r
10 b .b_dabort @ data abort\r
11 b .b_reserved @ reserved\r
12 b .b_irq @ IRQ\r
13 b .b_fiq @ FIQ\r
14\r
15@ test\r
16.b_reset:\r
17 mov r12, #0\r
18 b .Begin\r
19.b_undef:\r
20 mov r12, #1\r
21 b .Begin\r
22.b_swi:\r
23 mov r12, #2\r
24 b .Begin\r
25.b_pabort:\r
26 mov r12, #3\r
27 b .Begin\r
28.b_dabort:\r
29 mov r12, #4\r
30 b .Begin\r
31.b_reserved:\r
32 mov r12, #5\r
33 b .Begin\r
34.b_irq:\r
35 mov r12, #6\r
36 mov sp, #0x100000 @ reset stack\r
37 sub sp, sp, #4\r
38 mov r1, #mmsp2_regs\r
39 orr r2, r1, #0x3B00\r
40 orr r2, r2, #0x0046\r
41 mvn r3, #0\r
42 strh r3, [r2] @ clear any pending interrupts from the DUALCPU unit\r
43 orr r2, r1, #0x4500\r
44 str r3, [r2] @ clear all pending interrupts in irq controller's SRCPND register\r
45 orr r2, r2, #0x0010\r
46 str r3, [r2] @ clear all pending interrupts in irq controller's INTPND register\r
47 b .Enter\r
48.b_fiq:\r
49 mov r12, #7\r
50 b .Begin\r
51\r
52.Begin:\r
53 mov sp, #0x100000 @ set the stack top (1M)\r
54 sub sp, sp, #4 @ minus 4\r
55\r
56 @ set up memory region 0 -- the whole 4GB address space\r
57 mov r0, #(0x1f<<1)|1 @ region data\r
58 mcr p15, 0, r0, c6, c0, 0 @ opcode2 ~ data/instr\r
59 mcr p15, 0, r0, c6, c0, 1\r
60\r
61 @ set up region 1 which is the first 2 megabytes.\r
62 mov r0, #(0x14<<1)|1 @ region data\r
63 mcr p15, 0, r0, c6, c1, 0\r
64 mcr p15, 0, r0, c6, c1, 1\r
65\r
66 @ set up region 2: 64k 0x200000-0x210000\r
67 mov r0, #(0x0f<<1)|1\r
68 orr r0, r0, #0x200000\r
69 mcr p15, 0, r0, c6, c2, 0\r
70 mcr p15, 0, r0, c6, c2, 1\r
71\r
72 @ set up region 3: 64k 0xbe000000-0xbe010000 (hw control registers)\r
73 mov r0, #(0x0f<<1)|1\r
74 orr r0, r0, #mmsp2_regs\r
75 mcr p15, 0, r0, c6, c3, 0\r
76 mcr p15, 0, r0, c6, c3, 1\r
77\r
78 @ set up region 4: 16M 0x01000000-0x02000000 (mp3 area)\r
79 mov r0, #(0x17<<1)|1\r
80 orr r0, r0, #0x01000000\r
81 mcr p15, 0, r0, c6, c4, 0\r
82 mcr p15, 0, r0, c6, c4, 1\r
83\r
84 @ set regions 1 and 4 to be cacheable (so the first 2M and mp3 area will be cacheable)\r
85 mov r0, #(1<<1)|(1<<4)\r
86 mcr p15, 0, r0, c2, c0, 0\r
87 mcr p15, 0, r0, c2, c0, 1\r
88\r
89 @ set region 1 to be bufferable too (only data)\r
90 mov r0, #(1<<1)\r
91 mcr p15, 0, r0, c3, c0, 0\r
92\r
93 @ set protection, allow access only to regions 1 and 2\r
94 mov r0, #(3<<8)|(3<<6)|(3<<4)|(3<<2)|(0) @ data: [full, full, full, full, no access] for regions [4 3 2 1 0]\r
95 mcr p15, 0, r0, c5, c0, 0\r
96 mov r0, #(0<<8)|(0<<6)|(0<<4)|(3<<2)|(0) @ instructions: [no access, no, no, full, no]\r
97 mcr p15, 0, r0, c5, c0, 1\r
98\r
99 mrc p15, 0, r0, c1, c0, 0 @ fetch current control reg\r
100 orr r0, r0, #1 @ 0x00000001: enable protection unit\r
101 orr r0, r0, #4 @ 0x00000004: enable D cache\r
102 orr r0, r0, #0x1000 @ 0x00001000: enable I cache\r
103@ bic r0, r0, #0xC0000000\r
104@ orr r0, r0, #0x40000000 @ 0x40000000: synchronous, faster?\r
105 orr r0, r0, #0xC0000000 @ 0xC0000000: async\r
106 mcr p15, 0, r0, c1, c0, 0 @ set control reg\r
107\r
108 @ flush (invalidate) the cache (just in case)\r
109 mov r0, #0\r
110 mcr p15, 0, r0, c7, c6, 0\r
111\r
112.Enter:\r
113 mov r0, r12\r
114 mov r1, lr\r
115 bl Main940\r
116\r
117 @ we should never get here\r
118@.b_deadloop:\r
119@ b .b_deadloop\r
120 b .b_reserved\r
121\r
122\r
123\r
124@ so asm utils are also defined here:\r
125.global spend_cycles @ c\r
126\r
127spend_cycles:\r
128 mov r0, r0, lsr #2 @ 4 cycles/iteration\r
129 sub r0, r0, #2 @ entry/exit/init\r
130.sc_loop:\r
131 subs r0, r0, #1\r
132 bpl .sc_loop\r
133\r
134 bx lr\r
135\r
136\r
137@ clean-flush function from ARM940T technical reference manual\r
138.global cache_clean_flush\r
139\r
140cache_clean_flush:\r
141 mov r1, #0 @ init line counter\r
142ccf_outer_loop:\r
143 mov r0, #0 @ segment counter\r
144ccf_inner_loop:\r
145 orr r2, r1, r0 @ make segment and line address\r
146 mcr p15, 0, r2, c7, c14, 2 @ clean and flush that line\r
147 add r0, r0, #0x10 @ incremet secment counter\r
148 cmp r0, #0x40 @ complete all 4 segments?\r
149 bne ccf_inner_loop\r
150 add r1, r1, #0x04000000 @ increment line counter\r
151 cmp r1, #0 @ complete all lines?\r
152 bne ccf_outer_loop\r
153 bx lr\r
154\r
155\r
156@ clean-only version\r
157.global cache_clean\r
158\r
159cache_clean:\r
160 mov r1, #0 @ init line counter\r
161cf_outer_loop:\r
162 mov r0, #0 @ segment counter\r
163cf_inner_loop:\r
164 orr r2, r1, r0 @ make segment and line address\r
165 mcr p15, 0, r2, c7, c10, 2 @ clean that line\r
166 add r0, r0, #0x10 @ incremet secment counter\r
167 cmp r0, #0x40 @ complete all 4 segments?\r
168 bne cf_inner_loop\r
169 add r1, r1, #0x04000000 @ increment line counter\r
170 cmp r1, #0 @ complete all lines?\r
171 bne cf_outer_loop\r
172 bx lr\r
173\r
174\r
175.global wait_irq\r
176\r
177wait_irq:\r
178 mov r0, #mmsp2_regs\r
179 orr r0, r0, #0x3B00\r
180 orr r1, r0, #0x0042\r
181 mov r3, #0\r
182 strh r3, [r1] @ disable interrupts\r
183 orr r2, r0, #0x003E\r
184 strh r3, [r2] @ remove busy flag\r
185 mov r3, #1\r
186 strh r3, [r1] @ enable interrupts\r
187\r
188 mrs r0, cpsr\r
189 bic r0, r0, #0x80\r
190 msr cpsr_c, r0 @ enable interrupts\r
191\r
192 mov r0, #0\r
193 mcr p15, 0, r0, c7, c0, 4 @ wait for IRQ\r
194@ mcr p15, 0, r0, c15, c8, 2\r
195 nop\r
196 nop\r
197 b .b_reserved\r
198\r
199.pool\r
200\r
201\r
202.global set_if_not_changed @ int *val, int oldval, int newval\r
203\r
204set_if_not_changed:\r
205 swp r3, r2, [r0]\r
206 cmp r1, r3\r
207 bxeq lr\r
208 strne r3, [r0] @ restore value which was changed there by other core\r
209 bx lr\r
210\r
211@ vim:filetype=armasm:\r