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