Index: sys/arch/hp700/hp700/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/hp700/mainbus.c,v retrieving revision 1.49 diff -u -p -u -r1.49 mainbus.c --- sys/arch/hp700/hp700/mainbus.c 8 May 2009 09:33:58 -0000 1.49 +++ sys/arch/hp700/hp700/mainbus.c 18 May 2009 09:26:18 -0000 @@ -176,64 +176,100 @@ 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; + +#ifdef MBUSDEBUG + printf("%s(%x,%x,%scachable,%p)\n", __func__, + bpa, size, flags? "" : "non", bshp); +#endif - /* - * 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; + pa = bpa; + for ( ; 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))) { +#ifdef MBUSDEBUG + printf("+++ already b-mapped flex=%x, mask=%x\n", + flex, bmm[flex / 32]); +#endif + continue; + } + +#ifdef MBUSDEBUG + printf("bus_mem_add_mapping: adding flex=%x " + "%x-%x, ", flex, spa, epa - 1); +#endif + 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; + /* + * 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... */ +#ifdef MBUSDEBUG + printf("--- %x/%x, %x-%x ", + flex, HPPA_FLEX(pa - 1), spa, pa - 1); +#endif + /* register all ranges */ + for (; flex <= HPPA_FLEX(pa - 1); flex++) { +#ifdef MBUSDEBUG + printf("mask %x ", flex); +#endif + bmm[flex / 32] |= (1 << (flex % 32)); + } + if (len > epa - spa) + spa = epa; + else + spa = pa; continue; } - else if (error != ENOMEM) - return error; +#endif +#ifdef MBUSDEBUG + printf("kenter 0x%x-0x%x", spa, epa); +#endif + for (; spa != epa; spa += PAGE_SIZE) + pmap_kenter_pa(spa, spa, + VM_PROT_READ | VM_PROT_WRITE); } -#endif /* USE_BTLB */ - - /* - * Enter another single-page mapping. - */ - pmap_kenter_pa(bpa, bpa, VM_PROT_READ | VM_PROT_WRITE); - bpa += PAGE_SIZE; - frames--; } + *bshp = bpa; /* Success. */ return 0; } @@ -251,14 +287,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 +335,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 +342,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,12 +352,11 @@ 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) { 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"); + printf ("%s: pa 0x%lx, size 0x%lx\n", __func__, + bpa, size); + printf ("%s: can't free region\n", __func__); } } @@ -347,19 +366,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 +399,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); @@ -411,7 +423,7 @@ mbus_alloc(void *v, bus_addr_t rstart, b 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); + bpa, size); printf("bus_space_alloc: can't free region\n"); } } @@ -1521,11 +1533,11 @@ mbattach(device_t parent, device_t self, /* * Local-Broadcast the HPA to all modules on the bus */ - ((struct iomod *)(pdc_hpa.hpa & FLEX_MASK))[FPA_IOMOD].io_flex = - (void *)((pdc_hpa.hpa & FLEX_MASK) | DMA_ENABLE); + ((struct iomod *)(pdc_hpa.hpa & HPPA_FLEX_MASK))[FPA_IOMOD].io_flex = + (void *)((pdc_hpa.hpa & HPPA_FLEX_MASK) | DMA_ENABLE); sc->sc_hpa = pdc_hpa.hpa; - aprint_normal(" [flex %lx]\n", pdc_hpa.hpa & FLEX_MASK); + aprint_normal(" [flex %lx]\n", pdc_hpa.hpa & HPPA_FLEX_MASK); /* PDC first */ memset(&nca, 0, sizeof(nca)); Index: sys/arch/hp700/include/iomod.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/include/iomod.h,v retrieving revision 1.5 diff -u -p -u -r1.5 iomod.h --- sys/arch/hp700/include/iomod.h 30 Apr 2009 07:01:27 -0000 1.5 +++ sys/arch/hp700/include/iomod.h 18 May 2009 09:26:19 -0000 @@ -123,8 +123,9 @@ #define FPA_IOMOD ((FPA_HIGH-FPA_LOW)/sizeof(struct iomod)) #define MAXMODBUS ((int)(FPA_IOMOD)) /* maximum modules/bus */ -#define FLEX_MASK 0xFFFC0000 /* (see below) */ -#define HPPA_FLEX(a) (((a) & FLEX_MASK) >> 18) +#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 */ #define IOMOD_HPASIZE 0x1000