Merge branch 'isr_test' of git://github.com/theStack/ppcskel into isr_test
[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 OHCI0 interrupt on hollywood-pic
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_IRQFLAG, 0xffffffff);
28 #define BW_PI_IRQ_RESET         1
29 #define BW_PI_IRQ_HW            14
30         write32(BW_PI_IRQMASK, (1<<BW_PI_IRQ_RESET) | (1<<BW_PI_IRQ_HW));
31
32         //??? -- needed?!
33         write32(HW_PPCIRQMASK+0x04, 0);
34         write32(HW_PPCIRQMASK+0x20, 0);
35
36         _CPU_ISR_Enable()
37 }
38
39 void irq_shutdown(void)
40 {
41         write32(HW_PPCIRQMASK, 0);
42         write32(HW_PPCIRQFLAG, 0xffffffff);
43         irq_kill();
44 }
45
46 void irq_handler(void)
47 {
48         u32 enabled = read32(HW_PPCIRQMASK);
49         u32 flags = read32(HW_PPCIRQFLAG);
50         
51         printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", enabled, flags, flags & enabled);
52
53         flags = flags & enabled;
54
55         if(flags & IRQF_TIMER) {
56                 // done by mini already? 
57                 /*
58                 if (_alarm_frequency) {
59                         // currently we use the alarm timer only for lame usbgecko polling
60                         gecko_timer();
61                         write32(HW_ALARM, read32(HW_TIMER) + _alarm_frequency);
62                 }
63                 */
64                 write32(HW_PPCIRQFLAG, IRQF_TIMER);
65         }
66         if(flags & IRQF_NAND) {
67 //              printf("IRQ: NAND\n");
68                 // hmmm... should be done by mini?
69                 write32(NAND_CMD, 0x7fffffff); // shut it up
70                 write32(HW_PPCIRQFLAG, IRQF_NAND);
71                 //nand_irq();
72         }
73         if(flags & IRQF_GPIO1B) {
74 //              printf("IRQ: GPIO1B\n");
75                 // hmmm... should be done by mini?
76                 write32(HW_GPIO1BINTFLAG, 0xFFFFFF); // shut it up
77                 write32(HW_PPCIRQFLAG, IRQF_GPIO1B);
78         }
79         if(flags & IRQF_GPIO1) {
80 //              printf("IRQ: GPIO1\n");
81                 // hmmm... should be done by mini?
82                 write32(HW_GPIO1INTFLAG, 0xFFFFFF); // shut it up
83                 write32(HW_PPCIRQFLAG, IRQF_GPIO1);
84         }
85         if(flags & IRQF_RESET) {
86 //              printf("IRQ: RESET\n");
87                 write32(HW_PPCIRQFLAG, IRQF_RESET);
88         }
89         if(flags & IRQF_IPC) {
90                 //printf("IRQ: IPC\n");
91                 //not necessary here?
92                 //ipc_irq();
93                 write32(HW_PPCIRQFLAG, IRQF_IPC);
94         }
95         if(flags & IRQF_AES) {
96 //              printf("IRQ: AES\n");
97                 write32(HW_PPCIRQFLAG, IRQF_AES);
98         }
99         if (flags & IRQF_SDHC) {
100 //              printf("IRQ: SDHC\n");
101                 write32(HW_PPCIRQFLAG, IRQF_SDHC);
102                 //sdhc_irq();
103         }
104         if (flags & IRQF_OHCI0) {
105                 printf("IRQ: OHCI0\n");
106                 write32(HW_PPCIRQFLAG, IRQF_OHCI0);
107                 //TODO: ohci0_irq();
108         }
109         if (flags & IRQF_OHCI1) {
110                 printf("IRQ: OHCI1\n");
111                 write32(HW_PPCIRQFLAG, IRQF_OHCI1);
112                 //TODO: ohci1_irq();
113         }
114         
115         flags &= ~IRQF_ALL;
116         if(flags) {
117                 printf("IRQ: unknown 0x%08x\n", flags);
118                 write32(HW_PPCIRQFLAG, flags);
119         }
120 }
121
122 void irq_enable(u32 irq)
123 {
124         set32(HW_PPCIRQMASK, 1<<irq);
125 }
126
127 void irq_disable(u32 irq)
128 {
129         clear32(HW_PPCIRQMASK, 1<<irq);
130 }
131
132 inline u32 irq_kill() {
133         u32 cookie;
134         _CPU_ISR_Disable(cookie);
135         return cookie;
136 }
137
138 inline void irq_restore(u32 cookie) {
139         _CPU_ISR_Restore(cookie);
140 }
141