Date: Sat, 1 Sep 2007 16:19:48 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 125948 for review Message-ID: <200709011619.l81GJmBn040252@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125948 Change 125948 by gonzo@gonzo_jeeves on 2007/09/01 16:19:29 o Add LBA registers programming o Add resource handling for PCI bus in idtpci.c o Add PCI interrupt routing o Some rudimentary interrupts managing stuff. Affected files ... .. //depot/projects/mips2/src/sys/mips/mips32/idt/idtpci.c#2 edit .. //depot/projects/mips2/src/sys/mips/mips32/idt/idtreg.h#2 edit .. //depot/projects/mips2/src/sys/mips/mips32/idt/obio.c#2 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/mips32/idt/idtpci.c#2 (text+ko) ==== @@ -135,7 +135,7 @@ { int busno = 0; struct idtpci_softc *sc = device_get_softc(dev); - unsigned int pci_data; + unsigned int pci_data, force_endianess = 0; sc->sc_dev = dev; sc->sc_busno = busno; @@ -144,6 +144,7 @@ sc->sc_mem = 0; /* TODO: Check for host mode */ + /* Enabled PCI, IG mode, EAP mode */ REG_WRITE(IDT_PCI_CNTL, IDT_PCI_CNTL_IGM | IDT_PCI_CNTL_EAP | IDT_PCI_CNTL_EN); @@ -168,41 +169,75 @@ /* Init PCI messaging unit */ /* Disable messaging interrupts */ REG_WRITE(IDT_PCI_IIC, 0); - REG_WRITE(IDT_PCI_IIM, 0); + REG_WRITE(IDT_PCI_IIM, 0xffffffff); REG_WRITE(IDT_PCI_OIC, 0); REG_WRITE(IDT_PCI_OIM, 0); - /* TODO: handle lba stuff */ +#ifdef __MIPSEB__ + force_endianess = IDT_PCI_LBA_FE; +#endif + + /* LBA0 -- memory window */ + REG_WRITE(IDT_PCI_LBA0, IDT_PCIMEM0_BASE); + REG_WRITE(IDT_PCI_LBA0_MAP, IDT_PCIMEM0_BASE); + REG_WRITE(IDT_PCI_LBA0_CNTL, IDT_PCI_LBA_SIZE_16MB | force_endianess); + pci_data = REG_READ(IDT_PCI_LBA0_CNTL); + + /* LBA1 -- memory window */ + REG_WRITE(IDT_PCI_LBA1, IDT_PCIMEM1_BASE); + REG_WRITE(IDT_PCI_LBA1_MAP, IDT_PCIMEM1_BASE); + REG_WRITE(IDT_PCI_LBA1_CNTL, IDT_PCI_LBA_SIZE_256MB | force_endianess); + pci_data = REG_READ(IDT_PCI_LBA1_CNTL); + + /* LBA2 -- IO window */ + REG_WRITE(IDT_PCI_LBA2, IDT_PCIMEM2_BASE); + REG_WRITE(IDT_PCI_LBA2_MAP, IDT_PCIMEM2_BASE); + REG_WRITE(IDT_PCI_LBA2_CNTL, IDT_PCI_LBA_SIZE_4MB | IDT_PCI_LBA_MSI | + force_endianess); + pci_data = REG_READ(IDT_PCI_LBA2_CNTL); + + /* LBA3 -- IO window */ + REG_WRITE(IDT_PCI_LBA3, IDT_PCIMEM3_BASE); + REG_WRITE(IDT_PCI_LBA3_MAP, IDT_PCIMEM3_BASE); + REG_WRITE(IDT_PCI_LBA3_CNTL, IDT_PCI_LBA_SIZE_1MB | IDT_PCI_LBA_MSI | + force_endianess); + pci_data = REG_READ(IDT_PCI_LBA3_CNTL); + + + pci_data = REG_READ(IDT_PCI_CNTL) & ~IDT_PCI_CNTL_TNR; + REG_WRITE(IDT_PCI_CNTL, pci_data); + pci_data = REG_READ(IDT_PCI_CNTL); /* Rewrite Target Control register with default values */ REG_WRITE(IDT_PCI_TC, (IDT_PCI_TC_DTIMER << 8) | IDT_PCI_TC_RTIMER); -#if 0 /* Use KSEG1 to access IO ports for it is uncached */ - sc->sc_io = MIPS_PHYS_TO_KSEG1(ADM5120_BASE_PCI_IO); + sc->sc_io = 0; sc->sc_io_rman.rm_type = RMAN_ARRAY; sc->sc_io_rman.rm_descr = "IDTPCI I/O Ports"; if (rman_init(&sc->sc_io_rman) != 0 || - rman_manage_region(&sc->sc_io_rman, 0, 0xffff) != 0) { + rman_manage_region(&sc->sc_io_rman, + MIPS_PHYS_TO_KSEG1(IDT_PCIMEM3_BASE), + MIPS_PHYS_TO_KSEG1(IDT_PCIMEM3_BASE + IDT_PCIMEM3_SIZE - 1)) != 0) { panic("idtpci_attach: failed to set up I/O rman"); } /* Use KSEG1 to access PCI memory for it is uncached */ - sc->sc_mem = MIPS_PHYS_TO_KSEG1(ADM5120_BASE_PCI_MEM); + sc->sc_mem = MIPS_PHYS_TO_KSEG1(IDT_PCIMEM1_BASE); sc->sc_mem_rman.rm_type = RMAN_ARRAY; sc->sc_mem_rman.rm_descr = "IDTPCI PCI Memory"; if (rman_init(&sc->sc_mem_rman) != 0 || rman_manage_region(&sc->sc_mem_rman, - sc->sc_mem, sc->sc_mem + 0x100000) != 0) { + sc->sc_mem, sc->sc_mem + IDT_PCIMEM1_SIZE) != 0) { panic("idtpci_attach: failed to set up memory rman"); } sc->sc_irq_rman.rm_type = RMAN_ARRAY; sc->sc_irq_rman.rm_descr = "IDTPCI PCI IRQs"; if (rman_init(&sc->sc_irq_rman) != 0 || - rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0) + rman_manage_region(&sc->sc_irq_rman, PCI_IRQ_BASE, + PCI_IRQ_END) != 0) panic("idtpci_attach: failed to set up IRQ rman"); -#endif device_add_child(dev, "pci", busno); return (bus_generic_attach(dev)); @@ -230,8 +265,8 @@ uint32_t shift, mask; bus_addr_t addr; - IDTPCI_DPRINTF("%s: sc %p tag (%x, %x, %x) reg %d\n", __func__, - (void *)sc, bus, slot, func, reg); + IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, + bus, slot, func, reg, bytes); addr = idtpci_make_addr(bus, slot, func, reg); @@ -286,8 +321,8 @@ uint32_t reg_data; uint32_t shift, mask; - IDTPCI_DPRINTF("%s: sc %p tag (%x, %x, %x) reg %d\n", __func__, - (void *)sc, bus, slot, func, reg); + IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d) data %08x\n", __func__, + bus, slot, func, reg, bytes, data); if (bytes != 4) { reg_data = idtpci_read_config(dev, bus, slot, func, reg, 4); @@ -331,16 +366,42 @@ addr = idtpci_make_addr(bus, slot, func, reg); + REG_WRITE(IDT_PCI_CFG_ADDR, addr); + REG_WRITE(IDT_PCI_CFG_DATA, data); + __asm__ volatile ("sync"); + REG_WRITE(IDT_PCI_CFG_ADDR, 0); REG_WRITE(IDT_PCI_CFG_DATA, 0); - __asm__ volatile ("sync"); } static int -idtpci_route_interrupt(device_t pcib, device_t dev, int pin) +idtpci_route_interrupt(device_t pcib, device_t device, int pin) { - /* TODO: implement */ - return (0); + static int idt_pci_table[2][12] = + { + { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 } + }; + int dev, bus, irq; + + dev = pci_get_slot(device); + bus = pci_get_bus(device); + if (bootverbose) + device_printf(pcib, "routing pin %d for %s\n", pin, + device_get_nameunit(device)); + if (bus >= 0 && bus <= 1 && + dev >= 0 && dev <= 11) { + irq = IP_IRQ(6, idt_pci_table[bus][dev] + 4); + if (bootverbose) + printf("idtpci: %d/%d/%d -> IRQ%d\n", + pci_get_bus(device), dev, pci_get_function(device), + irq); + return (irq); + } else + printf("idtpci: no mapping for %d/%d/%d\n", + pci_get_bus(device), dev, pci_get_function(device)); + + return (-1); } static int @@ -375,8 +436,6 @@ u_long start, u_long end, u_long count, u_int flags) { - return (NULL); -#if 0 struct idtpci_softc *sc = device_get_softc(bus); struct resource *rv = NULL; struct rman *rm; @@ -415,7 +474,6 @@ } } return (rv); -#endif } static int @@ -496,7 +554,7 @@ DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_activate_resource, idtpci_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, idtpci_setup_intr), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, idtpci_teardown_intr), /* pcib interface */ ==== //depot/projects/mips2/src/sys/mips/mips32/idt/idtreg.h#2 (text+ko) ==== @@ -33,7 +33,7 @@ #define ICU_IPEND2 0x00 #define ICU_ITEST2 0x04 #define ICU_IMASK2 0x08 -#define ICU_IPEND3 0x0c +#define ICU_IPEND3 0x0C #define ICU_ITEST3 0x10 #define ICU_IMASK3 0x14 #define ICU_IPEND4 0x18 @@ -60,8 +60,33 @@ #define IDT_PCI_STATUS 0x04 #define IDT_PCI_STATUS_RIP 0x20000 #define IDT_PCI_STATUS_MASK 0x08 -#define IDT_PCI_CFG_ADDR 0x0c +#define IDT_PCI_CFG_ADDR 0x0C #define IDT_PCI_CFG_DATA 0x10 +/* LBA stuff */ +#define IDT_PCI_LBA0 0x14 +#define IDT_PCI_LBA0_CNTL 0x18 +#define IDT_PCI_LBA_MSI 0x01 +#define IDT_PCI_LBA_SIZE_1MB 0x14 +#define IDT_PCI_LBA_SIZE_2MB 0x15 +#define IDT_PCI_LBA_SIZE_4MB 0x16 +#define IDT_PCI_LBA_SIZE_8MB 0x17 +#define IDT_PCI_LBA_SIZE_16MB 0x18 +#define IDT_PCI_LBA_SIZE_32MB 0x19 +#define IDT_PCI_LBA_SIZE_64MB 0x1A +#define IDT_PCI_LBA_SIZE_128MB 0x1B +#define IDT_PCI_LBA_SIZE_256MB 0x1C +#define IDT_PCI_LBA_FE 0x80 +#define IDT_PCI_LBA_RT 0x100 +#define IDT_PCI_LBA0_MAP 0x1C +#define IDT_PCI_LBA1 0x20 +#define IDT_PCI_LBA1_CNTL 0x24 +#define IDT_PCI_LBA1_MAP 0x28 +#define IDT_PCI_LBA2 0x2C +#define IDT_PCI_LBA2_CNTL 0x30 +#define IDT_PCI_LBA2_MAP 0x34 +#define IDT_PCI_LBA3 0x38 +#define IDT_PCI_LBA3_CNTL 0x3C +#define IDT_PCI_LBA3_MAP 0x40 /* decoupled registers */ #define IDT_PCI_DAC 0x44 #define IDT_PCI_DAS 0x48 @@ -76,5 +101,28 @@ #define IDT_PCI_OIC 0x8030 #define IDT_PCI_OIM 0x8034 +/* PCI-related stuff */ +#define IDT_PCIMEM0_BASE 0x50000000 +#define IDT_PCIMEM0_SIZE 0x01000000 + +#define IDT_PCIMEM1_BASE 0x60000000 +#define IDT_PCIMEM1_SIZE 0x10000000 + +#define IDT_PCIMEM2_BASE 0x18C00000 +#define IDT_PCIMEM2_SIZE 0x00400000 + +#define IDT_PCIMEM3_BASE 0x18800000 +#define IDT_PCIMEM3_SIZE 0x00100000 + +/* Interrupts-related stuff */ +#define IRQ_BASE 8 +/* Convert <IPbit, irq_offset> pair to IRQ number */ +#define IP_IRQ(IPbit, offset) ((IPbit - 2) * 32 + (offset) + IRQ_BASE) +/* The last one available IRQ */ +#define IRQ_END IP_IRQ(6, 31) + +#define PCI_IRQ_BASE IP_IRQ(6, 4) +#define PCI_IRQ_END IP_IRQ(6, 7) + #endif /* __IDTREG_H__ */ ==== //depot/projects/mips2/src/sys/mips/mips32/idt/obio.c#2 (text+ko) ==== @@ -95,7 +95,7 @@ sc->oba_irq_rman.rm_descr = "OBIO IRQ"; if (rman_init(&sc->oba_irq_rman) != 0 || - rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0) + rman_manage_region(&sc->oba_irq_rman, IRQ_BASE, IRQ_END) != 0) panic("obio_attach: failed to set up IRQ rman"); /* Hook up our interrupt handlers. We should handle IRQ0..IRQ4*/ @@ -115,10 +115,10 @@ } /* disable all interrupts, IMASK4 is reserved, do not tuch it */ - REG_WRITE(ICU_IMASK2, 0xffffff); - REG_WRITE(ICU_IMASK3, 0xffffff); - REG_WRITE(ICU_IMASK5, 0xffffff); - REG_WRITE(ICU_IMASK6, 0xffffff); + REG_WRITE(ICU_IMASK2, 0xffffffff); + REG_WRITE(ICU_IMASK3, 0xffffffff); + REG_WRITE(ICU_IMASK5, 0xffffffff); + REG_WRITE(ICU_IMASK6, 0xffffffff); bus_generic_probe(dev); bus_enumerate_hinted_children(dev); @@ -281,7 +281,6 @@ { struct obio_softc *sc = device_get_softc(dev); int irq, result; - uint32_t irqmask; irq = rman_get_start(ires); if (irq >= NIRQS)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709011619.l81GJmBn040252>