Fix PCI interrupt handling on empb. Also, continue work on memory accesses. Now empb is good enough to handle satalink!
This commit is contained in:
parent
4b38c823d2
commit
fca4069ffb
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <sys/bus.h>
|
||||
|
@ -38,26 +40,759 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <amiga/pci/empbreg.h>
|
||||
#include <amiga/pci/empbvar.h>
|
||||
#include <amiga/pci/emmemvar.h>
|
||||
|
||||
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 */
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <machine/pci_machdep.h>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue