diff options
Diffstat (limited to 'sys/arch/amiga/isa/cross.c')
-rw-r--r-- | sys/arch/amiga/isa/cross.c | 381 |
1 files changed, 152 insertions, 229 deletions
diff --git a/sys/arch/amiga/isa/cross.c b/sys/arch/amiga/isa/cross.c index e12500f1811..b5bbf779ec2 100644 --- a/sys/arch/amiga/isa/cross.c +++ b/sys/arch/amiga/isa/cross.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cross.c,v 1.7 1996/11/23 21:45:26 kstailey Exp $ */ +/* $OpenBSD: cross.c,v 1.8 1996/11/28 23:33:06 niklas Exp $ */ /* * Copyright (c) 1994, 1996 Niklas Hallqvist, Carsten Hammer @@ -37,7 +37,11 @@ #include <sys/syslog.h> #include <sys/systm.h> -#include <machine/bus.old.h> +#include <vm/vm.h> +#include <vm/vm.h> +#include <vm/vm.h> + +#include <machine/bus.h> #include <machine/cpu.h> #include <machine/intr.h> @@ -48,8 +52,8 @@ #include <amiga/amiga/isr.h> #include <amiga/dev/zbusvar.h> #include <amiga/isa/isa_machdep.h> -#include <amiga/isa/crossvar.h> #include <amiga/isa/crossreg.h> +#include <amiga/isa/crossvar.h> extern int cold; @@ -59,50 +63,12 @@ void crossattach __P((struct device *, struct device *, void *)); int crossmatch __P((struct device *, void *, void *)); int crossprint __P((void *, const char *)); -int cross_io_map __P((bus_chipset_tag_t, bus_io_addr_t, bus_io_size_t, - bus_io_handle_t *)); -int cross_mem_map __P((bus_chipset_tag_t, bus_mem_addr_t, bus_mem_size_t, - int, bus_mem_handle_t *)); - -void cross_io_read_multi_1 __P((bus_io_handle_t, bus_io_size_t, u_int8_t *, - bus_io_size_t)); -void cross_io_read_multi_2 __P((bus_io_handle_t, bus_io_size_t, u_int16_t *, - bus_io_size_t)); - -void cross_io_write_multi_1 __P((bus_io_handle_t, bus_io_size_t, - const u_int8_t *, bus_io_size_t)); -void cross_io_write_multi_2 __P((bus_io_handle_t, bus_io_size_t, - const u_int16_t *, bus_io_size_t)); - -void cross_io_read_raw_multi_2 __P((bus_io_handle_t, bus_io_size_t, - u_int8_t *, bus_io_size_t)); -void cross_io_write_raw_multi_2 __P((bus_io_handle_t, bus_io_size_t, - const u_int8_t *, bus_io_size_t)); - -/* - * Note that the following unified access functions are prototyped for the - * I/O access case. We use casts to get type correctness. - */ -int cross_unmap __P((bus_io_handle_t, bus_io_size_t)); - -__inline u_int8_t cross_read_1 __P((bus_io_handle_t, bus_io_size_t)); -__inline u_int16_t cross_read_2 __P((bus_io_handle_t, bus_io_size_t)); - -__inline void cross_write_1 __P((bus_io_handle_t, bus_io_size_t, u_int8_t)); -__inline void cross_write_2 __P((bus_io_handle_t, bus_io_size_t, u_int16_t)); - -/* - * In order to share the access function implementations for I/O and memory - * access we cast the functions for the memory access case. These typedefs - * make that casting look nicer. - */ -typedef int (*bus_mem_unmap_t) __P((bus_mem_handle_t, bus_mem_size_t)); -typedef u_int8_t (*bus_mem_read_1_t) __P((bus_mem_handle_t, bus_mem_size_t)); -typedef u_int16_t (*bus_mem_read_2_t) __P((bus_mem_handle_t, bus_mem_size_t)); -typedef void (*bus_mem_write_1_t) __P((bus_mem_handle_t, bus_mem_size_t, - u_int8_t)); -typedef void (*bus_mem_write_2_t) __P((bus_mem_handle_t, bus_mem_size_t, - u_int16_t)); +int cross_io_map __P((bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *)); +int cross_mem_map __P((bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *)); +int cross_io_unmap __P((bus_space_handle_t, bus_size_t)); +int cross_mem_unmap __P((bus_space_handle_t, bus_size_t)); int crossintr __P((void *)); @@ -112,34 +78,7 @@ void *cross_intr_establish __P((void *, int, int, int, int (*)(void *), void *, char *)); void cross_intr_disestablish __P((void *, void *)); -static u_int16_t swap __P((u_int16_t)); - -struct amiga_bus_chipset cross_chipset = { - 0 /* bc_data */, - - cross_io_map, cross_unmap, - cross_read_1, cross_read_2, - 0 /* bc_io_read_4 */, 0 /* bc_io_read_8 */, - cross_io_read_multi_1, cross_io_read_multi_2, - 0 /* bc_io_multi_4 */, 0 /* bc_io_multi_8 */, - cross_write_1, cross_write_2, - 0 /* bc_io_write_4 */, 0 /* bc_io_write_8 */, - cross_io_write_multi_1, cross_io_write_multi_2, - 0 /* bc_io_write_multi_4 */, 0 /* bc_io_write_multi_8 */, - - cross_mem_map, (bus_mem_unmap_t)cross_unmap, - (bus_mem_read_1_t)cross_read_1, (bus_mem_read_2_t)cross_read_2, - 0 /* bc_mem_read_4 */, 0 /* bc_mem_read_8 */, - (bus_mem_write_1_t)cross_write_1, (bus_mem_write_2_t)cross_write_2, - 0 /* bc_mem_write_4 */, 0 /* bc_mem_write_8 */, - - /* These are extensions to the general NetBSD bus interface. */ - cross_io_read_raw_multi_2, - 0 /* bc_io_read_raw_multi_4 */, 0 /* bc_io_read_raw_multi_8 */, - - cross_io_write_raw_multi_2, - 0 /* bc_io_write_raw_multi_4 */, 0 /* bc_io_write_raw_multi_8 */, -}; +int cross_pager_get_pages __P((vm_pager_t, vm_page_t *, int, boolean_t)); struct cfattach cross_ca = { sizeof(struct cross_softc), crossmatch, crossattach @@ -149,6 +88,21 @@ struct cfdriver cross_cd = { NULL, "cross", DV_DULL, 0 }; +struct pagerops crosspagerops = { + NULL, + NULL, + NULL, + cross_pager_get_pages, + NULL, + NULL, + vm_pager_clusternull, + NULL, + NULL, + NULL +}; + +struct vm_pager crosspager; + int crossmatch(parent, match, aux) struct device *parent; @@ -172,17 +126,25 @@ crossattach(parent, self, aux) struct cross_softc *sc = (struct cross_softc *)self; struct zbus_args *zap = aux; struct isabus_attach_args iba; + int i; bcopy(zap, &sc->sc_zargs, sizeof(struct zbus_args)); - bcopy(&cross_chipset, &sc->sc_bc, sizeof(struct amiga_bus_chipset)); - sc->sc_bc.bc_data = sc; + sc->sc_iot.bs_data = sc; + sc->sc_iot.bs_map = cross_io_map; + sc->sc_iot.bs_unmap = cross_io_unmap; + sc->sc_iot.bs_swapped = 1; + sc->sc_memt.bs_data = sc; + sc->sc_memt.bs_map = cross_mem_map; + sc->sc_memt.bs_unmap = cross_mem_unmap; + sc->sc_memt.bs_swapped = 1; sc->sc_status = CROSS_STATUS_ADDR(zap->va); sc->sc_imask = 1 << CROSS_MASTER; /* Enable interrupts lazily in cross_intr_establish. */ CROSS_ENABLE_INTS(zap->va, 0); + /* Default 16 bit tranfer */ - *CROSS_HANDLE_TO_XLP_LATCH((bus_io_handle_t)zap->va) = CROSS_SBHE; + *CROSS_HANDLE_TO_XLP_LATCH((bus_space_handle_t)zap->va) = CROSS_SBHE; printf(": pa 0x%08x va 0x%08x size 0x%x\n", zap->pa, zap->va, zap->size); @@ -191,8 +153,17 @@ crossattach(parent, self, aux) sc->sc_ic.ic_intr_establish = cross_intr_establish; sc->sc_ic.ic_intr_disestablish = cross_intr_disestablish; + /* Allocate a bunch of pages used for the bank-switching logic. */ + for (i = 0; i < CROSS_BANK_SIZE / NBPG; i++) { + VM_PAGE_INIT(&sc->sc_page[i], NULL, 0); + sc->sc_page[i].phys_addr = zap->pa + CROSS_XL_MEM + i * NBPG; + sc->sc_page[i].flags |= PG_FICTITIOUS; + vm_page_free(&sc->sc_page[i]); + } + iba.iba_busname = "isa"; - iba.iba_bc = &sc->sc_bc; + iba.iba_iot = &sc->sc_iot; + iba.iba_memt = &sc->sc_memt; iba.iba_ic = &sc->sc_ic; config_found(self, &iba, crossprint); } @@ -209,169 +180,94 @@ crossprint(auxp, pnp) int -cross_io_map(bct, addr, sz, handle) - bus_chipset_tag_t bct; - bus_io_addr_t addr; - bus_io_size_t sz; - bus_io_handle_t *handle; -{ - *handle = (bus_io_handle_t) - ((struct cross_softc *)bct->bc_data)->sc_zargs.va + 2 * addr; -#if 0 - printf("io_map %x %d -> %x\n", addr, sz, *handle); -#endif - return 0; -} - -int -cross_mem_map(bct, addr, sz, cacheable, handle) - bus_chipset_tag_t bct; - bus_mem_addr_t addr; - bus_mem_size_t sz; +cross_io_map(bst, addr, sz, cacheable, handle) + bus_space_tag_t bst; + bus_addr_t addr; + bus_size_t sz; int cacheable; - bus_mem_handle_t *handle; + bus_space_handle_t *handle; { - *handle = (bus_mem_handle_t) - ((struct cross_softc *)bct->bc_data)->sc_zargs.va + 2 * addr + - CROSS_MEMORY_OFFSET; -#if 0 - printf("mem_map %x %d -> %x\n", addr, sz, *handle); -#endif + *handle = (bus_space_handle_t) + ((struct cross_softc *)bst->bs_data)->sc_zargs.va + 2 * addr; return 0; } int -cross_unmap(handle, sz) - bus_io_handle_t handle; - bus_io_size_t sz; -{ - return 0; -} - -__inline u_int8_t -cross_read_1(handle, addr) - bus_io_handle_t handle; - bus_io_size_t addr; -{ - u_int8_t val; - - /* generate A13-A19 for correct page */ - *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE; - val = *(volatile u_int8_t *)(handle + 2 * addr); - -#if 0 - printf("read_1 @%x handle %x -> %d\n", addr, handle, val); -#endif - return val; -} - -__inline u_int16_t -cross_read_2(handle, addr) - bus_io_handle_t handle; - bus_io_size_t addr; -{ - /* generate A13-A19 for correct page */ - *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE; - return *(volatile u_int16_t *)(handle + 2 * addr); -} - -void -cross_io_read_multi_1(handle, addr, buf, cnt) - bus_io_handle_t handle; - bus_io_size_t addr; - u_int8_t *buf; - bus_io_size_t cnt; -{ - while (cnt--) - *buf++ = cross_read_1(handle, addr); -} - -void -cross_io_read_multi_2(handle, addr, buf, cnt) - bus_io_handle_t handle; - bus_io_size_t addr; - u_int16_t *buf; - bus_io_size_t cnt; +cross_mem_map(bst, addr, sz, cacheable, handle) + bus_space_tag_t bst; + bus_addr_t addr; + bus_size_t sz; + int cacheable; + bus_space_handle_t *handle; { - while (cnt--) - *buf++ = cross_read_2(handle, addr); -} + bus_addr_t banked_start; + bus_size_t banked_size; + vm_object_t object; + vm_offset_t kva; + int error; -void -cross_io_read_raw_multi_2(handle, addr, buf, cnt) - bus_io_handle_t handle; - bus_io_size_t addr; - u_int8_t *buf; - bus_io_size_t cnt; -{ - u_int16_t *buf16 = (u_int16_t *)buf; + /* + * XXX When we do have a good enough extent-manager do extent + * checking here. + */ - while (cnt) { - cnt -= 2; - *buf16++ = swap(cross_read_2(handle, addr)); - } -} + /* + * Compute the bank range. Note that we need to shift bus-addresses + * and sizes left one bit. + */ + banked_start = (addr << 1) & ~(CROSS_BANK_SIZE - 1); + banked_size = ((sz << 1) + CROSS_BANK_SIZE - 1) & + ~(CROSS_BANK_SIZE - 1); -__inline void -cross_write_1(handle, addr, val) - bus_io_handle_t handle; - bus_io_size_t addr; - u_int8_t val; -{ - /* generate A13-A19 for correct page */ - *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE; -#if 0 - printf("write_1 @%x handle %x: %d\n", addr, handle, val); -#endif - *(volatile u_int8_t *)(handle + 2 * addr + 1) = val; -} + /* Create the object that will take care of the bankswitching. */ + object = vm_allocate_object(banked_size); + if (object == NULL) + goto fail_obj; + vm_object_setpager(object, cross_pager, 0, 0); -__inline void -cross_write_2(handle, addr, val) - bus_io_handle_t handle; - bus_io_size_t addr; - u_int16_t val; -{ - /* generate A13-A19 for correct page */ - *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE; - *(volatile u_int16_t *)(handle + 2 * addr) = val; -} + /* + * When done like this double mappings will be possible, thus + * wasting a little mapping space. This happens when several + * bus_space_map maps stuff from the same bank. But I don't care. + */ + kva = kmem_alloc_pageable(kernel_map, banked_size); + if (kva == 0) + goto fail_alloc; + vm_map_lock(kernel_map); + error = vm_map_insert(kernel_map, object, 0, kva, kva + banked_size); + vm_map_unlock(kernel_map); + if (error != KERN_SUCCESS) + goto fail_insert; + + /* Tell caller where to find his data. */ + *handle = (bus_space_handle_t)(kva + (addr << 1) - banked_addr)); + return 0; -void -cross_io_write_multi_1(handle, addr, buf, cnt) - bus_io_handle_t handle; - bus_io_size_t addr; - const u_int8_t *buf; - bus_io_size_t cnt; -{ - while (cnt--) - cross_write_1(handle, addr, *buf++); +fail_insert: + kmem_free(kernel_map, kva, banked_size); +fail_alloc: + vm_object_deallocate(object); +fail_obj: + return -1; } -void -cross_io_write_multi_2(handle, addr, buf, cnt) - bus_io_handle_t handle; - bus_io_size_t addr; - const u_int16_t *buf; - bus_io_size_t cnt; +int +cross_io_unmap(bst, handle, sz) + bus_space_tag_t bst; + bus_space_handle_t handle; + bus_size_t sz; { - while (cnt--) - cross_write_2(handle, addr, *buf++); + return 0; } -void -cross_io_write_raw_multi_2(handle, addr, buf, cnt) - bus_io_handle_t handle; - bus_io_size_t addr; - const u_int8_t *buf; - bus_io_size_t cnt; +int +cross_mem_unmap(bst, handle, sz) + bus_space_tag_t bst; + bus_space_handle_t handle; + bus_size_t sz; { - const u_int16_t *buf16 = (const u_int16_t *)buf; - - while (cnt) { - cnt -= 2; - cross_write_2(handle, addr, swap(*buf16++)); - } + /* Remove traphandler */ + return 0; } static cross_int_map[] = { @@ -501,10 +397,37 @@ cross_intr_disestablish(ic, arg) sc->sc_intrsharetype[irq] = IST_NONE; } -/* Swap bytes in a short word. */ -static u_short -swap(u_short x) +int +cross_pager_get_pages(pager, mlist, npages, sync) + vm_pager_t pager; + vm_page_t *mlist; + int npages; + boolean_t sync; { - __asm("rolw #8,%0" : "=r" (x) : "0" (x)); - return x; + int i; + vm_object_t object, old_object; + vm_offset_t offset; + + while(npages--) { + i = ((*mlist)->offset & (CROSS_BANK_SIZE - 1)) / NBPG; + object = (*mlist)->object; + old_object = sc->sc_page[i].offset; + offset = (*mlist)->offset; + vm_page_lock_queues(); + vm_object_lock(object); + if (old_object) + vm_object_lock(old_object); + vm_page_free(*mlist); + + /* generate A13-A19 for correct page */ + *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE; + + vm_page_rename(sc->sc_page[i], object, offset); + if (old_object) + vm_object_unlock(old_object); + vm_object_unlock(object); + vm_page_unlock_queues(); + mlist++: + } + return VM_PAGER_OK; } |