WIP: irq_handler
authorBernhard Urban <lewurm@gmx.net>
Thu, 3 Sep 2009 00:17:32 +0000 (02:17 +0200)
committerBernhard Urban <lewurm@gmx.net>
Thu, 3 Sep 2009 00:17:32 +0000 (02:17 +0200)
exception.c
irq.c
irq.h
main.c

index b2c5373b2f50a7eaeee780b57c52774e24b7123a..2d7451ecb8166db387559902ec6c43dc6c27b47e 100644 (file)
@@ -18,43 +18,44 @@ extern char exception_2200_start, exception_2200_end;
 
 void exception_handler(int exception)
 {
-       // check if the exception was actually an interrupt
+       // check if the exception was actually an external interrupt
        if (exception == 0x500) {
                u32 cookie = irq_kill();
                irq_handler();
                irq_restore(cookie);
-               return;
+               //_CPU_ISR_Enable(); //wtf
        }
 
        // check if exception happened due to the decrementer
-       if (exception == 0x900) {
+       else if (exception == 0x900) {
                printf("\nDecrementer exception occured - who cares?\n");
-               return;
        }
 
-       u32 *x;
-       u32 i;
+       else {
+               u32 *x;
+               u32 i;
 
-       printf("\nException %04x occurred!\n", exception);
+               printf("\nException %04X occurred!\n", exception);
 
-       x = (u32 *)0x80002000;
+               x = (u32 *)0x80002000;
 
-       printf("\n R0..R7    R8..R15  R16..R23  R24..R31\n");
-       for (i = 0; i < 8; i++) {
-               printf("%08x  %08x  %08x  %08x\n", x[0], x[8], x[16], x[24]);
-               x++;
-       }
-       x = (u32 *)0x80002080;
+               printf("\n R0..R7    R8..R15  R16..R23  R24..R31\n");
+               for (i = 0; i < 8; i++) {
+                       printf("%08x  %08x  %08x  %08x\n", x[0], x[8], x[16], x[24]);
+                       x++;
+               }
+               x = (u32 *)0x80002080;
 
-       printf("\n CR/XER    LR/CTR  SRR0/SRR1 DAR/DSISR\n");
-       for (i = 0; i < 2; i++) {
-               printf("%08x  %08x  %08x  %08x\n", x[0], x[2], x[4], x[6]);
-               x++;
-       }
+               printf("\n CR/XER    LR/CTR  SRR0/SRR1 DAR/DSISR\n");
+               for (i = 0; i < 2; i++) {
+                       printf("%08x  %08x  %08x  %08x\n", x[0], x[2], x[4], x[6]);
+                       x++;
+               }
 
-       // Hang.
-       for (;;)
-               ;
+               // Hang.
+               for (;;)
+                       ;
+       }
 }
 
 void exception_init(void)
diff --git a/irq.c b/irq.c
index 9ab1559505b5a14be4b6619389a1a7db569a9683..1c5902b6de6f34af6700e3254f4452e7188b94b9 100644 (file)
--- a/irq.c
+++ b/irq.c
@@ -19,19 +19,19 @@ Copyright (C) 2009                  Andre Heider "dhewg" <dhewg@wiibrew.org>
 
 void irq_initialize(void)
 {
-       // enable OHCI0 interrupt on hollywood-pic
+       // enable hollywood-pic for ppc
        write32(HW_PPCIRQMASK, 0);
        write32(HW_PPCIRQFLAG, 0xffffffff);
 
        // enable RESET and PIC (#14) interrupts on processor interface
+       write32(BW_PI_IRQMASK, 0);
        write32(BW_PI_IRQFLAG, 0xffffffff);
-#define BW_PI_IRQ_RESET        1
-#define BW_PI_IRQ_HW           14
-       write32(BW_PI_IRQMASK, (1<<BW_PI_IRQ_RESET) | (1<<BW_PI_IRQ_HW));
 
        //??? -- needed?!
+       /*
        write32(HW_PPCIRQMASK+0x04, 0);
        write32(HW_PPCIRQMASK+0x20, 0);
+       */
 
        _CPU_ISR_Enable()
 }
@@ -40,102 +40,128 @@ void irq_shutdown(void)
 {
        write32(HW_PPCIRQMASK, 0);
        write32(HW_PPCIRQFLAG, 0xffffffff);
-       irq_kill();
+       (void) irq_kill();
 }
 
 void irq_handler(void)
 {
-       u32 enabled = read32(HW_PPCIRQMASK);
-       u32 flags = read32(HW_PPCIRQFLAG);
-       
-       printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", enabled, flags, flags & enabled);
+       u32 enabled = read32(BW_PI_IRQMASK);
+       u32 flags = read32(BW_PI_IRQFLAG);
+       printf("flags1: 0x%08X\n", flags);
 
        flags = flags & enabled;
 
-       if(flags & IRQF_TIMER) {
-               // done by mini already? 
-               /*
-               if (_alarm_frequency) {
+       if (flags & (1<<1)) { //RESET
+               write32(BW_PI_IRQFLAG, 1<<BW_PI_IRQ_RESET);
+               printf("IRQ RESET\n");
+       }
+       if (flags & (1<<14)) { //HW-PIC IRQ
+               u32 hw_enabled = read32(HW_PPCIRQMASK);
+               u32 hw_flags = read32(HW_PPCIRQFLAG);
+
+               printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", hw_enabled, hw_flags, hw_flags & hw_enabled);
+
+               hw_flags = hw_flags & hw_enabled;
+
+               if(hw_flags & IRQF_TIMER) {
+                       // done by mini already? 
+                       /*
+                          if (_alarm_frequency) {
                        // currently we use the alarm timer only for lame usbgecko polling
                        gecko_timer();
                        write32(HW_ALARM, read32(HW_TIMER) + _alarm_frequency);
+                       }
+                       */
+                       write32(HW_PPCIRQFLAG, IRQF_TIMER);
                }
-               */
-               write32(HW_PPCIRQFLAG, IRQF_TIMER);
-       }
-       if(flags & IRQF_NAND) {
-//             printf("IRQ: NAND\n");
-               // hmmm... should be done by mini?
-               write32(NAND_CMD, 0x7fffffff); // shut it up
-               write32(HW_PPCIRQFLAG, IRQF_NAND);
-               //nand_irq();
-       }
-       if(flags & IRQF_GPIO1B) {
-//             printf("IRQ: GPIO1B\n");
-               // hmmm... should be done by mini?
-               write32(HW_GPIO1BINTFLAG, 0xFFFFFF); // shut it up
-               write32(HW_PPCIRQFLAG, IRQF_GPIO1B);
-       }
-       if(flags & IRQF_GPIO1) {
-//             printf("IRQ: GPIO1\n");
-               // hmmm... should be done by mini?
-               write32(HW_GPIO1INTFLAG, 0xFFFFFF); // shut it up
-               write32(HW_PPCIRQFLAG, IRQF_GPIO1);
-       }
-       if(flags & IRQF_RESET) {
-//             printf("IRQ: RESET\n");
-               write32(HW_PPCIRQFLAG, IRQF_RESET);
-       }
-       if(flags & IRQF_IPC) {
-               //printf("IRQ: IPC\n");
-               //not necessary here?
-               //ipc_irq();
-               write32(HW_PPCIRQFLAG, IRQF_IPC);
-       }
-       if(flags & IRQF_AES) {
-//             printf("IRQ: AES\n");
-               write32(HW_PPCIRQFLAG, IRQF_AES);
-       }
-       if (flags & IRQF_SDHC) {
-//             printf("IRQ: SDHC\n");
-               write32(HW_PPCIRQFLAG, IRQF_SDHC);
-               //sdhc_irq();
-       }
-       if (flags & IRQF_OHCI0) {
-               printf("IRQ: OHCI0\n");
-               write32(HW_PPCIRQFLAG, IRQF_OHCI0);
-               //TODO: ohci0_irq();
-       }
-       if (flags & IRQF_OHCI1) {
-               printf("IRQ: OHCI1\n");
-               write32(HW_PPCIRQFLAG, IRQF_OHCI1);
-               //TODO: ohci1_irq();
-       }
-       
-       flags &= ~IRQF_ALL;
-       if(flags) {
-               printf("IRQ: unknown 0x%08x\n", flags);
-               write32(HW_PPCIRQFLAG, flags);
+               if(hw_flags & IRQF_NAND) {
+                       //              printf("IRQ: NAND\n");
+                       // hmmm... should be done by mini?
+                       write32(NAND_CMD, 0x7fffffff); // shut it up
+                       write32(HW_PPCIRQFLAG, IRQF_NAND);
+                       //nand_irq();
+               }
+               if(hw_flags & IRQF_GPIO1B) {
+                       //              printf("IRQ: GPIO1B\n");
+                       // hmmm... should be done by mini?
+                       write32(HW_GPIO1BINTFLAG, 0xFFFFFF); // shut it up
+                       write32(HW_PPCIRQFLAG, IRQF_GPIO1B);
+               }
+               if(hw_flags & IRQF_GPIO1) {
+                       //              printf("IRQ: GPIO1\n");
+                       // hmmm... should be done by mini?
+                       write32(HW_GPIO1INTFLAG, 0xFFFFFF); // shut it up
+                       write32(HW_PPCIRQFLAG, IRQF_GPIO1);
+               }
+               if(hw_flags & IRQF_RESET) {
+                       //              printf("IRQ: RESET\n");
+                       write32(HW_PPCIRQFLAG, IRQF_RESET);
+               }
+               if(hw_flags & IRQF_IPC) {
+                       //printf("IRQ: IPC\n");
+                       //not necessary here?
+                       //ipc_irq();
+                       write32(HW_PPCIRQFLAG, IRQF_IPC);
+               }
+               if(hw_flags & IRQF_AES) {
+                       //              printf("IRQ: AES\n");
+                       write32(HW_PPCIRQFLAG, IRQF_AES);
+               }
+               if (hw_flags & IRQF_SDHC) {
+                       //              printf("IRQ: SDHC\n");
+                       write32(HW_PPCIRQFLAG, IRQF_SDHC);
+                       //sdhc_irq();
+               }
+               if (hw_flags & IRQF_OHCI0) {
+                       printf("IRQ: OHCI0\n");
+                       write32(HW_PPCIRQFLAG, IRQF_OHCI0);
+                       //TODO: ohci0_irq();
+               }
+               if (hw_flags & IRQF_OHCI1) {
+                       printf("IRQ: OHCI1\n");
+                       write32(HW_PPCIRQFLAG, IRQF_OHCI1);
+                       //TODO: ohci1_irq();
+               }
+
+               hw_flags &= ~IRQF_ALL;
+               if(hw_flags) {
+                       printf("IRQ: unknown 0x%08x\n", hw_flags);
+                       write32(HW_PPCIRQFLAG, hw_flags);
+               }
+               write32(BW_PI_IRQFLAG, 1<<BW_PI_IRQ_HW);
+               u32 flags2 = read32(BW_PI_IRQFLAG);
+               printf("flags2: 0x%08X\n", flags2);
        }
+
+//     flags &= 
+}
+
+void irq_bw_enable(u32 irq)
+{
+       set32(BW_PI_IRQMASK, 1<<irq);
+}
+
+void irq_bw_disable(u32 irq) {
+       clear32(BW_PI_IRQMASK, 1<<irq);
 }
 
-void irq_enable(u32 irq)
+void irq_hw_enable(u32 irq)
 {
        set32(HW_PPCIRQMASK, 1<<irq);
 }
 
-void irq_disable(u32 irq)
+void irq_hw_disable(u32 irq)
 {
        clear32(HW_PPCIRQMASK, 1<<irq);
 }
 
-inline u32 irq_kill() {
+u32 irq_kill() {
        u32 cookie;
        _CPU_ISR_Disable(cookie);
        return cookie;
 }
 
-inline void irq_restore(u32 cookie) {
+void irq_restore(u32 cookie) {
        _CPU_ISR_Restore(cookie);
 }
 
diff --git a/irq.h b/irq.h
index 688af9a9d6d6fdc8835d51bb0783bba509bf3186..9d6a666975fb94b78456b24b7c57e59d828e8a9b 100644 (file)
--- a/irq.h
+++ b/irq.h
 #define BW_PI_IRQFLAG (0x0c003000)
 #define BW_PI_IRQMASK (0x0c003004)
 
+// http://hitmen.c02.at/files/yagcd/yagcd/chap5.html#sec5.4
+#define BW_PI_IRQ_RESET        1
+#define BW_PI_IRQ_DI           2
+#define BW_PI_IRQ_SI           3
+#define BW_PI_IRQ_EXI          4
+#define BW_PI_IRQ_AI           5
+#define BW_PI_IRQ_DSP          6
+#define BW_PI_IRQ_MEM          7
+#define BW_PI_IRQ_VI           8
+#define BW_PI_IRQ_PE_TOKEN     9
+#define BW_PI_IRQ_PE_FINISH    10
+#define BW_PI_IRQ_CP           11
+#define BW_PI_IRQ_DEBUG        12
+#define BW_PI_IRQ_HSP          13
+#define BW_PI_IRQ_HW           14 //hollywood pic
 
 /* stolen from libogc - gc/ogc/machine/processor.h */
 #define _CPU_ISR_Enable() \
@@ -85,8 +100,10 @@ void irq_shutdown(void);
 
 void irq_handler(void);
 
-void irq_enable(u32 irq);
-void irq_disable(u32 irq);
+void irq_bw_enable(u32 irq);
+void irq_bw_disable(u32 irq);
+void irq_hw_enable(u32 irq);
+void irq_hw_disable(u32 irq);
 
 u32 irq_kill(void);
 void irq_restore(u32 cookie);
@@ -99,7 +116,6 @@ static inline void irq_wait(void)
 }
 */
 
-//void irq_set_alarm(u32 ms, u8 enable);
 #endif
 
 #else
diff --git a/main.c b/main.c
index 62116920a79401ed597fd10b3727ec5797da5b1d..51f43269c5302ff585aa05ca887a75c1b8668b91 100644 (file)
--- a/main.c
+++ b/main.c
@@ -85,7 +85,9 @@ int main(void)
        dsp_reset();
 
        irq_initialize();
-       irq_enable(IRQ_OHCI0);
+       irq_bw_enable(BW_PI_IRQ_RESET);
+       irq_bw_enable(BW_PI_IRQ_HW); //hollywood pic
+       irq_hw_enable(IRQ_OHCI0);
        
        ipc_initialize();
        ipc_slowping();
@@ -112,17 +114,17 @@ int main(void)
                        ; // better ideas welcome!
        }
 
+       /*
     print_str_noscroll(112, 112, "ohai, world!\n");
-
        testOTP();
-
        printf("bye, world!\n");
+       */
 
        while(1) {
                // just to get sure we are still in this loop
-               //wtf? _CPU_ISR_Enable() // don't know why this is needed...
-               udelay(100000);
-               printf("x");
+               //_CPU_ISR_Enable() // don't know why this is needed...
+               //udelay(100000);
+               //printf("x");
        }
 
        return 0;