the whitespace hunter has struck again!
[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 #include "ohci.h"
18
19 void irq_initialize(void)
20 {
21         // clear flipper-pic (processor interface)
22         write32(BW_PI_IRQMASK, 0);
23         write32(BW_PI_IRQFLAG, 0xffffffff);
24
25         // clear hollywood-pic
26         write32(HW_PPCIRQMASK, 0);
27         write32(HW_PPCIRQFLAG, 0xffffffff);
28
29         /* ??? -- needed?!
30          * in mini they do
31          *
32          * write32(HW_ARMIRQMASK+0x04, 0);
33          * write32(HW_ARMIRQMASK+0x20, 0);
34          *
35          *
36          * may it's here following; on the other 
37          * hand it's already done by mini...
38          *
39          * write32(HW_PPCIRQMASK+0x04+0x08, 0);
40          * write32(HW_PPCIRQMASK+0x20+0x08, 0);
41          */
42
43         _CPU_ISR_Enable()
44 }
45
46 void irq_shutdown(void)
47 {
48         write32(HW_PPCIRQMASK, 0);
49         write32(HW_PPCIRQFLAG, 0xffffffff);
50         (void) irq_kill();
51 }
52
53 void irq_handler(void)
54 {
55         u32 enabled = read32(BW_PI_IRQMASK);
56         u32 flags = read32(BW_PI_IRQFLAG);
57
58         flags = flags & enabled;
59
60         if (flags & (1<<BW_PI_IRQ_RESET)) { 
61                 write32(BW_PI_IRQFLAG, 1<<BW_PI_IRQ_RESET);
62                 printf("IRQ-BW RESET\n");
63         }
64         if (flags & (1<<BW_PI_IRQ_HW)) { //HW-PIC IRQ
65                 u32 hw_enabled = read32(HW_PPCIRQMASK);
66                 u32 hw_flags = read32(HW_PPCIRQFLAG);
67
68                 //printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", hw_enabled, hw_flags, hw_flags & hw_enabled);
69
70                 hw_flags = hw_flags & hw_enabled;
71
72                 if(hw_flags & IRQF_TIMER) {
73                         write32(HW_PPCIRQFLAG, IRQF_TIMER);
74                 }
75                 if(hw_flags & IRQF_NAND) {
76                         //              printf("IRQ: NAND\n");
77                         // hmmm... should be done by mini?
78                         write32(NAND_CMD, 0x7fffffff); // shut it up
79                         write32(HW_PPCIRQFLAG, IRQF_NAND);
80                         //nand_irq();
81                 }
82                 if(hw_flags & IRQF_GPIO1B) {
83                         //              printf("IRQ: GPIO1B\n");
84                         // hmmm... should be done by mini?
85                         write32(HW_GPIO1BINTFLAG, 0xFFFFFF); // shut it up
86                         write32(HW_PPCIRQFLAG, IRQF_GPIO1B);
87                 }
88                 if(hw_flags & IRQF_GPIO1) {
89                         //              printf("IRQ: GPIO1\n");
90                         // hmmm... should be done by mini?
91                         write32(HW_GPIO1INTFLAG, 0xFFFFFF); // shut it up
92                         write32(HW_PPCIRQFLAG, IRQF_GPIO1);
93                 }
94                 if(hw_flags & IRQF_RESET) {
95                         //              printf("IRQ: RESET\n");
96                         write32(HW_PPCIRQFLAG, IRQF_RESET);
97                 }
98                 if(hw_flags & IRQF_IPC) {
99                         //printf("IRQ: IPC\n");
100                         //not necessary here?
101                         //ipc_irq();
102                         write32(HW_PPCIRQFLAG, IRQF_IPC);
103                 }
104                 if(hw_flags & IRQF_AES) {
105                         //              printf("IRQ: AES\n");
106                         write32(HW_PPCIRQFLAG, IRQF_AES);
107                 }
108                 if (hw_flags & IRQF_SDHC) {
109                         //              printf("IRQ: SDHC\n");
110                         write32(HW_PPCIRQFLAG, IRQF_SDHC);
111                         //sdhc_irq();
112                 }
113                 if (hw_flags & IRQF_OHCI0) {
114                         ohci0_irq();
115                         write32(HW_PPCIRQFLAG, IRQF_OHCI0);
116                 }
117                 if (hw_flags & IRQF_OHCI1) {
118                         //TODO: ohci1_irq();
119                         write32(HW_PPCIRQFLAG, IRQF_OHCI1);
120                 }
121
122                 hw_flags &= ~IRQF_ALL;
123                 if(hw_flags) {
124                         printf("IRQ: unknown 0x%08x\n", hw_flags);
125                         write32(HW_PPCIRQFLAG, hw_flags);
126                 }
127
128                 // not necessary here, but "cleaner"?
129                 write32(BW_PI_IRQFLAG, 1<<BW_PI_IRQ_HW);
130         }
131 }
132
133 void irq_bw_enable(u32 irq)
134 {
135         set32(BW_PI_IRQMASK, 1<<irq);
136 }
137
138 void irq_bw_disable(u32 irq) {
139         clear32(BW_PI_IRQMASK, 1<<irq);
140 }
141
142 void irq_hw_enable(u32 irq)
143 {
144         set32(HW_PPCIRQMASK, 1<<irq);
145 }
146
147 void irq_hw_disable(u32 irq)
148 {
149         clear32(HW_PPCIRQMASK, 1<<irq);
150 }
151
152 u32 irq_kill() {
153         u32 cookie;
154         _CPU_ISR_Disable(cookie);
155         return cookie;
156 }
157
158 void irq_restore(u32 cookie) {
159         _CPU_ISR_Restore(cookie);
160         _CPU_ISR_Enable(); //wtf :/
161 }
162