WIP: irq_handler
[ppcskel.git] / irq.c
1 /*
2         ppcskel - a Free Software replacement for the Nintendo/BroadOn IOS.
3         IRQ support
4
5 Copyright (C) 2008, 2009        Hector Martin "marcan" <marcan@marcansoft.com>
6 Copyright (C) 2008, 2009        Sven Peter <svenpeter@gmail.com>
7 Copyright (C) 2009                      Andre Heider "dhewg" <dhewg@wiibrew.org>
8
9 # This code is licensed to you under the terms of the GNU GPL, version 2;
10 # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
11 */
12
13 #include "irq.h"
14 #include "hollywood.h"
15 #include "ipc.h"
16 #include "bootmii_ppc.h"
17 //debug only
18 #include "printf.h"
19
20 void irq_initialize(void)
21 {
22         // enable hollywood-pic for ppc
23         write32(HW_PPCIRQMASK, 0);
24         write32(HW_PPCIRQFLAG, 0xffffffff);
25
26         // enable RESET and PIC (#14) interrupts on processor interface
27         write32(BW_PI_IRQMASK, 0);
28         write32(BW_PI_IRQFLAG, 0xffffffff);
29
30         //??? -- needed?!
31         /*
32         write32(HW_PPCIRQMASK+0x04, 0);
33         write32(HW_PPCIRQMASK+0x20, 0);
34         */
35
36         _CPU_ISR_Enable()
37 }
38
39 void irq_shutdown(void)
40 {
41         write32(HW_PPCIRQMASK, 0);
42         write32(HW_PPCIRQFLAG, 0xffffffff);
43         (void) irq_kill();
44 }
45
46 void irq_handler(void)
47 {
48         u32 enabled = read32(BW_PI_IRQMASK);
49         u32 flags = read32(BW_PI_IRQFLAG);
50         printf("flags1: 0x%08X\n", flags);
51
52         flags = flags & enabled;
53
54         if (flags & (1<<1)) { //RESET
55                 write32(BW_PI_IRQFLAG, 1<<BW_PI_IRQ_RESET);
56                 printf("IRQ RESET\n");
57         }
58         if (flags & (1<<14)) { //HW-PIC IRQ
59                 u32 hw_enabled = read32(HW_PPCIRQMASK);
60                 u32 hw_flags = read32(HW_PPCIRQFLAG);
61
62                 printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", hw_enabled, hw_flags, hw_flags & hw_enabled);
63
64                 hw_flags = hw_flags & hw_enabled;
65
66                 if(hw_flags & IRQF_TIMER) {
67                         // done by mini already? 
68                         /*
69                            if (_alarm_frequency) {
70                         // currently we use the alarm timer only for lame usbgecko polling
71                         gecko_timer();
72                         write32(HW_ALARM, read32(HW_TIMER) + _alarm_frequency);
73                         }
74                         */
75                         write32(HW_PPCIRQFLAG, IRQF_TIMER);
76                 }
77                 if(hw_flags & IRQF_NAND) {
78                         //              printf("IRQ: NAND\n");
79                         // hmmm... should be done by mini?
80                         write32(NAND_CMD, 0x7fffffff); // shut it up
81                         write32(HW_PPCIRQFLAG, IRQF_NAND);
82                         //nand_irq();
83                 }
84                 if(hw_flags & IRQF_GPIO1B) {
85                         //              printf("IRQ: GPIO1B\n");
86                         // hmmm... should be done by mini?
87                         write32(HW_GPIO1BINTFLAG, 0xFFFFFF); // shut it up
88                         write32(HW_PPCIRQFLAG, IRQF_GPIO1B);
89                 }
90                 if(hw_flags & IRQF_GPIO1) {
91                         //              printf("IRQ: GPIO1\n");
92                         // hmmm... should be done by mini?
93                         write32(HW_GPIO1INTFLAG, 0xFFFFFF); // shut it up
94                         write32(HW_PPCIRQFLAG, IRQF_GPIO1);
95                 }
96                 if(hw_flags & IRQF_RESET) {
97                         //              printf("IRQ: RESET\n");
98                         write32(HW_PPCIRQFLAG, IRQF_RESET);
99                 }
100                 if(hw_flags & IRQF_IPC) {
101                         //printf("IRQ: IPC\n");
102                         //not necessary here?
103                         //ipc_irq();
104                         write32(HW_PPCIRQFLAG, IRQF_IPC);
105                 }
106                 if(hw_flags & IRQF_AES) {
107                         //              printf("IRQ: AES\n");
108                         write32(HW_PPCIRQFLAG, IRQF_AES);
109                 }
110                 if (hw_flags & IRQF_SDHC) {
111                         //              printf("IRQ: SDHC\n");
112                         write32(HW_PPCIRQFLAG, IRQF_SDHC);
113                         //sdhc_irq();
114                 }
115                 if (hw_flags & IRQF_OHCI0) {
116                         printf("IRQ: OHCI0\n");
117                         write32(HW_PPCIRQFLAG, IRQF_OHCI0);
118                         //TODO: ohci0_irq();
119                 }
120                 if (hw_flags & IRQF_OHCI1) {
121                         printf("IRQ: OHCI1\n");
122                         write32(HW_PPCIRQFLAG, IRQF_OHCI1);
123                         //TODO: ohci1_irq();
124                 }
125
126                 hw_flags &= ~IRQF_ALL;
127                 if(hw_flags) {
128                         printf("IRQ: unknown 0x%08x\n", hw_flags);
129                         write32(HW_PPCIRQFLAG, hw_flags);
130                 }
131                 write32(BW_PI_IRQFLAG, 1<<BW_PI_IRQ_HW);
132                 u32 flags2 = read32(BW_PI_IRQFLAG);
133                 printf("flags2: 0x%08X\n", flags2);
134         }
135
136 //      flags &= 
137 }
138
139 void irq_bw_enable(u32 irq)
140 {
141         set32(BW_PI_IRQMASK, 1<<irq);
142 }
143
144 void irq_bw_disable(u32 irq) {
145         clear32(BW_PI_IRQMASK, 1<<irq);
146 }
147
148 void irq_hw_enable(u32 irq)
149 {
150         set32(HW_PPCIRQMASK, 1<<irq);
151 }
152
153 void irq_hw_disable(u32 irq)
154 {
155         clear32(HW_PPCIRQMASK, 1<<irq);
156 }
157
158 u32 irq_kill() {
159         u32 cookie;
160         _CPU_ISR_Disable(cookie);
161         return cookie;
162 }
163
164 void irq_restore(u32 cookie) {
165         _CPU_ISR_Restore(cookie);
166 }
167