diff options
| author | rkujawa <rkujawa@NetBSD.org> | 2012-05-31 21:29:02 +0000 |
|---|---|---|
| committer | rkujawa <rkujawa@NetBSD.org> | 2012-05-31 21:29:02 +0000 |
| commit | 164d24d1de4fa09df4e0d6153fba96e2ce431bdd (patch) | |
| tree | 923ffce0091e0cd98203607353b08c39c8060161 /sys | |
| parent | 484c0c29515ddc28fde0e087dbf1a64bf135cfe4 (diff) | |
Add empb(4) functions to switch memory window position.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/amiga/pci/emmem.c | 4 | ||||
| -rw-r--r-- | sys/arch/amiga/pci/empb.c | 102 | ||||
| -rw-r--r-- | sys/arch/amiga/pci/empbreg.h | 6 |
3 files changed, 92 insertions, 20 deletions
diff --git a/sys/arch/amiga/pci/emmem.c b/sys/arch/amiga/pci/emmem.c index 34519320c83..c1cdf4e0ec8 100644 --- a/sys/arch/amiga/pci/emmem.c +++ b/sys/arch/amiga/pci/emmem.c @@ -1,4 +1,4 @@ -/* $NetBSD: emmem.c,v 1.1 2012/05/30 18:01:51 rkujawa Exp $ */ +/* $NetBSD: emmem.c,v 1.2 2012/05/31 21:29:02 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -90,7 +90,7 @@ emmem_attach(device_t parent, device_t self, void *aux) zap = aux; sc->sc_dev = self; - sc->sc_base = zap->pa; + sc->sc_base = zap->va; sc->sc_size = zap->size; aprint_normal(": ELBOX Mediator PCI memory window, %d kB\n", diff --git a/sys/arch/amiga/pci/empb.c b/sys/arch/amiga/pci/empb.c index 608bc189736..63db450ced6 100644 --- a/sys/arch/amiga/pci/empb.c +++ b/sys/arch/amiga/pci/empb.c @@ -1,4 +1,4 @@ -/* $NetBSD: empb.c,v 1.1 2012/05/30 18:01:51 rkujawa Exp $ */ +/* $NetBSD: empb.c,v 1.2 2012/05/31 21:29:02 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -58,11 +58,14 @@ #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)) +#define WINDOW_LOCK(s) (s) = splhigh() +#define WINDOW_UNLOCK(s) splx((s)) + struct empb_softc { device_t sc_dev; @@ -75,8 +78,10 @@ struct empb_softc { bus_space_handle_t pci_confio_h; uint8_t pci_confio_mode; - struct bus_space_tag pci_mem_window; - uint32_t pci_mem_window_size; + struct bus_space_tag pci_mem_win; + uint32_t pci_mem_win_size; + bus_addr_t pci_mem_win_pos; + uint16_t pci_mem_win_mask; struct amiga_pci_chipset apc; @@ -84,10 +89,12 @@ struct empb_softc { static int empb_match(struct device *, struct cfdata *, void *); static void empb_attach(struct device *, struct device *, void *); + static void empb_callback(device_t self); -/*static bool empb_find_mem(struct empb_softc *sc);*/ -void empb_switch_bridge(struct empb_softc *sc, uint8_t mode); +static void empb_find_mem(struct empb_softc *sc); +static void empb_switch_bridge(struct empb_softc *sc, uint8_t mode); +static void empb_switch_window(struct empb_softc *sc, bus_addr_t address); 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); @@ -211,6 +218,16 @@ empb_callback(device_t self) { aprint_error_dev(self, "couldn't map Mediator setup space\n"); + empb_find_mem(sc); + if (sc->pci_mem_win_size == 0) + aprint_error_dev(self, + "couldn't find memory space, check your WINDOW jumper\n"); + + /* just a test */ + empb_switch_window(sc, 0x80000000); + empb_switch_window(sc, 0x82F00000); + empb_switch_window(sc, 0x82000000); + /* Initialize the PCI chipset tag. */ sc->apc.pc_conf_v = (void*) pc; sc->apc.pc_bus_maxdevs = empb_pci_bus_maxdevs; @@ -236,10 +253,10 @@ empb_callback(device_t self) { pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_IO_OKAY; - /*if(sc->pci_mem_window_size > 0) { - pba.pba_memt = &(sc->pci_mem_window); + if(sc->pci_mem_win_size > 0) { + pba.pba_memt = &(sc->pci_mem_win); pba.pba_flags |= PCI_FLAGS_MEM_OKAY; - } else */ + } else pba.pba_memt = NULL; pba.pba_bus = 0; @@ -251,7 +268,7 @@ empb_callback(device_t self) { /* * Switch between configuration space and I/O space. */ -void +static void empb_switch_bridge(struct empb_softc *sc, uint8_t mode) { bus_space_write_1(sc->setup_area_t, sc->setup_area_h, @@ -262,24 +279,75 @@ empb_switch_bridge(struct empb_softc *sc, uint8_t mode) /* * Try to find a (optional) memory window board. */ -/*bool +static void empb_find_mem(struct empb_softc *sc) { device_t memdev; struct emmem_softc *mem_sc; memdev = device_find_by_xname("emmem0"); + sc->pci_mem_win_size = 0; - if(memdev == NULL) - return false; + if(memdev == NULL) { + return; + } mem_sc = device_private(memdev); - sc->pci_mem_window.base = (bus_addr_t) mem_sc->sc_base; - sc->pci_mem_window.absm = &amiga_bus_stride_1; + 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_size = mem_sc->sc_size; + + if(sc->pci_mem_win_size == 8*1024*1024) + sc->pci_mem_win_mask = EMPB_WINDOW_MASK_8M; + else if(sc->pci_mem_win_size == 4*1024*1024) + sc->pci_mem_win_mask = EMPB_WINDOW_MASK_4M; + else /* disable anyway */ + sc->pci_mem_win_size = 0; + +#ifdef EMPB_DEBUG + aprint_normal("empb: found %x b window at %p, switch mask %x\n", + sc->pci_mem_win_size, (void*) sc->pci_mem_win.base, + sc->pci_mem_win_mask); +#endif /* EMPB_DEBUG */ + +} + +/* + * Switch memory window position. + */ +static void +empb_switch_window(struct empb_softc *sc, bus_addr_t address) +{ + int s; + uint16_t win_reg; + + 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, + EMPB_SETUP_WINDOW_OFF); + + WINDOW_UNLOCK(s); + +#ifdef EMPB_DEBUG + aprint_normal("empb: window reg now %x\n", win_reg); +#endif /* EMPB_DEBUG */ +} - sc->pci_mem_window_size = mem_sc->sc_size; -}*/ pcireg_t empb_pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) diff --git a/sys/arch/amiga/pci/empbreg.h b/sys/arch/amiga/pci/empbreg.h index e0ae839cc5a..2ca9d2cb68a 100644 --- a/sys/arch/amiga/pci/empbreg.h +++ b/sys/arch/amiga/pci/empbreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: empbreg.h,v 1.1 2012/05/30 18:01:51 rkujawa Exp $ */ +/* $NetBSD: empbreg.h,v 1.2 2012/05/31 21:29:02 rkujawa Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -78,6 +78,10 @@ #define EMPB_CONF_DEV_STRIDE 0x800 /* offset between PCI devices */ #define EMPB_CONF_FUNC_STRIDE 0x100 /* XXX: offset between PCI funcs */ +#define EMPB_WINDOW_SHIFT 0x10 +#define EMPB_WINDOW_MASK_8M 0xFF80 +#define EMPB_WINDOW_MASK_4M 0xFFC0 + /* All PCI interrupt lines are wired to INT2? */ #define EMPB_INT 2 // XXX: wild guess |
