Index: sys/arch/hp700/dev/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/dev/cpu.c,v retrieving revision 1.13 diff -u -p -u -r1.13 cpu.c --- sys/arch/hp700/dev/cpu.c 8 May 2009 09:33:57 -0000 1.13 +++ sys/arch/hp700/dev/cpu.c 27 May 2009 09:35:40 -0000 @@ -163,5 +163,13 @@ cpuattach(device_t parent, device_t self * or below 27. */ int_reg_cpu.int_reg_allocatable_bits = - (1 << 28) | (1 << 27) | (1 << 26); + (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | + (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | + (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15) | +#if 1 + 0; +#else + (1 << 28) | (1 << 27) | (1 << 26) | (1 << 25); +#endif } Index: sys/arch/hp700/dev/dino.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/dev/dino.c,v retrieving revision 1.13 diff -u -p -u -r1.13 dino.c --- sys/arch/hp700/dev/dino.c 24 May 2009 06:53:34 -0000 1.13 +++ sys/arch/hp700/dev/dino.c 27 May 2009 09:35:41 -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; @@ -148,6 +147,7 @@ const char *dino_intr_string(void *, pci void *dino_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *), void *); void dino_intr_disestablish(void *, void *); + void *dino_alloc_parent(device_t, 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,7 +159,9 @@ 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); uint8_t dino_r1(void *, bus_space_handle_t, bus_size_t); uint16_t dino_r2(void *, bus_space_handle_t, bus_size_t); @@ -256,6 +258,7 @@ void dino_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba) { +#if 1 struct dino_softc *sc = pba->pba_pc->_cookie; /* @@ -264,8 +267,10 @@ dino_attach_hook(device_t parent, device * Therefore we recursively walk all buses to simply enable everything. */ dino_enable_bus(sc, 0); +#endif } +/* XXXNH not used by OpenBSD at all */ void dino_enable_bus(struct dino_softc *sc, int bus) { @@ -327,9 +332,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 +353,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 +378,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 * @@ -381,6 +404,7 @@ dino_intr_establish(void *v, pci_intr_ha { struct dino_softc *sc = v; + return hp700_intr_establish(sc->sc_dv, pri, handler, arg, &sc->sc_int_reg, ih); } @@ -454,8 +478,10 @@ dino_memmap(void *v, bus_addr_t bpa, bus if (reg & 0x80000001) panic("mapping outside the mem extent range"); #endif - if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp))) + if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp))) { + return error; +} ++sc->sc_memrefcount[((bpa >> 23) & 0x1f)]; /* map into the upper bus space, if not yet mapped this 8M */ if (reg != r->io_addr_en) @@ -579,7 +605,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 uint8_t *)&r->pci_io_data + (h & 3)); } } @@ -588,24 +614,20 @@ uint16_t dino_r2(void *v, bus_space_handle_t h, bus_size_t o) { volatile uint16_t *p; - volatile uint16_t d; h += o; - if (h & 0xf0000000) { + if (h & 0xf0000000) p = (volatile uint16_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 uint16_t *)&r->pci_io_data; if (h & 2) p++; - d = le16toh(*p); } - - return d; + return le16toh(*p); } uint32_t @@ -647,7 +669,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 uint8_t *)&r->pci_io_data + (h & 3)) = vv; } } @@ -664,7 +686,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; @@ -694,7 +716,7 @@ dino_w8(void *v, bus_space_handle_t h, b { h += o; if (h & 0xf0000000) - *(volatile uint64_t *)h = vv; + *(volatile uint64_t *)h = htole64(vv); else panic("dino_w8: not implemented"); } @@ -712,7 +734,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 uint8_t *)&r->pci_io_data + (h & 3); } @@ -732,7 +754,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; @@ -780,7 +802,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 uint8_t *)&r->pci_io_data + (h & 3); } @@ -800,7 +822,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; @@ -848,7 +870,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 uint8_t *)&r->pci_io_data + (h & 3); } @@ -868,7 +890,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; @@ -917,12 +939,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; } + c /= 2; while (c--) *a++ = *p; } @@ -944,6 +967,7 @@ dino_rrm_4(void *v, bus_space_handle_t h p = (volatile uint32_t *)&r->pci_io_data; } + c /= 4; while (c--) *a++ = *p; } @@ -968,12 +992,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; } + c /= 2; while (c--) *p = *a++; } @@ -995,6 +1020,7 @@ dino_wrm_4(void *v, bus_space_handle_t h p = (volatile uint32_t *)&r->pci_io_data; } + c /= 4; while (c--) *p = *a++; } @@ -1020,12 +1046,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 uint8_t *)&r->pci_io_data + (h & 3); *a++ = *p; - if (!(++h & 3)) - r->pci_addr = h; } } } @@ -1033,26 +1057,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, uint16_t *a, bus_size_t c) { - volatile uint16_t *p; + volatile uint16_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile uint16_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 uint16_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 +1084,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, uint32_t *a, bus_size_t c) { - volatile uint32_t *p; + volatile uint32_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile uint32_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 +1125,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 uint8_t *)&r->pci_io_data + (h & 3); *p = *a++; - if (!(++h & 3)) - r->pci_addr = h; } } } @@ -1111,26 +1136,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 uint16_t *a, bus_size_t c) { - volatile uint16_t *p; + volatile uint16_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile uint16_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 uint16_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 +1163,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 uint32_t *a, bus_size_t c) { - volatile uint32_t *p; + volatile uint32_t *p, data; h += o; if (h & 0xf0000000) { p = (volatile uint32_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 +1196,7 @@ dino_rrr_2(void *v, bus_space_handle_t h { volatile uint16_t *p; + c /= 2; h += o; if (h & 0xf0000000) { p = (volatile uint16_t *)h; @@ -1177,15 +1206,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; *a++ = *p; - h += 2; - if (!(h & 2)) - r->pci_addr = h; } } } @@ -1196,6 +1222,7 @@ dino_rrr_4(void *v, bus_space_handle_t h { volatile uint32_t *p; + c /= 4; h += o; if (h & 0xf0000000) { p = (volatile uint32_t *)h; @@ -1225,6 +1252,7 @@ dino_wrr_2(void *v, bus_space_handle_t h { volatile uint16_t *p; + c /= 2; h += o; if (h & 0xf0000000) { p = (volatile uint16_t *)h; @@ -1234,15 +1262,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 uint16_t *)&r->pci_io_data; if (h & 2) p++; *p = *a++; - h += 2; - if (!(h & 2)) - r->pci_addr = h; } } } @@ -1253,6 +1278,7 @@ dino_wrr_4(void *v, bus_space_handle_t h { volatile uint32_t *p; + c /= 4; h += o; if (h & 0xf0000000) { p = (volatile uint32_t *)h; @@ -1290,12 +1316,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 uint8_t *)&r->pci_io_data + (h & 3); *p = vv; - if (!(++h & 3)) - r->pci_addr = h; } } } @@ -1306,23 +1330,21 @@ dino_sr_2(void *v, bus_space_handle_t h, volatile uint16_t *p; h += o; + vv = htole16(vv); if (h & 0xf0000000) { p = (volatile uint16_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 += 2) { + r->pci_addr = h; p = (volatile uint16_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 +1355,18 @@ dino_sr_4(void *v, bus_space_handle_t h, volatile uint32_t *p; h += o; + vv = htole32(vv); if (h & 0xf0000000) { p = (volatile uint32_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 +1589,10 @@ dinomatch(device_t parent, cfdata_t cfda 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); @@ -1599,17 +1626,25 @@ dinoattach(device_t parent, device_t sel } 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 */ + r->brdg_feat &= ~0xf00; + r->brdg_feat |= 3; +#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), @@ -1623,10 +1658,12 @@ dinoattach(device_t parent, device_t sel /* interrupts guts */ s = splhigh(); - 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. */ Index: sys/arch/hp700/hp700/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/hp700/mainbus.c,v retrieving revision 1.52 diff -u -p -u -r1.52 mainbus.c --- sys/arch/hp700/hp700/mainbus.c 27 May 2009 09:30:14 -0000 1.52 +++ sys/arch/hp700/hp700/mainbus.c 27 May 2009 09:35:46 -0000 @@ -29,10 +29,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* $OpenBSD: mainbus.c,v 1.13 2001/09/19 20:50:56 mickey Exp $ */ +/* $OpenBSD: mainbus.c,v 1.74 2009/04/20 00:42:06 oga Exp $ */ /* - * Copyright (c) 1998-2000 Michael Shalayeff + * Copyright (c) 1998-2004 Michael Shalayeff * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,11 +43,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Michael Shalayeff. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -85,9 +80,23 @@ __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v #include #include #include +#include static struct pdc_hpa pdc_hpa PDC_ALIGNMENT; +#ifdef MBUSDEBUG + +#define DPRINTF(s) do { \ + if (mbusdebug) \ + printf s; \ +} while(0) + +int mbusdebug = 0; +#else +#define DPRINTF(s) /* */ +#endif + + struct mainbus_softc { device_t sc_dv; @@ -176,64 +185,92 @@ int mbus_add_mapping(bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp) { - u_int frames; -#ifdef USE_BTLB - vsize_t btlb_size; - int error; -#endif /* USE_BTLB */ + static uint32_t bmm[0x4000/32]; /* XXXNH */ + vaddr_t pa, spa, epa; + vsize_t len; + int flex; + + DPRINTF(("\n%s(%x,%x,%scachable,%p)\n", __func__, + (int)bpa, (int)size, flags? "" : "non", bshp)); - /* - * We must be called with a page-aligned address in - * I/O space, and with a multiple of the page size. - */ - KASSERT((bpa & PGOFSET) == 0); KASSERT(bpa >= HPPA_IOSPACE); - KASSERT((size & PGOFSET) == 0); + KASSERT(!(flags & BUS_SPACE_MAP_CACHEABLE)); /* - * Assume that this will succeed. + * Mappings are established in HPPA_FLEX_SIZE units, + * either with BTLB, or regular mappings of the whole area. */ - *bshp = bpa; + for (pa = bpa ; size != 0; pa = epa) { + flex = HPPA_FLEX(pa); + spa = pa & HPPA_FLEX_MASK; + epa = spa + HPPA_FLEX_SIZE; /* may wrap to 0... */ - /* - * Loop while there is space left to map. - */ - frames = size >> PGSHIFT; - while (frames > 0) { + size -= min(size, HPPA_FLEX_SIZE - (pa - spa)); + + /* do need a new mapping? */ + if (bmm[flex / 32] & (1 << (flex % 32))) { + DPRINTF(("+++ already b-mapped flex=%x, mask=%x\n", + flex, bmm[flex / 32])); + continue; + } + + DPRINTF(("%s: adding flex=%x %x-%x, ", __func__, flex, spa, + epa - 1)); + + while (spa != epa) { + len = epa - spa; - /* - * If this mapping is more than eight pages long, - * try to add a BTLB entry. - */ #ifdef USE_BTLB - if (frames > 8 && - frames >= hppa_btlb_size_min) { - btlb_size = frames; + XXX + /* + * Try to map with a BTLB first (might map + * much more than what we are requesting + * for, and cross HPPA_FLEX boundaries). + * + * Note that this code assumes that + * BTLB size are a power of two, so if + * the size is larger than HPPA_FLEX_SIZE + * it will span an integral number of + * HPPA_FLEX_SIZE slots. + */ + if (btlb_size > hppa_btlb_size_max) btlb_size = hppa_btlb_size_max; + if (len > pdc_btlb.max_size << PGSHIFT) + len = pdc_btlb.max_size << PGSHIFT; + + btlb_size <<= PGSHIFT; - error = hppa_btlb_insert(pmap_kernel()->pmap_space, - bpa, bpa, &btlb_size, - pmap_kernel()->pmap_pid | + error = hppa_btlb_insert(pmap_kernel()->pmap_space, + spa, spa, &len, pmap_kernel()->pmap_pid | pmap_prot(pmap_kernel(), VM_PROT_READ | VM_PROT_WRITE)); - if (error == 0) { - bpa += btlb_size; - frames -= (btlb_size >> PGSHIFT); + if (error == 0) { + pa = spa + len; /* may wrap to 0... */ + + DPRINTF(("--- %x/%x, %x-%x ", + flex, HPPA_FLEX(pa - 1), spa, pa - 1)); + + /* register all ranges */ + for (; flex <= HPPA_FLEX(pa - 1); flex++) { + + DPRINTF(("mask %x ", flex)); + bmm[flex / 32] |= (1 << (flex % 32)); + } + if (len > epa - spa) + spa = epa; + else + spa = pa; continue; } - else if (error != ENOMEM) - return error; - } #endif /* USE_BTLB */ - - /* - * Enter another single-page mapping. - */ - pmap_kenter_pa(bpa, bpa, VM_PROT_READ | VM_PROT_WRITE); - bpa += PAGE_SIZE; - frames--; + DPRINTF(("kenter 0x%x-0x%x", (int)spa, (int)epa)); + for (; spa != epa; spa += PAGE_SIZE) + pmap_kenter_pa(spa, spa, + VM_PROT_READ | VM_PROT_WRITE); + } } + *bshp = bpa; /* Success. */ return 0; } @@ -251,14 +288,7 @@ mbus_remove_mapping(bus_space_handle_t b int error; #endif /* USE_BTLB */ - /* - * We must be called with a page-aligned address in - * I/O space, and with a multiple of the page size. - */ bpa = *bpap = bsh; - KASSERT((bpa & PGOFSET) == 0); - KASSERT(bpa >= HPPA_IOSPACE); - KASSERT((size & PGOFSET) == 0); /* * Loop while there is space left to unmap. @@ -306,7 +336,6 @@ mbus_map(void *v, bus_addr_t bpa, bus_si bus_space_handle_t *bshp) { int error; - bus_size_t offset; /* * We must only be called with addresses in I/O space. @@ -314,14 +343,6 @@ mbus_map(void *v, bus_addr_t bpa, bus_si KASSERT(bpa >= HPPA_IOSPACE); /* - * Page-align the I/O address and size. - */ - offset = (bpa & PGOFSET); - bpa -= offset; - size += offset; - size = round_page(size); - - /* * Allocate the region of I/O space. */ error = extent_alloc_region(hp700_io_extent, bpa, size, EX_NOWAIT); @@ -332,11 +353,10 @@ mbus_map(void *v, bus_addr_t bpa, bus_si * Map the region of I/O space. */ error = mbus_add_mapping(bpa, size, flags, bshp); - *bshp |= offset; if (error) { + printf ("bus_space_map: pa 0x%lx, size 0x%lx\n", + bpa, size); if (extent_free(hp700_io_extent, bpa, size, EX_NOWAIT)) { - printf ("bus_space_map: pa 0x%lx, size 0x%lx\n", - bpa, size); printf ("bus_space_map: can't free region\n"); } } @@ -347,19 +367,10 @@ mbus_map(void *v, bus_addr_t bpa, bus_si void mbus_unmap(void *v, bus_space_handle_t bsh, bus_size_t size) { - bus_size_t offset; bus_addr_t bpa; int error; /* - * Page-align the bus_space handle and size. - */ - offset = bsh & PGOFSET; - bsh -= offset; - size += offset; - size = round_page(size); - - /* * Unmap the region of I/O space. */ error = mbus_remove_mapping(bsh, size, &bpa); @@ -389,18 +400,20 @@ mbus_alloc(void *v, bus_addr_t rstart, b rend > hp700_io_extent->ex_end) panic("bus_space_alloc: bad region start/end"); +#if 0 /* * Force the allocated region to be page-aligned. */ if (align < PAGE_SIZE) align = PAGE_SIZE; size = round_page(size); +#endif /* * Allocate the region of I/O space. */ error = extent_alloc_subregion1(hp700_io_extent, rstart, rend, size, - align, 0, boundary, EX_NOWAIT, &bpa); + align, 0, boundary, EX_NOWAIT, &bpa); if (error) return (error); @@ -409,9 +422,9 @@ mbus_alloc(void *v, bus_addr_t rstart, b */ error = mbus_add_mapping(bpa, size, flags, bshp); if (error) { - if (extent_free(hp700_io_extent, bpa, size, EX_NOWAIT)) { printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n", bpa, size); + if (extent_free(hp700_io_extent, bpa, size, EX_NOWAIT)) { printf("bus_space_alloc: can't free region\n"); } } @@ -1170,8 +1183,14 @@ mbus_dmamem_alloc(void *v, bus_size_t si * Allocate physical pages from the VM system. */ TAILQ_INIT(mlist); - error = uvm_pglistalloc(size, low, high, 0, 0, - mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0); +/* 45678901234567890123456789012345678901234567890123456789012345678901234567 */ +#if 1 + error = uvm_pglistalloc(size, low, high, 0, 0, mlist, nsegs, + (flags & BUS_DMA_NOWAIT) == 0); +#else + error = uvm_pglistalloc(size, low, high, alignment, boundry, mlist, + 1, (flags & BUS_DMA_NOWAIT) == 0); +#endif /* * If the allocation failed, and this is a 24-bit @@ -1197,6 +1216,7 @@ mbus_dmamem_alloc(void *v, bus_size_t si return (0); } } + /* If we don't have the pages. */ if (error) { @@ -1272,10 +1292,12 @@ mbus_dmamem_map(void *v, bus_dma_segment { struct vm_page *pg; struct pglist *pglist; +#if 0 vaddr_t va; paddr_t pa; const uvm_flag_t kmflags = (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0; +#endif size = round_page(size); @@ -1286,6 +1308,19 @@ mbus_dmamem_map(void *v, bus_dma_segment *kvap = (void *)segs[0]._ds_va; return (0); } +#if 1 + else { + pglist = segs[0]._ds_mlist; + pg = TAILQ_FIRST(pglist); + segs[0]._ds_va = segs[0].ds_addr = VM_PAGE_TO_PHYS(pg); + segs[0].ds_len = size; + *kvap = (void *)segs[0]._ds_va; + + TAILQ_FOREACH(pg, pglist, pageq.queue) + /* XXX for now */ + pmap_changebit(pg, PTE_PROT(TLB_UNCACHEABLE), 0); + } +#else /* Get a chunk of kernel virtual space. */ va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags); @@ -1305,6 +1340,8 @@ mbus_dmamem_map(void *v, bus_dma_segment va += PAGE_SIZE; size -= PAGE_SIZE; } +#endif + pmap_update(); return (0); } @@ -1332,7 +1369,9 @@ mbus_dmamem_unmap(void *v, void *kva, si size = round_page(size); pmap_kremove((vaddr_t)kva, size); pmap_update(pmap_kernel()); +#if 0 uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY); +#endif } /* @@ -1515,8 +1554,11 @@ mbattach(device_t parent, device_t self, * XXX fredette - this may be a copout, or it may * be a great idea. I'm not sure which yet. */ - if (bus_space_map(&hppa_bustag, pdc_hpa.hpa, 0 - pdc_hpa.hpa, 0, &ioh)) - panic("mbattach: can't map mainbus IO space"); + + /* map all the way till the end of the memory */ + if (bus_space_map(&hppa_bustag, pdc_hpa.hpa, + (~0LU - pdc_hpa.hpa + 1), 0, &ioh)) + panic("mbattach: cannot map mainbus IO space"); /* * Local-Broadcast the HPA to all modules on the bus Index: sys/arch/hp700/hp700/pim.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/hp700/pim.h,v retrieving revision 1.4 diff -u -p -u -r1.4 pim.h --- sys/arch/hp700/hp700/pim.h 17 May 2009 18:21:29 -0000 1.4 +++ sys/arch/hp700/hp700/pim.h 27 May 2009 09:35:46 -0000 @@ -190,7 +190,16 @@ struct hp700_pim_checks { #define PIM_BUS_PIV (1 << 7) #define PIM_BUS_BSV (1 << 6) #define PIM_BUS_STAT(bc) ((bc) & 0x3f) -#define PIM_BUS_BITS "\020\026RSV\025RQV\010PIV\007BSV" +#define PIM_BUS_BITS \ + "\177\020" /* New bitmask format */ \ + "b\025RSV\0" /* bit 21 */ \ + "b\024RQV\0" /* bit 20 */ \ + "f\020\004VAR\0" /* bit 16 .. 19 */ \ + "f\014\004TYPE\0" /* bit 12 .. 15 */ \ + "f\010\004SIZE\0" /* bit 8 .. 11 */ \ + "b\007PIV\0" \ + "b\006BSV\0" \ + "f\000\006STAT\0" /* bit 0 .. 5 */ /* The Assist Check word. */ uint32_t pim_check_assist; Index: sys/arch/hp700/include/iomod.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/include/iomod.h,v retrieving revision 1.6 diff -u -p -u -r1.6 iomod.h --- sys/arch/hp700/include/iomod.h 27 May 2009 09:30:14 -0000 1.6 +++ sys/arch/hp700/include/iomod.h 27 May 2009 09:35:47 -0000 @@ -124,6 +124,7 @@ #define MAXMODBUS ((int)(FPA_IOMOD)) /* maximum modules/bus */ #define HPPA_FLEX_MASK 0xFFFC0000 /* (see below) */ +#define HPPA_FLEX_SIZE (~HPPA_FLEX_MASK + 1) #define HPPA_FLEX(a) (((a) & HPPA_FLEX_MASK) >> 18) /* size of HPA space for any device */