diff --git a/sys/arch/amiga/pci/empb.c b/sys/arch/amiga/pci/empb.c index 81c0baffa107..adc080b3d606 100644 --- a/sys/arch/amiga/pci/empb.c +++ b/sys/arch/amiga/pci/empb.c @@ -1,4 +1,4 @@ -/* $NetBSD: empb.c,v 1.4 2012/06/01 17:41:16 rkujawa Exp $ */ +/* $NetBSD: empb.c,v 1.5 2012/06/04 12:56:48 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -55,7 +55,7 @@ #include "opt_pci.h" -#define EMPB_DEBUG 1 +/* #define EMPB_DEBUG 1 */ #define PCI_CONF_LOCK(s) (s) = splhigh() #define PCI_CONF_UNLOCK(s) splx((s)) @@ -70,6 +70,7 @@ static void empb_callback(device_t self); static void empb_find_mem(struct empb_softc *sc); static void empb_switch_bridge(struct empb_softc *sc, uint8_t mode); +static void empb_intr_enable(struct empb_softc *sc); pcireg_t empb_pci_conf_read(pci_chipset_tag_t, pcitag_t, int); void empb_pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); @@ -84,6 +85,8 @@ int empb_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp); const struct evcnt * empb_pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih); +int empb_pci_conf_hook(pci_chipset_tag_t pct, int bus, + int dev, int func, pcireg_t id); CFATTACH_DECL_NEW(empb, sizeof(struct empb_softc), empb_match, empb_attach, NULL, NULL); @@ -181,6 +184,11 @@ empb_callback(device_t self) { sc->pci_confio_t = &(sc->pci_confio_area); + /* + * We should not map I/O space here, however we have no choice + * since these addresses are shared between configuration space and + * I/O space. Not really a problem on m68k, however on PPC... + */ if (bus_space_map(sc->pci_confio_t, 0, EMPB_BRIDGE_SIZE, 0, &sc->pci_confio_h)) aprint_error_dev(self, @@ -220,7 +228,7 @@ empb_callback(device_t self) { sc->apc.pc_intr_establish = amiga_pci_intr_establish; sc->apc.pc_intr_disestablish = amiga_pci_intr_disestablish; - sc->apc.pc_conf_hook = amiga_pci_conf_hook; + sc->apc.pc_conf_hook = empb_pci_conf_hook; sc->apc.pc_conf_interrupt = amiga_pci_conf_interrupt; sc->apc.cookie = sc; @@ -254,9 +262,18 @@ empb_callback(device_t self) { pba.pba_bus = 0; pba.pba_bridgetag = NULL; + empb_intr_enable(sc); + config_found_ia(self, "pcibus", &pba, pcibusprint); } +static void +empb_intr_enable(struct empb_softc *sc) +{ + bus_space_write_1(sc->setup_area_t, sc->setup_area_h, + EMPB_SETUP_INTR_OFF, EMPB_INTR_ENABLE); +} + /* * Switch between configuration space and I/O space. */ @@ -287,9 +304,9 @@ empb_find_mem(struct empb_softc *sc) mem_sc = device_private(memdev); sc->pci_mem_win.base = (bus_addr_t) mem_sc->sc_base; - sc->pci_mem_win.absm = &amiga_bus_stride_1; - + sc->pci_mem_win.absm = &empb_bus_swap; sc->pci_mem_win_size = mem_sc->sc_size; + sc->pci_mem_win_t = &sc->pci_mem_win; if(sc->pci_mem_win_size == 8*1024*1024) sc->pci_mem_win_mask = EMPB_WINDOW_MASK_8M; @@ -307,37 +324,39 @@ empb_find_mem(struct empb_softc *sc) } /* - * Switch memory window position. + * Switch memory window position. Return PCI mem address seen at the beginning + * of window. */ -void +bus_addr_t empb_switch_window(struct empb_softc *sc, bus_addr_t address) { int s; uint16_t win_reg; +#ifdef EMPB_DEBUG + uint16_t rwin_reg; +#endif /* EMPB_DEBUG */ WINDOW_LOCK(s); win_reg = bswap16((address >> EMPB_WINDOW_SHIFT) & sc->pci_mem_win_mask); -#ifdef EMPB_DEBUG - aprint_normal("empb: access to %p window switch to %x (@%p)\n", - (void*) address, win_reg, (void*) sc->setup_area_h); -#endif /* EMPB_DEBUG */ - bus_space_write_2(sc->setup_area_t, sc->setup_area_h, EMPB_SETUP_WINDOW_OFF, win_reg); /* store window pos, like: sc->pci_mem_win_pos = win_reg ? */ - win_reg = bus_space_read_2(sc->setup_area_t, sc->setup_area_h, +#ifdef EMPB_DEBUG + rwin_reg = bus_space_read_2(sc->setup_area_t, sc->setup_area_h, EMPB_SETUP_WINDOW_OFF); + aprint_normal("empb: access to %p window switch to %x => reg now %x\n", + (void*) address, win_reg, rwin_reg); +#endif /* EMPB_DEBUG */ + WINDOW_UNLOCK(s); -#ifdef EMPB_DEBUG - aprint_normal("empb: window reg now %x\n", win_reg); -#endif /* EMPB_DEBUG */ + return (bus_addr_t)((bswap16(win_reg)) << EMPB_WINDOW_SHIFT); } @@ -427,3 +446,18 @@ empb_pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih) return NULL; } +int +empb_pci_conf_hook(pci_chipset_tag_t pct, int bus, int dev, int func, + pcireg_t id) +{ + + /* + * Register information about some known PCI devices with + * DMA-able memory. + */ + /*if ((PCI_VENDOR(id) == PCI_VENDOR_3DFX) && + (PCI_PRODUCT(id) >= PCI_PRODUCT_3DFX_VOODOO3))*/ + + + return PCI_CONF_DEFAULT; +} diff --git a/sys/arch/amiga/pci/empb_bsm.c b/sys/arch/amiga/pci/empb_bsm.c index 0982d7334c00..7e7c727f8c57 100644 --- a/sys/arch/amiga/pci/empb_bsm.c +++ b/sys/arch/amiga/pci/empb_bsm.c @@ -1,4 +1,4 @@ -/* $NetBSD: empb_bsm.c,v 1.2 2012/06/01 17:41:16 rkujawa Exp $ */ +/* $NetBSD: empb_bsm.c,v 1.3 2012/06/04 12:56:48 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,9 @@ */ /* - * Special bus space methods handling PCI memory window. + * Special bus space methods handling PCI memory window. Used only by empb. + * + * XXX: Handle ops on window boundary! Currently these are broken! */ #include @@ -38,26 +40,759 @@ #include #include #include +#include #include #include #include +static bool empb_bsm_init(void); + /* -int + * The bus_space functions are prototyped below. Due to macro-ridden + * maddness of amiga port bus_space implementation, these prototypes look + * somewhat different than what you can read in bus_space(9) man page. + */ + +static int empb_bsm(bus_space_tag_t space, bus_addr_t address, + bus_size_t size, int flags, bus_space_handle_t *handlep); +static int empb_bsms(bus_space_handle_t handle, bus_size_t offset, + bus_size_t size, bus_space_handle_t *nhandlep); +static void empb_bsu(bus_space_handle_t handle, + bus_size_t size); + +static bsr(empb_bsr1, u_int8_t); +static bsw(empb_bsw1, u_int8_t); +static bsrm(empb_bsrm1, u_int8_t); +static bswm(empb_bswm1, u_int8_t); +static bsrm(empb_bsrr1, u_int8_t); +static bswm(empb_bswr1, u_int8_t); +static bssr(empb_bssr1, u_int8_t); +static bscr(empb_bscr1, u_int8_t); + +static bsr(empb_bsr2_swap, u_int16_t); +static bsw(empb_bsw2_swap, u_int16_t); +static bsr(empb_bsr2, u_int16_t); +static bsw(empb_bsw2, u_int16_t); +static bsrm(empb_bsrm2_swap, u_int16_t); +static bswm(empb_bswm2_swap, u_int16_t); +static bsrm(empb_bsrm2, u_int16_t); +static bswm(empb_bswm2, u_int16_t); +static bsrm(empb_bsrr2_swap, u_int16_t); +static bswm(empb_bswr2_swap, u_int16_t); +static bsrm(empb_bsrr2, u_int16_t); +static bswm(empb_bswr2, u_int16_t); +static bssr(empb_bssr2_swap, u_int16_t); +static bscr(empb_bscr2, u_int16_t); + +/*static bsr(empb_bsr4_swap, u_int32_t); +static bsw(empb_bsw4_swap, u_int32_t); +static bsr(empb_bsr4, u_int32_t); +static bsw(empb_bsw4, u_int32_t); +static bsrm(empb_bsrm4_swap, u_int32_t); +static bswm(empb_bswm4_swap, u_int32_t); +static bsrm(empb_bsrm4, u_int32_t); +static bswm(empb_bswm4, u_int32_t); +static bsrm(empb_bsrr4_swap, u_int32_t); +static bswm(empb_bswr4_swap, u_int32_t); +static bsrm(empb_bsrr4, u_int32_t); +static bswm(empb_bswr4, u_int32_t); +static bssr(empb_bssr4_swap, u_int32_t); +static bscr(empb_bscr4, u_int32_t);*/ +/* + * Hold pointer to bridge driver here. We need to access it to switch + * window position. Perhaps it should be stored in bus_space_tag instead... + */ +static struct empb_softc *empb_sc = NULL; + +static bool +empb_bsm_init(void) +{ + device_t dev; + + /* We can't have more than one Mediator anyway. */ + if (!(dev = device_find_by_xname("empb0"))) { + aprint_error("empb: can't find bridge device\n"); + return false; + } + + if (!(empb_sc = device_private(dev))) { + aprint_error_dev(dev, "can't obtain bridge softc\n"); + return false; + } + + if (empb_sc->pci_mem_win_size == 0) { + aprint_error_dev(dev, "no PCI memory window found\n"); + return false; + } + + return true; +} + +/* === common bus space methods === */ + +static int empb_bsm(bus_space_tag_t space, bus_addr_t address, bus_size_t size, - int flags, bus_space_handle_t *handlep); -int -empb_bsms(bus_space_tag_t space, bus_space_handle_t handle, - bus_size_t offset, bus_size_t size, bus_space_handle_t *nhandlep); + int flags, bus_space_handle_t *handlep) +{ + + /* Check for bridge driver softc. */ + if (empb_sc==NULL) + if(empb_bsm_init() == false) + return -1; + + /* Fail miserably if the driver wants linear space. */ + if (flags & BUS_SPACE_MAP_LINEAR) + { + aprint_error("empb: linear space mapping not possible\n"); + return -1; + } + + /* + * Just store the desired PCI bus address as handlep. Don't make things + * more complicated than they need to be. + */ + *handlep = address; + + return 0; +} + +static int +empb_bsms(bus_space_handle_t handle, + bus_size_t offset, bus_size_t size, bus_space_handle_t *nhandlep) +{ + *nhandlep = handle + offset; + return 0; +} + +static void +empb_bsu(bus_space_handle_t handle, bus_size_t size) +{ + return; +} + +/* === 8-bit methods === */ + +static uint8_t +empb_bsr1(bus_space_handle_t handle, bus_size_t offset) +{ + uint8_t *p; + uint8_t x; + bus_addr_t wp; /* window position */ + + wp = empb_switch_window(empb_sc, handle); + + /* window address + (PCI mem address - window position) */ + p = (uint8_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + x = *p; + + return x; +} + void -empb_bsu(bus_space_tag_t space, bus_space_handle_t handle, - bus_size_t size); -uint8_t -empb_bsr1(bus_space_tag_t space, bus_space_handle_t handle, - bus_size_t offset); +empb_bsw1(bus_space_handle_t handle, bus_size_t offset, unsigned value) +{ + uint8_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (uint8_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + *p = value; +} + +void +empb_bsrm1(bus_space_handle_t handle, bus_size_t offset, u_int8_t *pointer, + bus_size_t count) +{ + volatile uint8_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int8_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *pointer++ = *p; + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bswm1(bus_space_handle_t handle, bus_size_t offset, + const u_int8_t *pointer, bus_size_t count) +{ + volatile uint8_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int8_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = *pointer++; + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bsrr1(bus_space_handle_t handle, bus_size_t offset, u_int8_t *pointer, + bus_size_t count) +{ + volatile uint8_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int8_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *pointer++ = *p; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bswr1(bus_space_handle_t handle, bus_size_t offset, + const u_int8_t *pointer, bus_size_t count) +{ + volatile uint8_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int8_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = *pointer++; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bssr1(bus_space_handle_t handle, bus_size_t offset, unsigned value, + bus_size_t count) +{ + volatile uint8_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int8_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = value; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +/* XXX: this is broken, rewrite */ +void +empb_bscr1(bus_space_handle_t handlefrom, bus_size_t from, + bus_space_handle_t handleto, bus_size_t to, bus_size_t count) +{ + volatile uint8_t *p, *q; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handlefrom); + + p = (volatile u_int8_t *) + ( ((empb_sc->pci_mem_win_t->base)+(handlefrom - wp)) + from ); + q = (volatile u_int8_t *) + ( ((empb_sc->pci_mem_win_t->base)+(handleto - wp)) + to ); + + while (count > 0) { + *q = *p; + amiga_bus_reorder_protect(); + p ++; q++; + --count; + } +} + +/* === 16-bit methods === */ + +static uint16_t +empb_bsr2(bus_space_handle_t handle, bus_size_t offset) +{ + uint16_t *p; + uint16_t x; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + + p = (uint16_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + x = *p; + + return x; +} + +static uint16_t +empb_bsr2_swap(bus_space_handle_t handle, bus_size_t offset) +{ + uint16_t *p; + uint16_t x; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + + p = (uint16_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + x = *p; + + return bswap16(x); +} +void +empb_bsw2(bus_space_handle_t handle, bus_size_t offset, unsigned value) +{ + uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (uint16_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + *p = value; +} + +void +empb_bsw2_swap(bus_space_handle_t handle, bus_size_t offset, unsigned value) +{ + uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (uint16_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + *p = bswap16(value); +} + +void +empb_bsrm2(bus_space_handle_t handle, bus_size_t offset, u_int16_t *pointer, + bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *pointer++ = *p; + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bsrm2_swap(bus_space_handle_t handle, bus_size_t offset, + u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *pointer++ = bswap16(*p); + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bswm2(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *p = *pointer++; + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bswm2_swap(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *p = bswap16(*pointer++); + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bsrr2(bus_space_handle_t handle, bus_size_t offset, u_int16_t *pointer, + bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile uint16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *pointer++ = *p; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bsrr2_swap(bus_space_handle_t handle, bus_size_t offset, + u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile uint16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *pointer++ = bswap16(*p); + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bssr2_swap(bus_space_handle_t handle, bus_size_t offset, unsigned value, + bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile uint16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *p = bswap16(value); + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bswr2(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = *pointer++; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bswr2_swap(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = bswap16(*pointer++); + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +/* XXX: this is broken, rewrite, XXX 2: should we swap here? */ +void +empb_bscr2(bus_space_handle_t handlefrom, bus_size_t from, + bus_space_handle_t handleto, bus_size_t to, bus_size_t count) +{ + volatile uint16_t *p, *q; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handlefrom); + + p = (volatile uint16_t *) + ( ((empb_sc->pci_mem_win_t->base)+(handlefrom - wp)) + from ); + q = (volatile uint16_t *) + ( ((empb_sc->pci_mem_win_t->base)+(handleto - wp)) + to ); + + while (count > 0) { + *q = *p; + amiga_bus_reorder_protect(); + p++; q++; + --count; + } +} + +/* === 32-bit methods === */ +/* +static uint32_t +empb_bsr4(bus_space_handle_t handle, bus_size_t offset) +{ + uint32_t *p; + uint32_t x; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + + p = (uint32_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + x = *p; + + return x; +} + +static uint32_t +empb_bsr4_swap(bus_space_handle_t handle, bus_size_t offset) +{ + uint32_t *p; + uint32_t x; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + + p = (uint32_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + x = *p; + + return bswap32(x); +} + + +void +empb_bsw4(bus_space_handle_t handle, bus_size_t offset, unsigned value) +{ + uint32_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (uint16_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + *p = value; +} + +void +empb_bsw2_swap(bus_space_handle_t handle, bus_size_t offset, unsigned value) +{ + uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (uint16_t*)((empb_sc->pci_mem_win_t->base) + (handle - wp)); + *p = bswap16(value); +} + +void +empb_bsrm2(bus_space_handle_t handle, bus_size_t offset, u_int16_t *pointer, + bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *pointer++ = *p; + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bsrm2_swap(bus_space_handle_t handle, bus_size_t offset, + u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *pointer++ = bswap16(*p); + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bswm2(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *p = *pointer++; + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bswm2_swap(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *p = bswap16(*pointer++); + amiga_bus_reorder_protect(); + --count; + } +} + +void +empb_bsrr2(bus_space_handle_t handle, bus_size_t offset, u_int16_t *pointer, + bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile uint16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *pointer++ = *p; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bsrr2_swap(bus_space_handle_t handle, bus_size_t offset, + u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile uint16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *pointer++ = bswap16(*p); + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bssr2_swap(bus_space_handle_t handle, bus_size_t offset, unsigned value, + bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile uint16_t *) ((empb_sc->pci_mem_win_t->base) + + (handle - wp)); + + while (count > 0) { + *p = bswap16(value); + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bswr2(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = *pointer++; + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +void +empb_bswr2_swap(bus_space_handle_t handle, bus_size_t offset, + const u_int16_t *pointer, bus_size_t count) +{ + volatile uint16_t *p; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handle); + p = (volatile u_int16_t *)((empb_sc->pci_mem_win_t->base)+(handle - wp)); + + while (count > 0) { + *p = bswap16(*pointer++); + amiga_bus_reorder_protect(); + p++; + --count; + } +} + +// XXX: this is broken, rewrite, XXX 2: should we swap here? +void +empb_bscr2(bus_space_handle_t handlefrom, bus_size_t from, + bus_space_handle_t handleto, bus_size_t to, bus_size_t count) +{ + volatile uint16_t *p, *q; + bus_addr_t wp; + + wp = empb_switch_window(empb_sc, handlefrom); + + p = (volatile uint16_t *) + ( ((empb_sc->pci_mem_win_t->base)+(handlefrom - wp)) + from ); + q = (volatile uint16_t *) + ( ((empb_sc->pci_mem_win_t->base)+(handleto - wp)) + to ); + + while (count > 0) { + *q = *p; + amiga_bus_reorder_protect(); + p++; q++; + --count; + } +} */ +/* === end of implementation === */ const struct amiga_bus_space_methods empb_bus_swap = { @@ -67,6 +802,7 @@ const struct amiga_bus_space_methods empb_bus_swap = { .bsa = NULL, .bsf = NULL, + /* 8-bit methods */ .bsr1 = empb_bsr1, .bsw1 = empb_bsw1, .bsrm1 = empb_bsrm1, @@ -76,6 +812,7 @@ const struct amiga_bus_space_methods empb_bus_swap = { .bssr1 = empb_bssr1, .bscr1 = empb_bscr1, + /* 16-bit methods */ .bsr2 = empb_bsr2_swap, .bsw2 = empb_bsw2_swap, .bsrs2 = empb_bsr2, @@ -89,8 +826,9 @@ const struct amiga_bus_space_methods empb_bus_swap = { .bsrrs2 = empb_bsrr2, .bswrs2 = empb_bswr2, .bssr2 = empb_bssr2_swap, - .bscr2 = empb_bscr2_swap, + .bscr2 = empb_bscr2 /* + //32-bit methods .bsr4 = empb_bsr4_swap, .bsw4 = empb_bsw4_swap, .bsrs4 = empb_bsr4, @@ -104,7 +842,7 @@ const struct amiga_bus_space_methods empb_bus_swap = { .bsrrs4 = empb_bsrr4, .bswrs4 = empb_bswr4, .bssr4 = empb_bssr4_swap, - .bscr4 = empb_bscr4_swap + .bscr4 = empb_bscr4_swap */ }; -*/ + diff --git a/sys/arch/amiga/pci/empbreg.h b/sys/arch/amiga/pci/empbreg.h index 3e2e1c51affd..1b565bb6a5db 100644 --- a/sys/arch/amiga/pci/empbreg.h +++ b/sys/arch/amiga/pci/empbreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: empbreg.h,v 1.3 2012/06/01 17:41:17 rkujawa Exp $ */ +/* $NetBSD: empbreg.h,v 1.4 2012/06/04 12:56:49 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -68,6 +68,7 @@ #define EMPB_SETUP_WINDOW_OFF 0x2 /* set memory window position */ #define EMPB_SETUP_BRIDGE_OFF 0x7 /* select between conf or I/O */ +#define EMPB_SETUP_INTR_OFF 0xB /* interrupt setup */ #define BRIDGE_CONF 0xA0 /* switch into configuration space */ #define BRIDGE_IO 0x20 /* switch into I/O space */ @@ -78,6 +79,8 @@ #define EMPB_CONF_DEV_STRIDE 0x800 /* offset between PCI devices */ #define EMPB_CONF_FUNC_STRIDE 0x100 /* XXX: offset between PCI funcs */ +#define EMPB_INTR_ENABLE 0xFF /* enable all interrupts */ + #define EMPB_WINDOW_SHIFT 0x10 #define EMPB_WINDOW_MASK_8M 0xFF80 #define EMPB_WINDOW_MASK_4M 0xFFC0 diff --git a/sys/arch/amiga/pci/empbvar.h b/sys/arch/amiga/pci/empbvar.h index e830c999d8fb..3aa4eb4b0fc4 100644 --- a/sys/arch/amiga/pci/empbvar.h +++ b/sys/arch/amiga/pci/empbvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: empbvar.h,v 1.1 2012/06/01 09:41:35 rkujawa Exp $ */ +/* $NetBSD: empbvar.h,v 1.2 2012/06/04 12:56:49 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -39,6 +39,21 @@ #include +/* + * Structure used to describe PCI devices with memory that can be used as + * bounce buffers. XXX: not used yet. + */ +struct empb_dmamemdev_entry { + /* location of the device on bus */ + int bus; + int dev; + int function; + /* how to find memory on device */ + uint8_t bar; /* which BAR will be used to access the mem */ + uint32_t off; /* offset from BAR address */ + uint32_t size; /* how much memory will we steal */ +}; + struct empb_softc { device_t sc_dev; @@ -52,6 +67,7 @@ struct empb_softc { uint8_t pci_confio_mode; struct bus_space_tag pci_mem_win; + bus_space_tag_t pci_mem_win_t; uint32_t pci_mem_win_size; bus_addr_t pci_mem_win_pos; uint16_t pci_mem_win_mask; @@ -61,4 +77,5 @@ struct empb_softc { }; -void empb_switch_window(struct empb_softc *sc, bus_addr_t address); +bus_addr_t empb_switch_window(struct empb_softc *sc, bus_addr_t address); +