From f0c291eef75de102cee627c1c684ed6b9874f296 Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Thu, 24 Apr 2003 03:31:38 +0000 Subject: [PATCH] IRQ stuff. --- src/arch/ppc/include/arch/pirq_routing.h | 54 +++++++++++ src/arch/ppc/lib/pirq_routing.c | 94 +++++++++++++++++++ src/mainboard/motorola/sandpoint/irq_tables.c | 26 +++++ src/southbridge/winbond/w83c553/w83c553f.c | 22 ++--- 4 files changed, 183 insertions(+), 13 deletions(-) create mode 100644 src/arch/ppc/include/arch/pirq_routing.h create mode 100644 src/arch/ppc/lib/pirq_routing.c create mode 100644 src/mainboard/motorola/sandpoint/irq_tables.c diff --git a/src/arch/ppc/include/arch/pirq_routing.h b/src/arch/ppc/include/arch/pirq_routing.h new file mode 100644 index 0000000000..dad8531eb5 --- /dev/null +++ b/src/arch/ppc/include/arch/pirq_routing.h @@ -0,0 +1,54 @@ +#ifndef ARCH_PIRQ_ROUTING_H +#define ARCH_PIRQ_ROUTING_H + +#include + +#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) +#define PIRQ_VERSION 0x0100 + +struct irq_info { + u8 bus, devfn; /* Bus, device and function */ + struct { + u8 link; /* IRQ line ID, chipset dependent, 0=not routed */ + u16 bitmap; /* Available IRQs */ + } __attribute__((packed)) irq[4]; + u8 slot; /* Slot number, 0=onboard */ + u8 rfu; +} __attribute__((packed)); + +#if defined(IRQ_SLOT_COUNT) +#define IRQ_SLOTS_COUNT IRQ_SLOT_COUNT +#elif (__GNUC__ < 3) +#define IRQ_SLOTS_COUNT 1 +#else +#define IRQ_SLOTS_COUNT +#endif + +struct irq_routing_table { + u32 signature; /* PIRQ_SIGNATURE should be here */ + u16 version; /* PIRQ_VERSION */ + u16 size; /* Table size in bytes */ + u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */ + u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ + u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */ + u32 miniport_data; /* Crap */ + u8 rfu[11]; + u8 checksum; /* Modulo 256 checksum must give zero */ + struct irq_info slots[IRQ_SLOTS_COUNT]; +} __attribute__((packed)); + +extern const struct irq_routing_table intel_irq_routing_table; + +#if defined(DEBUG) && defined(HAVE_PIRQ_TABLE) +void check_pirq_routing_table(void); +#else +#define check_pirq_routing_table() do {} while(0) +#endif + +#if defined(HAVE_PIRQ_TABLE) +unsigned long copy_pirq_routing_table(unsigned long start); +#else +#define copy_pirq_routing_table(start) (start) +#endif + +#endif /* ARCH_PIRQ_ROUTING_H */ diff --git a/src/arch/ppc/lib/pirq_routing.c b/src/arch/ppc/lib/pirq_routing.c new file mode 100644 index 0000000000..dd0e360c0d --- /dev/null +++ b/src/arch/ppc/lib/pirq_routing.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +#ifdef DEBUG +void check_pirq_routing_table(void) +{ + const u8 *addr; + const struct irq_routing_table *rt; + int i; + u8 sum; + + printk_info("Checking IRQ routing tables...\n"); + +#ifdef(IRQ_SLOT_COUNT) + if (sizeof(intel_irq_routing_table) != intel_irq_routing_table.size) { + printk_warning("Inconsistent IRQ routing table size\n"); + } +#endif + + rt = &intel_irq_routing_table; + addr = (u8 *)rt; + + sum = 0; + for (i = 0; i < rt->size; i++) + sum += addr[i]; + + printk_debug("%s:%6d:%s() - irq_routing_table located at: 0x%p\n", + __FILE__, __LINE__, __FUNCTION__, addr); + + sum = (unsigned char)(rt->checksum-sum); + + if (sum != rt->checksum) { + printk_warning("%s:%6d:%s() - " + "checksum is: 0x%02x but should be: 0x%02x\n", + __FILE__, __LINE__, __FUNCTION__, rt->checksum, sum); + } + + if (rt->signature != PIRQ_SIGNATURE || rt->version != PIRQ_VERSION || + rt->size % 16 || rt->size < sizeof(struct irq_routing_table)) { + printk_warning("%s:%6d:%s() - " + "Interrupt Routing Table not valid\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + sum = 0; + for (i=0; isize; i++) + sum += addr[i]; + + if (sum) { + printk_warning("%s:%6d:%s() - " + "checksum error in irq routing table\n", + __FILE__, __LINE__, __FUNCTION__); + } + + printk_info("done.\n"); +} + +int verify_copy_pirq_routing_table(unsigned long addr) +{ + int i; + u8 *rt_orig, *rt_curr; + + rt_curr = (u8*)addr; + rt_orig = (u8*)&intel_irq_routing_table; + printk_info("Verifing priq routing tables copy at 0x%x...", addr); + for (i = 0; i < intel_irq_routing_table.size; i++) { + if (*(rt_curr + i) != *(rt_orig + i)) { + printk_info("failed\n"); + return -1; + } + } + printk_info("succeed\n"); + return 0; +} +#else +#define verify_copy_pirq_routing_table(addr) +#endif + +unsigned long copy_pirq_routing_table(unsigned long addr) +{ + /* Align the table to be 16 byte aligned. */ + addr += 15; + addr &= ~15; + + /* This table must be betweeen 0xf0000 & 0x100000 */ + printk_info("Copying IRQ routing tables to 0x%x...", addr); + memcpy((void *)addr, &intel_irq_routing_table, intel_irq_routing_table.size); + printk_info("done.\n"); + verify_copy_pirq_routing_table(addr); + return addr + intel_irq_routing_table.size; +} diff --git a/src/mainboard/motorola/sandpoint/irq_tables.c b/src/mainboard/motorola/sandpoint/irq_tables.c new file mode 100644 index 0000000000..a8a961439c --- /dev/null +++ b/src/mainboard/motorola/sandpoint/irq_tables.c @@ -0,0 +1,26 @@ +#include + +const struct irq_routing_table ppc_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32+16*9, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x1057, /* u16 Vendor - Motorola */ + 0x0004, /* Device ID - MPC107 */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + IRQ_CHECKSUM, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x10, {{0x62, 0xdeb8}, {0x62, 0xdeb8}, {0x62, 0xdeb8}, {0x62, 0xdeb8}}, 0x00, 0x00}, + {0x04, 0x40, {{0x68, 0xdeb8}, {0x69, 0xdeb8}, {0x6a, 0xdeb8}, {0x6b, 0xdeb8}}, 0x01, 0x00}, + {0x04, 0x38, {{0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}}, 0x02, 0x00}, + {0x04, 0x08, {{0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}, {0x60, 0xdeb8}}, 0x03, 0x00}, + {0x04, 0x10, {{0x62, 0xdeb8}, {0x63, 0xdeb8}, {0x60, 0xdeb8}, {0x61, 0xdeb8}}, 0x04, 0x00}, + {0x04, 0x18, {{0x63, 0xdeb8}, {0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}}, 0x05, 0x00}, + {0x04, 0x20, {{0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}}, 0x06, 0x00}, + {0x03, 0x20, {{0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}}, 0x07, 0x00}, + {0x00, 0xf8, {{0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x6b, 0xdeb8}, {0x63, 0xdeb8}}, 0x08, 0x00} + } +}; diff --git a/src/southbridge/winbond/w83c553/w83c553f.c b/src/southbridge/winbond/w83c553/w83c553f.c index 66e5b924c8..1c00578ab1 100644 --- a/src/southbridge/winbond/w83c553/w83c553f.c +++ b/src/southbridge/winbond/w83c553/w83c553f.c @@ -56,10 +56,7 @@ extern struct pci_ops pci_direct_ppc; void southbridge_early_init(void) { - struct pci_dev *devbusfn; unsigned char reg8; - unsigned short reg16; - unsigned int reg32; /* * Set ISA memory space @@ -68,7 +65,7 @@ void southbridge_early_init(void) /* 16 MB ISA memory space */ reg8 |= (IPADCR_IPATOM4 | IPADCR_IPATOM5 | IPADCR_IPATOM6 | IPADCR_IPATOM7); reg8 &= ~IPADCR_MBE512; - pci_direct_ppc.read_byte(0, 0x58, WINBOND_IPADCR, reg8); + pci_direct_ppc.write_byte(0, 0x58, WINBOND_IPADCR, ®8); } void southbridge_init(void) @@ -113,14 +110,14 @@ void southbridge_init(void) /* * Interrupt routing: - * - IDE -> INTC/INTD - * - INTA -> IRQ 5 - * - INTB -> IRQ 6 - * - INTC -> IRQ 7 - * - INTD -> IRQ 8 + * - IDE -> 9/0 + * - INTA -> IRQ 10 + * - INTB -> IRQ 11 + * - INTC -> IRQ 14 + * - INTD -> IRQ 15 */ - pci_write_config_byte(devbusfn, WINBOND_IDEIRCR, 0x0); - pci_write_config_word(devbusfn, WINBOND_PCIIRCR, 0x5678); + pci_write_config_byte(devbusfn, WINBOND_IDEIRCR, 0x90); + pci_write_config_word(devbusfn, WINBOND_PCIIRCR, 0xABEF); /* * Read IDE bus offsets from function 1 device. @@ -144,8 +141,7 @@ void southbridge_init(void) * Secondary port Mode 0 ~P1F16 */ pci_read_config_dword(devbusfn, WINDOND_IDECSR, ®32); - reg32 |= IDECSR_LEGIRQ; - reg32 &= ~(IDECSR_P1EN | IDECSR_P1F16); + reg32 &= ~(IDECSR_LEGIRQ | IDECSR_P1EN | IDECSR_P1F16); pci_write_config_dword(devbusfn, WINDOND_IDECSR, reg32); pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &ide_bus_offset[0]);