From e256c484ff2f56a6a58547c88b3763e8f2ae2c13 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Tue, 1 Sep 2009 18:36:06 +0200 Subject: [PATCH] WIP: copy irq_handler from mini to ppcskel --- .deps/exception.d | 9 -- .deps/main.d | 30 ------ .gitignore | 1 + Makefile | 4 +- bootmii_ppc.h | 10 ++ exception.c | 22 +--- hollywood.h | 248 ++++++++++++++++++++++++++++++++++++++++++++++ irq.c | 141 ++++++++++++++++++++++++++ irq.h | 72 +++++++++++++- main.c | 16 +-- ohci.c | 11 +- 11 files changed, 481 insertions(+), 83 deletions(-) delete mode 100644 .deps/exception.d delete mode 100644 .deps/main.d create mode 100644 hollywood.h create mode 100644 irq.c diff --git a/.deps/exception.d b/.deps/exception.d deleted file mode 100644 index 10580b9..0000000 --- a/.deps/exception.d +++ /dev/null @@ -1,9 +0,0 @@ -exception.o: exception.c bootmii_ppc.h types.h printf.h string.h - -bootmii_ppc.h: - -types.h: - -printf.h: - -string.h: diff --git a/.deps/main.d b/.deps/main.d deleted file mode 100644 index db1b5bb..0000000 --- a/.deps/main.d +++ /dev/null @@ -1,30 +0,0 @@ -main.o: main.c bootmii_ppc.h types.h printf.h string.h ipc.h mini_ipc.h \ - nandfs.h fat.h ff.h diskio.h malloc.h video_low.h input.h console.h - -bootmii_ppc.h: - -types.h: - -printf.h: - -string.h: - -ipc.h: - -mini_ipc.h: - -nandfs.h: - -fat.h: - -ff.h: - -diskio.h: - -malloc.h: - -video_low.h: - -input.h: - -console.h: diff --git a/.gitignore b/.gitignore index ad0bbdf..daaf8b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ git_version.h *.d +.deps/*.d *.bin *.elf *.map diff --git a/Makefile b/Makefile index 7d89ec9..ef1414a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include broadway.mk -DEFINES = -DLACKS_SYS_TYPES_H -DLACKS_ERRNO_H -DLACKS_STDLIB_H -DLACKS_STRING_H -DLACKS_STRINGS_H -DLACKS_UNISTD_H +DEFINES = -DLACKS_SYS_TYPES_H -DLACKS_ERRNO_H -DLACKS_STDLIB_H -DLACKS_STRING_H -DLACKS_STRINGS_H -DLACKS_UNISTD_H -DCAN_HAZ_IRQ LDSCRIPT = mini.ld LIBS = -lgcc @@ -9,7 +9,7 @@ TARGET = ppcboot.elf OBJS = realmode.o crt0.o main.o string.o sync.o time.o printf.o input.o \ exception.o exception_2200.o malloc.o gecko.o video_low.o \ ipc.o mini_ipc.o nandfs.o ff.o diskio.o fat.o font.o console.o \ - ohci.o + ohci.o irq.o include common.mk diff --git a/bootmii_ppc.h b/bootmii_ppc.h index 49de6b5..b5210f8 100644 --- a/bootmii_ppc.h +++ b/bootmii_ppc.h @@ -45,6 +45,16 @@ static inline void write32(u32 addr, u32 x) asm("stw %0,0(%1) ; eieio" : : "r"(x), "b"(0xc0000000 | addr)); } +static inline void set32(u32 addr, u32 set) +{ + write32(addr, read32(addr) | set); +} + +static inline void clear32(u32 addr, u32 clear) +{ + write32(addr, read32(addr)&(~clear)); +} + static inline void mask32(u32 addr, u32 clear, u32 set) { write32(addr, (read32(addr)&(~clear)) | set); diff --git a/exception.c b/exception.c index 44055f1..f439b14 100644 --- a/exception.c +++ b/exception.c @@ -12,6 +12,7 @@ Copyright (C) 2008 Segher Boessenkool #include "string.h" #include "irq.h" +#include "hollywood.h" extern char exception_2200_start, exception_2200_end; @@ -19,24 +20,9 @@ void exception_handler(int exception) { // check if the exception was actually an interrupt if (exception == 0x500) { - u32 cookie; - - _CPU_ISR_Disable(cookie); - printf("\nInterrupt occured ;-) Which one? -> "); - u32 enabled = read32(BW_PI_IRQMASK); - u32 flags = read32(BW_PI_IRQFLAG); - flags = flags & enabled; - if (flags & (1<<1)) { // RESET - write32(BW_PI_IRQFLAG, 1<<1); - printf("RESET :)\n"); - } - if (flags & (1<<14)) { // Hollywood-PIC IRQ - write32(BW_PI_IRQFLAG, 1<<14); - write32(HW_PPCIRQFLAG, ~0); // dirty - printf("Hollywood-PIC :)\n"); - } - _CPU_ISR_Restore(cookie); - + u32 cookie = irq_kill(); + irq_handler(); + irq_restore(cookie); return; } diff --git a/hollywood.h b/hollywood.h new file mode 100644 index 0000000..3f2dde4 --- /dev/null +++ b/hollywood.h @@ -0,0 +1,248 @@ +/* + mini - a Free Software replacement for the Nintendo/BroadOn IOS. + Hollywood register definitions + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __HOLLYWOOD_H__ +#define __HOLLYWOOD_H__ + +/* Hollywood Registers */ + +#define HW_PPC_REG_BASE 0xd000000 +#define HW_REG_BASE 0xd800000 + +// The PPC can only see the first three IPC registers +#define HW_IPC_PPCMSG (HW_REG_BASE + 0x000) +#define HW_IPC_PPCCTRL (HW_REG_BASE + 0x004) +#define HW_IPC_ARMMSG (HW_REG_BASE + 0x008) +#define HW_IPC_ARMCTRL (HW_REG_BASE + 0x00c) + +#define HW_TIMER (HW_REG_BASE + 0x010) +#define HW_ALARM (HW_REG_BASE + 0x014) + +#define HW_PPCIRQFLAG (HW_REG_BASE + 0x030) +#define HW_PPCIRQMASK (HW_REG_BASE + 0x034) + +#define HW_ARMIRQFLAG (HW_REG_BASE + 0x038) +#define HW_ARMIRQMASK (HW_REG_BASE + 0x03c) + +#define HW_MEMMIRR (HW_REG_BASE + 0x060) + +// something to do with PPCBOOT +// and legacy DI it seems ?!? +#define HW_EXICTRL (HW_REG_BASE + 0x070) +#define EXICTRL_ENABLE_EXI 1 + +// PPC side of GPIO1 (Starlet can access this too) +// Output state +#define HW_GPIO1BOUT (HW_REG_BASE + 0x0c0) +// Direction (1=output) +#define HW_GPIO1BDIR (HW_REG_BASE + 0x0c4) +// Input state +#define HW_GPIO1BIN (HW_REG_BASE + 0x0c8) +// Interrupt level +#define HW_GPIO1BINTLVL (HW_REG_BASE + 0x0cc) +// Interrupt flags (write 1 to clear) +#define HW_GPIO1BINTFLAG (HW_REG_BASE + 0x0d0) +// Interrupt propagation enable +// Do these interrupts go anywhere??? +#define HW_GPIO1BINTENABLE (HW_REG_BASE + 0x0d4) +//??? seems to be a mirror of inputs at some point... power-up state? +#define HW_GPIO1BINMIR (HW_REG_BASE + 0x0d8) +// 0xFFFFFF by default, if cleared disables respective outputs. Top bits non-settable. +#define HW_GPIO1ENABLE (HW_REG_BASE + 0x0dc) + +#define HW_GPIO1_SLOT 0x000020 +#define HW_GPIO1_DEBUG 0xFF0000 +#define HW_GPIO1_DEBUG_SH 16 + +// Starlet side of GPIO1 +// Output state +#define HW_GPIO1OUT (HW_REG_BASE + 0x0e0) +// Direction (1=output) +#define HW_GPIO1DIR (HW_REG_BASE + 0x0e4) +// Input state +#define HW_GPIO1IN (HW_REG_BASE + 0x0e8) +// Interrupt level +#define HW_GPIO1INTLVL (HW_REG_BASE + 0x0ec) +// Interrupt flags (write 1 to clear) +#define HW_GPIO1INTFLAG (HW_REG_BASE + 0x0f0) +// Interrupt propagation enable (interrupts go to main interrupt 0x800) +#define HW_GPIO1INTENABLE (HW_REG_BASE + 0x0f4) +//??? seems to be a mirror of inputs at some point... power-up state? +#define HW_GPIO1INMIR (HW_REG_BASE + 0x0f8) +// Owner of each GPIO bit. If 1, GPIO1B registers assume control. If 0, GPIO1 registers assume control. +#define HW_GPIO1OWNER (HW_REG_BASE + 0x0fc) + +// ???? +#define HW_DIFLAGS (HW_REG_BASE + 0x180) +#define DIFLAGS_BOOT_CODE 0x100000 + +// maybe a GPIO??? +#define HW_RESETS (HW_REG_BASE + 0x194) + +#define HW_CLOCKS (HW_REG_BASE + 0x1b4) + +#define HW_GPIO2OUT (HW_REG_BASE + 0x1c8) +#define HW_GPIO2DIR (HW_REG_BASE + 0x1cc) +#define HW_GPIO2IN (HW_REG_BASE + 0x1d0) + +#define HW_OTPCMD (HW_REG_BASE + 0x1ec) +#define HW_OTPDATA (HW_REG_BASE + 0x1f0) +#define HW_VERSION (HW_REG_BASE + 0x214) + +/* NAND Registers */ + +#define NAND_REG_BASE 0xd010000 + +#define NAND_CMD (NAND_REG_BASE + 0x000) +#define NAND_STATUS NAND_CMD +#define NAND_CONF (NAND_REG_BASE + 0x004) +#define NAND_ADDR0 (NAND_REG_BASE + 0x008) +#define NAND_ADDR1 (NAND_REG_BASE + 0x00c) +#define NAND_DATA (NAND_REG_BASE + 0x010) +#define NAND_ECC (NAND_REG_BASE + 0x014) +#define NAND_UNK1 (NAND_REG_BASE + 0x018) +#define NAND_UNK2 (NAND_REG_BASE + 0x01c) + +/* AES Registers */ + +#define AES_REG_BASE 0xd020000 + +#define AES_CMD (AES_REG_BASE + 0x000) +#define AES_SRC (AES_REG_BASE + 0x004) +#define AES_DEST (AES_REG_BASE + 0x008) +#define AES_KEY (AES_REG_BASE + 0x00c) +#define AES_IV (AES_REG_BASE + 0x010) + +/* SHA-1 Registers */ + +#define SHA_REG_BASE 0xd030000 + +#define SHA_CMD (SHA_REG_BASE + 0x000) +#define SHA_SRC (SHA_REG_BASE + 0x004) +#define SHA_H0 (SHA_REG_BASE + 0x008) +#define SHA_H1 (SHA_REG_BASE + 0x00c) +#define SHA_H2 (SHA_REG_BASE + 0x010) +#define SHA_H3 (SHA_REG_BASE + 0x014) +#define SHA_H4 (SHA_REG_BASE + 0x018) + +/* SD Host Controller Registers */ + +#define SDHC_REG_BASE 0xd070000 + +/* OHCI0 Registers */ + +#define OHCI0_REG_BASE 0xd050000 + +#define OHCI0_HC_REVISION (OHCI0_REG_BASE + 0x00) +#define OHCI0_HC_CONTROL (OHCI0_REG_BASE + 0x04) +#define OHCI0_HC_COMMAND_STATUS (OHCI0_REG_BASE + 0x08) +#define OHCI0_HC_INT_STATUS (OHCI0_REG_BASE + 0x0C) + +#define OHCI0_HC_INT_ENABLE (OHCI0_REG_BASE + 0x10) +#define OHCI0_HC_INT_DISABLE (OHCI0_REG_BASE + 0x14) +#define OHCI0_HC_HCCA (OHCI0_REG_BASE + 0x18) +#define OHCI0_HC_PERIOD_CURRENT_ED (OHCI0_REG_BASE + 0x1C) + +#define OHCI0_HC_CTRL_HEAD_ED (OHCI0_REG_BASE + 0x20) +#define OHCI0_HC_CTRL_CURRENT_ED (OHCI0_REG_BASE + 0x24) +#define OHCI0_HC_BULK_HEAD_ED (OHCI0_REG_BASE + 0x28) +#define OHCI0_HC_BULK_CURRENT_ED (OHCI0_REG_BASE + 0x2C) + +#define OHCI0_HC_DONE_HEAD (OHCI0_REG_BASE + 0x30) +#define OHCI0_HC_FM_INTERVAL (OHCI0_REG_BASE + 0x34) +#define OHCI0_HC_FM_REMAINING (OHCI0_REG_BASE + 0x38) +#define OHCI0_HC_FM_NUMBER (OHCI0_REG_BASE + 0x3C) + +#define OHCI0_HC_PERIODIC_START (OHCI0_REG_BASE + 0x40) +#define OHCI0_HC_LS_THRESHOLD (OHCI0_REG_BASE + 0x44) +#define OHCI0_HC_RH_DESCRIPTOR_A (OHCI0_REG_BASE + 0x48) +#define OHCI0_HC_RH_DESCRIPTOR_B (OHCI0_REG_BASE + 0x4C) + +#define OHCI0_HC_RH_STATUS (OHCI0_REG_BASE + 0x50) + +/* OHCI1 Registers */ + +#define OHCI1_REG_BASE 0xd060000 + +#define OHCI1_HC_REVISION (OHCI1_REG_BASE + 0x00) +#define OHCI1_HC_CONTROL (OHCI1_REG_BASE + 0x04) +#define OHCI1_HC_COMMAND_STATUS (OHCI1_REG_BASE + 0x08) +#define OHCI1_HC_INT_STATUS (OHCI1_REG_BASE + 0x0C) + +#define OHCI1_HC_INT_ENABLE (OHCI1_REG_BASE + 0x10) +#define OHCI1_HC_INT_DISABLE (OHCI1_REG_BASE + 0x14) +#define OHCI1_HC_HCCA (OHCI1_REG_BASE + 0x18) +#define OHCI1_HC_PERIOD_CURRENT_ED (OHCI1_REG_BASE + 0x1C) + +#define OHCI1_HC_CTRL_HEAD_ED (OHCI1_REG_BASE + 0x20) +#define OHCI1_HC_CTRL_CURRENT_ED (OHCI1_REG_BASE + 0x24) +#define OHCI1_HC_BULK_HEAD_ED (OHCI1_REG_BASE + 0x28) +#define OHCI1_HC_BULK_CURRENT_ED (OHCI1_REG_BASE + 0x2C) + +#define OHCI1_HC_DONE_HEAD (OHCI1_REG_BASE + 0x30) +#define OHCI1_HC_FM_INTERVAL (OHCI1_REG_BASE + 0x34) +#define OHCI1_HC_FM_REMAINING (OHCI1_REG_BASE + 0x38) +#define OHCI1_HC_FM_NUMBER (OHCI1_REG_BASE + 0x3C) + +#define OHCI1_HC_PERIODIC_START (OHCI1_REG_BASE + 0x40) +#define OHCI1_HC_LS_THRESHOLD (OHCI1_REG_BASE + 0x44) +#define OHCI1_HC_RH_DESCRIPTOR_A (OHCI1_REG_BASE + 0x48) +#define OHCI1_HC_RH_DESCRIPTOR_B (OHCI1_REG_BASE + 0x4C) + +#define OHCI1_HC_RH_STATUS (OHCI1_REG_BASE + 0x50) + +/* EHCI Registers */ +#define EHCI_REG_BASE 0xd040000 + +/* stolen from mikep2 patched linux kernel: drivers/usb/host/ohci-mipc.c */ +#define EHCI_CTL (EHCI_REG_BASE + 0xCC) +#define EHCI_CTL_OH0INTE (1<<11) /* oh0 interrupt enable */ +#define EHCI_CTL_OH1INTE (1<<12) /* oh1 interrupt enable */ + +/* EXI Registers */ + +#define EXI_REG_BASE 0xd806800 +#define EXI0_REG_BASE (EXI_REG_BASE+0x000) +#define EXI1_REG_BASE (EXI_REG_BASE+0x014) +#define EXI2_REG_BASE (EXI_REG_BASE+0x028) + +#define EXI0_CSR (EXI0_REG_BASE+0x000) +#define EXI0_MAR (EXI0_REG_BASE+0x004) +#define EXI0_LENGTH (EXI0_REG_BASE+0x008) +#define EXI0_CR (EXI0_REG_BASE+0x00c) +#define EXI0_DATA (EXI0_REG_BASE+0x010) + +#define EXI1_CSR (EXI1_REG_BASE+0x000) +#define EXI1_MAR (EXI1_REG_BASE+0x004) +#define EXI1_LENGTH (EXI1_REG_BASE+0x008) +#define EXI1_CR (EXI1_REG_BASE+0x00c) +#define EXI1_DATA (EXI1_REG_BASE+0x010) + +#define EXI2_CSR (EXI2_REG_BASE+0x000) +#define EXI2_MAR (EXI2_REG_BASE+0x004) +#define EXI2_LENGTH (EXI2_REG_BASE+0x008) +#define EXI2_CR (EXI2_REG_BASE+0x00c) +#define EXI2_DATA (EXI2_REG_BASE+0x010) + +#define EXI_BOOT_BASE (EXI_REG_BASE+0x040) + +/* MEMORY CONTROLLER Registers */ + +#define MEM_REG_BASE 0xd8b4000 +#define MEM_PROT (MEM_REG_BASE+0x20a) +#define MEM_PROT_START (MEM_REG_BASE+0x20c) +#define MEM_PROT_END (MEM_REG_BASE+0x20e) +#define MEM_FLUSHREQ (MEM_REG_BASE+0x228) +#define MEM_FLUSHACK (MEM_REG_BASE+0x22a) + +#endif diff --git a/irq.c b/irq.c new file mode 100644 index 0000000..9ab1559 --- /dev/null +++ b/irq.c @@ -0,0 +1,141 @@ +/* + ppcskel - a Free Software replacement for the Nintendo/BroadOn IOS. + IRQ support + +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "irq.h" +#include "hollywood.h" +#include "ipc.h" +#include "bootmii_ppc.h" +//debug only +#include "printf.h" + +void irq_initialize(void) +{ + // enable OHCI0 interrupt on hollywood-pic + write32(HW_PPCIRQMASK, 0); + write32(HW_PPCIRQFLAG, 0xffffffff); + + // enable RESET and PIC (#14) interrupts on processor interface + write32(BW_PI_IRQFLAG, 0xffffffff); +#define BW_PI_IRQ_RESET 1 +#define BW_PI_IRQ_HW 14 + write32(BW_PI_IRQMASK, (1< #include "irq.h" #define gecko_printf printf -#define set32(address, flags) write32(address, read32(address) | flags) #define dma_addr(address) (u32)address @@ -70,10 +69,7 @@ void ohci_init() { within 2msec else HC enters RESUME */ - //u32 cookie = irq_kill(); - u32 cookie; - _CPU_ISR_Disable(cookie); - + u32 cookie = irq_kill(); /* Tell the controller where the control and bulk lists are * The lists are empty now. */ @@ -107,11 +103,8 @@ void ohci_init() { write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_INIT); - //irq_restore(cookie); - _CPU_ISR_Restore(cookie); - + irq_restore(cookie); dbg_op_state(); - } -- 2.25.1