PERFORCE change 125948 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Sat Sep 1 09:19:49 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125948
Change 125948 by gonzo at 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)
More information about the p4-projects
mailing list