carl9170: Update to latest upstream
[linux-libre-firmware.git] / aica / arm / crt0.s
1 # KallistiOS ##version##
2 #
3 #  crt0.s
4 #  (c)2000-2002 Dan Potter
5 #
6 #  Startup for ARM program
7 #  Adapted from Marcus' AICA example among a few other sources =)
8
9 .text
10 .globl  arm_main
11 .globl  jps
12
13 # Meaningless but makes the linker shut up
14 .globl  reset
15 reset:
16
17 # Exception vectors
18         b       start
19         b       undef
20         b       softint
21         b       pref_abort
22         b       data_abort
23         b       rsrvd
24         b       irq
25
26
27 # FIQ code adapted from the Marcus AICA example
28 fiq:
29         # Save regs
30         #stmdb  sp!, {r0-r14}
31
32         # Grab interrupt type (store as parameter)
33         ldr     r8,intreq
34         ldr     r9,[r8]
35         and     r9,r9,#7
36
37         # Timer interupt?
38         cmp     r9,#2
39         beq     fiq_timer
40
41         # Bus request?
42         cmp     r9,#5
43         beq     fiq_busreq
44
45         # Dunno -- ack and skip
46         b       fiq_done
47
48 fiq_busreq:
49         # Type 5 is bus request. Wait until the INTBusRequest register
50         # goes back from 0x100.
51         ldr     r8,busreq_control
52 fiq_busreq_loop:
53         # This could probably be done more efficiently, but I'm
54         # no ARM assembly expert...
55         ldr     r9,[r8]
56         and     r9,r9,#0x100
57         cmp     r9,#0
58         bne     fiq_busreq_loop
59
60         b       fiq_done
61
62 fiq_timer:
63         # Type 2 is timer interrupt. Increment timer variable.
64         # Update the next line to AICA_MEM_CLOCK if you change AICA_CMD_IFACE
65         mov     r8,#0x21000
66         ldr     r9,[r8]
67         add     r9,r9,#1
68         str     r9,[r8]
69         
70         # Request a new timer interrupt. We'll calculate the number
71         # put in here based on the "jps" (jiffies per second). 
72         ldr     r8, timer_control
73         mov     r9,#256-(44100/4410)
74 #       ldr     r9,jps
75         str     r9,[r8,#0x10]
76         mov     r9,#0x40
77         str     r9,[r8,#0x24]
78 #       b       fiq_done
79         
80         # Return from interrupt
81 fiq_done:
82
83         # Clear interrupt
84         ldr     r8,intclr
85         mov     r9,#1
86         str     r9,[r8]
87         str     r9,[r8]
88         str     r9,[r8]
89         str     r9,[r8]
90
91         # Restore regs and return
92         #ldmdb  sp!, {r0-r14}
93         subs    pc,r14,#4
94
95 intreq:
96         .long   0x00802d00
97 intclr:
98         .long   0x00802d04
99 timer_control:
100         .long   0x00802880
101 busreq_control:
102         .long   0x00802808
103 jps:
104         # 1000 jiffies per second
105         .long   256-(44100/1000)
106
107
108 start:
109         # Setup a basic stack, disable IRQ, enable FIQ
110         mov     sp,#0xb000
111         mrs     r10,CPSR
112         orr     r10,r10,#0x80
113         bic     r10,r10,#0x40
114         msr     CPSR_all,r10
115
116         # Call the main for the SPU
117         bl      arm_main
118
119         # Loop infinitely if we get here
120 here:   b       here
121
122
123 # Handlers we don't bother to catch
124 undef:
125 softint:
126         mov     pc,r14
127 pref_abort:
128 data_abort:
129 irq:
130 rsrvd:
131         sub     pc,r14,#4