Index: sys/arch/hp700/dev/dino.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/dev/dino.c,v retrieving revision 1.8 diff -u -p -u -r1.8 dino.c --- sys/arch/hp700/dev/dino.c 30 Apr 2009 07:01:26 -0000 1.8 +++ sys/arch/hp700/dev/dino.c 6 May 2009 13:40:21 -0000 @@ -114,7 +114,6 @@ struct dino_softc { struct hp700_int_reg sc_int_reg; bus_space_tag_t sc_bt; bus_space_handle_t sc_bh; - bus_space_handle_t sc_memh; bus_dma_tag_t sc_dmat; volatile struct dino_regs *sc_regs; @@ -146,8 +145,9 @@ void dino_conf_write(void *, pcitag_t, i int dino_intr_map(struct pci_attach_args *, pci_intr_handle_t *); const char *dino_intr_string(void *, pci_intr_handle_t); void *dino_intr_establish(void *, pci_intr_handle_t, int, - int (*handler)(void *), void *); + int (*)(void *), void *); void dino_intr_disestablish(void *, void *); + void *dino_alloc_parent(struct device *, struct pci_attach_args *, int); int dino_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); int dino_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); @@ -159,8 +159,11 @@ int dino_memalloc(void *, bus_addr_t, bu bus_size_t, int, bus_addr_t *, bus_space_handle_t *); void dino_unmap(void *, bus_space_handle_t, bus_size_t); void dino_free(void *, bus_space_handle_t, bus_size_t); + void dino_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int); + void *dino_vaddr(void *, bus_space_handle_t); + u_int8_t dino_r1(void *, bus_space_handle_t, bus_size_t); u_int16_t dino_r2(void *, bus_space_handle_t, bus_size_t); u_int32_t dino_r4(void *, bus_space_handle_t, bus_size_t); @@ -266,6 +269,7 @@ dino_attach_hook(struct device *parent, dino_enable_bus(sc, 0); } +/* XXXNH not used by OpenBSD at all */ void dino_enable_bus(struct dino_softc *sc, int bus) { @@ -327,9 +331,18 @@ dino_conf_read(void *v, pcitag_t tag, in struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; pcireg_t data; + uint32_t pamr; + + /* fix arbitration errata by disabling all pci devs on config read */ + pamr = r->pamr; + r->pamr = 0; r->pci_addr = tag | reg; data = r->pci_conf_data; + + /* restore arbitration */ + r->pamr = pamr; + return le32toh(data); } @@ -339,16 +352,21 @@ dino_conf_write(void *v, pcitag_t tag, i struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; pcireg_t data1; + uint32_t pamr; - /* fix coalescing config writes errata by interleaving w/ a read */ - r->pci_addr = tag | PCI_ID_REG; - data1 = r->pci_conf_data; + /* fix arbitration errata by disabling all pci devs on config read */ + pamr = r->pamr; + r->pamr = 0; r->pci_addr = tag | reg; r->pci_conf_data = htole32(data); + /* fix coalescing config and io writes by interleaving w/ a read */ r->pci_addr = tag | PCI_ID_REG; data1 = r->pci_conf_data; + + /* restore arbitration */ + r->pamr = pamr; } int @@ -359,8 +377,12 @@ dino_intr_map(struct pci_attach_args *pa pcireg_t reg; reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); - *ihp = PCI_INTERRUPT_LINE(reg); - return *ihp < 0; + + if (PCI_INTERRUPT_LINE(reg) == 0xff) + return 1; + + *ihp = PCI_INTERRUPT_LINE(reg); /* XXXNH OpenBSD has +1 - why ? */ + return 0; /* return *ihp < 0; */ } const char * @@ -368,21 +390,35 @@ dino_intr_string(void *v, pci_intr_handl { static char buf[32]; - snprintf(buf, 32, "irq %ld", ih); + snprintf(buf, sizeof(buf), "irq %ld", ih); return buf; } -extern int cold; - - void * dino_intr_establish(void *v, pci_intr_handle_t ih, int pri, int (*handler)(void *), void *arg) { struct dino_softc *sc = v; +#if 0 + volatile struct dino_regs *r = &sc->sc_regs; +#endif + void *iv; - return hp700_intr_establish(&sc->sc_dv, pri, handler, arg, + if (ih <= 0 || ih > 11) { + Debugger(); + return NULL; + } + + iv = hp700_intr_establish(&sc->sc_dv, pri, handler, arg, &sc->sc_int_reg, ih); +#if 0 + if (iv) + if (cold) + sc->sc_imr |= (1 << (ih /* -1 XXXNH */)); + else + r->imr = |= (1 << (ih /* -1 XXXNH */)); +#endif + return iv; } void @@ -579,7 +615,7 @@ dino_r1(void *v, bus_space_handle_t h, b struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; return *((volatile u_int8_t *)&r->pci_io_data + (h & 3)); } } @@ -588,24 +624,20 @@ u_int16_t dino_r2(void *v, bus_space_handle_t h, bus_size_t o) { volatile u_int16_t *p; - volatile u_int16_t d; h += o; - if (h & 0xf0000000) { + if (h & 0xf0000000) p = (volatile u_int16_t *)h; - d = le16toh(*p); - } else { + else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; - d = le16toh(*p); } - - return d; + return le16toh(*p); } u_int32_t @@ -647,7 +679,7 @@ dino_w1(void *v, bus_space_handle_t h, b struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; *((volatile u_int8_t *)&r->pci_io_data + (h & 3)) = vv; } } @@ -664,7 +696,7 @@ dino_w2(void *v, bus_space_handle_t h, b struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; @@ -694,7 +726,7 @@ dino_w8(void *v, bus_space_handle_t h, b { h += o; if (h & 0xf0000000) - *(volatile u_int64_t *)h = vv; + *(volatile u_int64_t *)h = htole64(vv); else panic("dino_w8: not implemented"); } @@ -712,7 +744,7 @@ dino_rm_1(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); } @@ -732,7 +764,7 @@ dino_rm_2(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; @@ -780,7 +812,7 @@ dino_wm_1(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); } @@ -800,7 +832,7 @@ dino_wm_2(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; @@ -848,7 +880,7 @@ dino_sm_1(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); } @@ -868,7 +900,7 @@ dino_sm_2(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; @@ -917,12 +949,13 @@ dino_rrm_2(void *v, bus_space_handle_t h struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; } + c /= 2; while (c--) *a++ = *p; } @@ -944,6 +977,7 @@ dino_rrm_4(void *v, bus_space_handle_t h p = (volatile u_int32_t *)&r->pci_io_data; } + c /= 4; while (c--) *a++ = *p; } @@ -968,12 +1002,13 @@ dino_wrm_2(void *v, bus_space_handle_t h struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; } + c /= 2; while (c--) *p = *a++; } @@ -995,6 +1030,7 @@ dino_wrm_4(void *v, bus_space_handle_t h p = (volatile u_int32_t *)&r->pci_io_data; } + c /= 4; while (c--) *p = *a++; } @@ -1020,12 +1056,10 @@ dino_rr_1(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h++) { + r->pci_addr = h; p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); *a++ = *p; - if (!(++h & 3)) - r->pci_addr = h; } } } @@ -1033,26 +1067,26 @@ dino_rr_1(void *v, bus_space_handle_t h, void dino_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c) { - volatile u_int16_t *p; + volatile u_int16_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile u_int16_t *)h; - while (c--) - *a++ = le16toh(*p++); + while (c--) { + data = *p++; + *a++ = le16toh(data); + } } else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h += 2) { + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; - *a++ = le16toh(*p); - h += 2; - if (!(h & 2)) - r->pci_addr = h; + data = *p; + *a++ = le16toh(data); } } } @@ -1060,20 +1094,23 @@ dino_rr_2(void *v, bus_space_handle_t h, void dino_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c) { - volatile u_int32_t *p; + volatile u_int32_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile u_int32_t *)h; - while (c--) - *a++ = le32toh(*p++); + while (c--) { + data = *p++; + *a++ = le32toh(data); + } } else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; for (; c--; h += 4) { r->pci_addr = h; - *a++ = le32toh(r->pci_io_data); + data = r->pci_io_data; + *a++ = le32toh(data); } } } @@ -1098,12 +1135,10 @@ dino_wr_1(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h++) { + r->pci_addr = h; p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); *p = *a++; - if (!(++h & 3)) - r->pci_addr = h; } } } @@ -1111,26 +1146,26 @@ dino_wr_1(void *v, bus_space_handle_t h, void dino_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c) { - volatile u_int16_t *p; + volatile u_int16_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile u_int16_t *)h; - while (c--) - *p++ = htole16(*a++); + while (c--) { + data = *a++; + *p++ = htole16(data); + } } else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h += 2) { + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; - *p = htole16(*a++); - h += 2; - if (!(h & 2)) - r->pci_addr = h; + data = *a++; + *p = htole16(data); } } } @@ -1138,20 +1173,23 @@ dino_wr_2(void *v, bus_space_handle_t h, void dino_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c) { - volatile u_int32_t *p; + volatile u_int32_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile u_int32_t *)h; - while (c--) - *p++ = htole32(*a++); + while (c--) { + data = *a++; + *p++ = htole32(data); + } } else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; for (; c--; h += 4) { r->pci_addr = h; - r->pci_io_data = htole32(*a++); + data = *a++; + r->pci_io_data = htole32(data); } } } @@ -1168,6 +1206,7 @@ dino_rrr_2(void *v, bus_space_handle_t h { volatile u_int16_t *p; + c /= 2; h += o; if (h & 0xf0000000) { p = (volatile u_int16_t *)h; @@ -1177,15 +1216,12 @@ dino_rrr_2(void *v, bus_space_handle_t h struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h += 2) { + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; *a++ = *p; - h += 2; - if (!(h & 2)) - r->pci_addr = h; } } } @@ -1196,6 +1232,7 @@ dino_rrr_4(void *v, bus_space_handle_t h { volatile u_int32_t *p; + c /= 4; h += o; if (h & 0xf0000000) { p = (volatile u_int32_t *)h; @@ -1225,6 +1262,7 @@ dino_wrr_2(void *v, bus_space_handle_t h { volatile u_int16_t *p; + c /= 2; h += o; if (h & 0xf0000000) { p = (volatile u_int16_t *)h; @@ -1234,15 +1272,12 @@ dino_wrr_2(void *v, bus_space_handle_t h struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h += 2) { + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; *p = *a++; - h += 2; - if (!(h & 2)) - r->pci_addr = h; } } } @@ -1253,6 +1288,7 @@ dino_wrr_4(void *v, bus_space_handle_t h { volatile u_int32_t *p; + c /= 4; h += o; if (h & 0xf0000000) { p = (volatile u_int32_t *)h; @@ -1290,12 +1326,10 @@ dino_sr_1(void *v, bus_space_handle_t h, struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h++) { + r->pci_addr = h; p = (volatile u_int8_t *)&r->pci_io_data + (h & 3); *p = vv; - if (!(++h & 3)) - r->pci_addr = h; } } } @@ -1306,23 +1340,21 @@ dino_sr_2(void *v, bus_space_handle_t h, volatile u_int16_t *p; h += o; + vv = htole16(vv); if (h & 0xf0000000) { p = (volatile u_int16_t *)h; while (c--) - *p++ = htole16(vv); + *p++ = vv; } else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; - r->pci_addr = h & ~3; - while (c--) { + for (; c--; h++) { + r->pci_addr = h; p = (volatile u_int16_t *)&r->pci_io_data; if (h & 2) p++; - *p = htole16(vv); - h += 2; - if (!(h & 2)) - r->pci_addr = h; + *p = vv; } } } @@ -1333,17 +1365,18 @@ dino_sr_4(void *v, bus_space_handle_t h, volatile u_int32_t *p; h += o; + vv = htole32(vv); if (h & 0xf0000000) { p = (volatile u_int32_t *)h; while (c--) - *p++ = htole32(vv); + *p++ = vv; } else { struct dino_softc *sc = v; volatile struct dino_regs *r = sc->sc_regs; for (; c--; h += 4) { r->pci_addr = h; - r->pci_io_data = htole32(vv); + r->pci_io_data = vv; } } } @@ -1566,6 +1599,10 @@ dinomatch(struct device *parent, struct ca->ca_type.iodc_sv_model != HPPA_BRIDGE_DINO) return 0; + /* do not match on the elroy family */ + if (ca->ca_type.iodc_model == 0x78) + return 0; + /* Make sure we have an IRQ. */ if (ca->ca_irq == HP700CF_IRQ_UNDEF) { ca->ca_irq = hp700_intr_allocate_bit(&int_reg_cpu); @@ -1597,17 +1634,23 @@ dinoattach(struct device *parent, struct } sc->sc_regs = r = (volatile struct dino_regs *)sc->sc_bh; -#ifdef trust_the_firmware_to_proper_initialize_everything + r->pciror = 0; + r->pciwor = 0; r->io_addr_en = 0; + r->gmask &= ~1; /* allow GSC bus req */ +#ifdef trust_the_firmware_to_proper_initialize_everything r->io_control = 0x80; r->pamr = 0; r->papr = 0; r->io_fbb_en |= 1; r->damode = 0; - r->gmask &= ~1; /* allow GSC bus req */ - r->pciror = 0; - r->pciwor = 0; r->brdg_feat = 0xc0000000; + r->mltim = 0x40 /* 64 clocks */ + r->tltim = 0x8c /* 12 clocks */ + + /* PCI reset */ + r->pcicmd = 0x6f; + DELAY(10000); /* 10ms for reset to settle */ #endif snprintf(sc->sc_ioexname, sizeof(sc->sc_ioexname), @@ -1624,7 +1667,10 @@ dinoattach(struct device *parent, struct r->icr = 0; r->imr = ~0; data = r->irr0; + data = r->irr1; r->imr = 0; + __asm __volatile ("" ::: "memory"); + r->icr = 0; r->iar0 = cpu_gethpa(0) | (31 - ca->ca_irq); splx(s); /* Establish the interrupt register. */