Added common sun68k autoconfiguration and bus_space
related code. Currently used by sun2.
This commit is contained in:
parent
2de3233da6
commit
5d81b8d269
461
sys/arch/sun68k/sun68k/autoconf.c
Normal file
461
sys/arch/sun68k/sun68k/autoconf.c
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
/* $NetBSD: autoconf.c,v 1.1 2001/06/27 02:48:32 fredette Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Adam Glass, Gordon W. Ross, and Matthew Fredette.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the NetBSD
|
||||||
|
* Foundation, Inc. and its contributors.
|
||||||
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the system to run on the current machine.
|
||||||
|
*
|
||||||
|
* Configure() is called at boot time. Available devices are
|
||||||
|
* determined (from possibilities mentioned in ioconf.c), and
|
||||||
|
* the drivers are initialized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opt_kgdb.h"
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
|
#include <sys/device.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
|
|
||||||
|
#include <dev/scsipi/scsi_all.h>
|
||||||
|
#include <dev/scsipi/scsipi_all.h>
|
||||||
|
#include <dev/scsipi/scsiconf.h>
|
||||||
|
|
||||||
|
#include <machine/autoconf.h>
|
||||||
|
#include <machine/intr.h>
|
||||||
|
#include <machine/promlib.h>
|
||||||
|
|
||||||
|
#ifdef KGDB
|
||||||
|
#include <sys/kgdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do general device autoconfiguration,
|
||||||
|
* then choose root device (etc.)
|
||||||
|
* Called by machdep.c: cpu_startup()
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_configure()
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Consider stopping for a debugger before
|
||||||
|
* autoconfiguration.
|
||||||
|
*/
|
||||||
|
if (boothowto & RB_KDB) {
|
||||||
|
#ifdef KGDB
|
||||||
|
/* XXX - Ask on console for kgdb_dev? */
|
||||||
|
/* Note: this will just return if kgdb_dev==NODEV */
|
||||||
|
kgdb_connect(1);
|
||||||
|
#else /* KGDB */
|
||||||
|
/* Either DDB or no debugger (just PROM). */
|
||||||
|
Debugger();
|
||||||
|
#endif /* KGDB */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install handlers for our "soft" interrupts.
|
||||||
|
* There might be a better place to do this?
|
||||||
|
*/
|
||||||
|
softintr_init();
|
||||||
|
|
||||||
|
/* General device autoconfiguration. */
|
||||||
|
if (config_rootfound("mainbus", NULL) == NULL)
|
||||||
|
panic("configure: mainbus not found");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that device autoconfiguration is finished,
|
||||||
|
* we can safely enable interrupts.
|
||||||
|
*/
|
||||||
|
printf("enabling interrupts\n");
|
||||||
|
(void)spl0();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mainbus_match __P((struct device *, struct cfdata *, void *));
|
||||||
|
static void mainbus_attach __P((struct device *, struct device *, void *));
|
||||||
|
|
||||||
|
struct cfattach mainbus_ca = {
|
||||||
|
sizeof(struct device), mainbus_match, mainbus_attach
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Probe for the mainbus; always succeeds.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mainbus_match(parent, cf, aux)
|
||||||
|
struct device *parent;
|
||||||
|
struct cfdata *cf;
|
||||||
|
void *aux;
|
||||||
|
{
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do "direct" configuration for the bus types on mainbus.
|
||||||
|
* This controls the order of autoconfig for important things
|
||||||
|
* used early. For example, idprom is used by Ether drivers.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mainbus_attach(parent, self, args)
|
||||||
|
struct device *parent;
|
||||||
|
struct device *self;
|
||||||
|
void *args;
|
||||||
|
{
|
||||||
|
extern struct sun68k_bus_dma_tag mainbus_dma_tag;
|
||||||
|
extern struct sun68k_bus_space_tag mainbus_space_tag;
|
||||||
|
|
||||||
|
struct mainbus_attach_args ma;
|
||||||
|
const char *const *cpp;
|
||||||
|
static const char *const special[] = {
|
||||||
|
/* find these first */
|
||||||
|
"obio",
|
||||||
|
"obmem",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
ma.ma_bustag = &mainbus_space_tag;
|
||||||
|
ma.ma_dmatag = &mainbus_dma_tag;
|
||||||
|
|
||||||
|
/* Find all `early' mainbus buses */
|
||||||
|
for (cpp = special; *cpp != NULL; cpp++) {
|
||||||
|
ma.ma_name = *cpp;
|
||||||
|
(void)config_found(self, &ma, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the remaining buses */
|
||||||
|
ma.ma_name = NULL;
|
||||||
|
(void) config_found(self, &ma, NULL);
|
||||||
|
|
||||||
|
/* Lastly, find the PROM console */
|
||||||
|
ma.ma_name = "pcons";
|
||||||
|
(void) config_found(self, &ma, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sun68k_bus_search:
|
||||||
|
* This function is passed to config_search() by the attach function
|
||||||
|
* for each of the "bus" drivers (obio, obmem, mbmem, vme, ...).
|
||||||
|
* The purpose of this function is to copy the "locators" into our
|
||||||
|
* _attach_args structure, so child drivers may use the _attach_args both
|
||||||
|
* as match parameters and as temporary storage for the defaulted
|
||||||
|
* locator values determined in the child_match and preserved for
|
||||||
|
* the child_attach function. If the bus attach functions just
|
||||||
|
* used config_found, then we would not have an opportunity to
|
||||||
|
* setup the _attach_args for each child match and attach call.
|
||||||
|
*/
|
||||||
|
int sun68k_bus_search(parent, cf, aux)
|
||||||
|
struct device *parent;
|
||||||
|
struct cfdata *cf;
|
||||||
|
void *aux;
|
||||||
|
{
|
||||||
|
struct mainbus_attach_args *map = aux;
|
||||||
|
struct mainbus_attach_args ma;
|
||||||
|
cfmatch_t mf;
|
||||||
|
|
||||||
|
/* Check whether we're looking for a specifically named device */
|
||||||
|
if (map->ma_name != NULL && strcmp(map->ma_name, cf->cf_driver->cd_name) != 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
if (cf->cf_fstate == FSTATE_STAR)
|
||||||
|
panic("bus_scan: FSTATE_STAR");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare to copy the locators into our _attach_args.
|
||||||
|
*/
|
||||||
|
ma = *map;
|
||||||
|
ma.ma_name = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Avoid entries which are missing attach information that
|
||||||
|
* they need, or that have attach information that they
|
||||||
|
* cannot have. The individual bus attach functions tell
|
||||||
|
* us this by initializing the locator fields in the attach
|
||||||
|
* args they provide us.
|
||||||
|
*
|
||||||
|
* At the same time we copy these values into the _attach_args
|
||||||
|
* will pass to the device's match and attach functions.
|
||||||
|
*/
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
#define BAD_LOCATOR(ma_loc, what) panic("sun68k_bus_search: %s %s for: %s%d\n", \
|
||||||
|
map-> ma_loc == LOCATOR_REQUIRED ? "missing" : "unexpected", \
|
||||||
|
what, cf->cf_driver->cd_name, cf->cf_unit)
|
||||||
|
#else
|
||||||
|
#define BAD_LOCATOR(ma_loc, what) return (0)
|
||||||
|
#endif
|
||||||
|
#define CHECK_LOCATOR(ma_loc, cf_loc, what) \
|
||||||
|
if ((map-> ma_loc == LOCATOR_FORBIDDEN && cf->cf_loc != -1) || \
|
||||||
|
(map-> ma_loc == LOCATOR_REQUIRED && cf->cf_loc == -1)) \
|
||||||
|
BAD_LOCATOR( ma_loc, what); \
|
||||||
|
else \
|
||||||
|
ma. ma_loc = cf->cf_loc
|
||||||
|
ma.ma_paddr = LOCATOR_REQUIRED;
|
||||||
|
CHECK_LOCATOR(ma_paddr, cf_paddr, "address");
|
||||||
|
CHECK_LOCATOR(ma_pri, cf_intpri, "ipl");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that this allows the match function to save
|
||||||
|
* defaulted locators in the _attach_args that will be
|
||||||
|
* preserved for the related attach call.
|
||||||
|
* XXX - This is a hack...
|
||||||
|
*/
|
||||||
|
mf = cf->cf_attach->ca_match;
|
||||||
|
if ((*mf)(parent, cf, &ma) > 0) {
|
||||||
|
config_attach(parent, cf, &ma, sun68k_bus_print);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sun68k_bus_print:
|
||||||
|
* Just print out the final (non-default) locators.
|
||||||
|
* The parent name is non-NULL when there was no match
|
||||||
|
* found by config_found().
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68k_bus_print(args, name)
|
||||||
|
void *args;
|
||||||
|
const char *name;
|
||||||
|
{
|
||||||
|
struct mainbus_attach_args *ma = args;
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
printf("%s:", name);
|
||||||
|
|
||||||
|
if (ma->ma_paddr != -1)
|
||||||
|
printf(" addr 0x%x", (unsigned int) ma->ma_paddr);
|
||||||
|
if (ma->ma_pri != -1)
|
||||||
|
printf(" ipl %d", ma->ma_pri);
|
||||||
|
|
||||||
|
return(UNCONF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
|
||||||
|
/* This takes the args: name, ctlr, unit */
|
||||||
|
typedef struct device * (*findfunc_t) __P((char *, int, int));
|
||||||
|
|
||||||
|
static struct device * find_dev_byname __P((char *));
|
||||||
|
static struct device * net_find __P((char *, int, int));
|
||||||
|
static struct device * scsi_find __P((char *, int, int));
|
||||||
|
static struct device * xx_find __P((char *, int, int));
|
||||||
|
|
||||||
|
struct prom_n2f {
|
||||||
|
const char name[4];
|
||||||
|
findfunc_t func;
|
||||||
|
};
|
||||||
|
static struct prom_n2f prom_dev_table[] = {
|
||||||
|
{ "ie", net_find },
|
||||||
|
{ "ec", net_find },
|
||||||
|
{ "le", net_find },
|
||||||
|
{ "sd", scsi_find },
|
||||||
|
{ "xy", xx_find },
|
||||||
|
{ "xd", xx_find },
|
||||||
|
{ "", 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This converts one hex number to an integer, and returns
|
||||||
|
* an updated string pointer.
|
||||||
|
*/
|
||||||
|
static const char *str2hex __P((const char *, int *));
|
||||||
|
static const char *
|
||||||
|
str2hex(p, _val)
|
||||||
|
const char *p;
|
||||||
|
int *_val;
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for(val = 0;; val = (val << 4) + c, p++) {
|
||||||
|
c = *((unsigned char *) p);
|
||||||
|
if (c >= 'a') c-= ('a' + 10);
|
||||||
|
else if (c >= 'A') c -= ('A' + 10);
|
||||||
|
else if (c >= '0') c -= '0';
|
||||||
|
if (c < 0 || c > 15) break;
|
||||||
|
}
|
||||||
|
*_val = val;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Choose root and swap devices.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_rootconf()
|
||||||
|
{
|
||||||
|
struct prom_n2f *nf;
|
||||||
|
struct device *boot_device;
|
||||||
|
int boot_partition;
|
||||||
|
char *devname;
|
||||||
|
findfunc_t find;
|
||||||
|
char promname[4];
|
||||||
|
char partname[4];
|
||||||
|
const char *prompath;
|
||||||
|
int prom_ctlr, prom_unit, prom_part;
|
||||||
|
|
||||||
|
/* Get the PROM boot path and take it apart. */
|
||||||
|
prompath = prom_getbootpath();
|
||||||
|
if (prompath == NULL) prompath = "zz(0,0,0)";
|
||||||
|
promname[0] = *(prompath++);
|
||||||
|
promname[1] = *(prompath++);
|
||||||
|
promname[2] = '\0';
|
||||||
|
prom_ctlr = prom_unit = prom_part = 0;
|
||||||
|
if (*prompath == '(' &&
|
||||||
|
*(prompath = str2hex(++prompath, &prom_ctlr)) == ',' &&
|
||||||
|
*(prompath = str2hex(++prompath, &prom_unit)) == ',')
|
||||||
|
(void) str2hex(++prompath, &prom_part);
|
||||||
|
|
||||||
|
/* Default to "unknown" */
|
||||||
|
boot_device = NULL;
|
||||||
|
boot_partition = 0;
|
||||||
|
devname = "<unknown>";
|
||||||
|
partname[0] = '\0';
|
||||||
|
find = NULL;
|
||||||
|
|
||||||
|
/* Do we know anything about the PROM boot device? */
|
||||||
|
for (nf = prom_dev_table; nf->func; nf++)
|
||||||
|
if (!strcmp(nf->name, promname)) {
|
||||||
|
find = nf->func;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (find)
|
||||||
|
boot_device = (*find)(promname, prom_ctlr, prom_unit);
|
||||||
|
if (boot_device) {
|
||||||
|
devname = boot_device->dv_xname;
|
||||||
|
if (boot_device->dv_class == DV_DISK) {
|
||||||
|
boot_partition = prom_part & 7;
|
||||||
|
partname[0] = 'a' + boot_partition;
|
||||||
|
partname[1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("boot device: %s%s\n", devname, partname);
|
||||||
|
setroot(boot_device, boot_partition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions to find devices using PROM boot parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Network device: Just use controller number.
|
||||||
|
*/
|
||||||
|
static struct device *
|
||||||
|
net_find(name, ctlr, unit)
|
||||||
|
char *name;
|
||||||
|
int ctlr, unit;
|
||||||
|
{
|
||||||
|
char tname[16];
|
||||||
|
|
||||||
|
sprintf(tname, "%s%d", name, ctlr);
|
||||||
|
return (find_dev_byname(tname));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SCSI device: The controller number corresponds to the
|
||||||
|
* scsibus number, and the unit number is (targ*8 + LUN).
|
||||||
|
*/
|
||||||
|
static struct device *
|
||||||
|
scsi_find(name, ctlr, unit)
|
||||||
|
char *name;
|
||||||
|
int ctlr, unit;
|
||||||
|
{
|
||||||
|
struct device *scsibus;
|
||||||
|
struct scsibus_softc *sbsc;
|
||||||
|
struct scsipi_periph *periph;
|
||||||
|
int target, lun;
|
||||||
|
char tname[16];
|
||||||
|
|
||||||
|
sprintf(tname, "scsibus%d", ctlr);
|
||||||
|
scsibus = find_dev_byname(tname);
|
||||||
|
if (scsibus == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* Compute SCSI target/LUN from PROM unit. */
|
||||||
|
target = prom_sd_target((unit >> 3) & 7);
|
||||||
|
lun = unit & 7;
|
||||||
|
|
||||||
|
/* Find the device at this target/LUN */
|
||||||
|
sbsc = (struct scsibus_softc *)scsibus;
|
||||||
|
periph = sbsc->sc_channel->chan_periphs[target][lun];
|
||||||
|
if (periph == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
return (periph->periph_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Xylogics SMD disk: (xy, xd)
|
||||||
|
* Assume wired-in unit numbers for now...
|
||||||
|
*/
|
||||||
|
static struct device *
|
||||||
|
xx_find(name, ctlr, unit)
|
||||||
|
char *name;
|
||||||
|
int ctlr, unit;
|
||||||
|
{
|
||||||
|
int diskunit;
|
||||||
|
char tname[16];
|
||||||
|
|
||||||
|
diskunit = (ctlr * 2) + unit;
|
||||||
|
sprintf(tname, "%s%d", name, diskunit);
|
||||||
|
return (find_dev_byname(tname));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a device name, find its struct device
|
||||||
|
* XXX - Move this to some common file?
|
||||||
|
*/
|
||||||
|
static struct device *
|
||||||
|
find_dev_byname(name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
struct device *dv;
|
||||||
|
|
||||||
|
for (dv = alldevs.tqh_first; dv != NULL;
|
||||||
|
dv = dv->dv_list.tqe_next) {
|
||||||
|
if (!strcmp(dv->dv_xname, name)) {
|
||||||
|
return(dv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
829
sys/arch/sun68k/sun68k/bus.c
Normal file
829
sys/arch/sun68k/sun68k/bus.c
Normal file
@ -0,0 +1,829 @@
|
|||||||
|
/* $NetBSD: bus.c,v 1.1 2001/06/27 02:48:32 fredette Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001 Matthew Fredette.
|
||||||
|
* Copyright (c) 1994, 1995 Gordon W. Ross
|
||||||
|
* Copyright (c) 1993 Adam Glass
|
||||||
|
* Copyright (c) 1988 University of Utah.
|
||||||
|
* Copyright (c) 1982, 1986, 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* the Systems Programming Group of the University of Utah Computer
|
||||||
|
* Science Department.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* from: Utah Hdr: machdep.c 1.74 92/12/20
|
||||||
|
* from: @(#)machdep.c 8.10 (Berkeley) 4/20/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||||
|
* NASA Ames Research Center.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the NetBSD
|
||||||
|
* Foundation, Inc. and its contributors.
|
||||||
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Lawrence Berkeley Laboratory.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)machdep.c 8.6 (Berkeley) 1/14/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/map.h>
|
||||||
|
#include <sys/device.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/mbuf.h>
|
||||||
|
|
||||||
|
#include <uvm/uvm.h> /* XXX: not _extern ... need vm_map_create */
|
||||||
|
|
||||||
|
#include <machine/pte.h>
|
||||||
|
#define _SUN68K_BUS_DMA_PRIVATE
|
||||||
|
#include <machine/autoconf.h>
|
||||||
|
#include <machine/bus.h>
|
||||||
|
#include <machine/intr.h>
|
||||||
|
#include <machine/pmap.h>
|
||||||
|
|
||||||
|
#include <sun68k/sun68k/control.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for DMA map creation. May be called by bus-specific
|
||||||
|
* DMA map creation functions.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, flags, dmamp)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_size_t size;
|
||||||
|
int nsegments;
|
||||||
|
bus_size_t maxsegsz;
|
||||||
|
bus_size_t boundary;
|
||||||
|
int flags;
|
||||||
|
bus_dmamap_t *dmamp;
|
||||||
|
{
|
||||||
|
struct sun68k_bus_dmamap *map;
|
||||||
|
void *mapstore;
|
||||||
|
size_t mapsize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and initialize the DMA map. The end of the map
|
||||||
|
* is a variable-sized array of segments, so we allocate enough
|
||||||
|
* room for them in one shot.
|
||||||
|
*
|
||||||
|
* Note we don't preserve the WAITOK or NOWAIT flags. Preservation
|
||||||
|
* of ALLOCNOW notifies others that we've reserved these resources,
|
||||||
|
* and they are not to be freed.
|
||||||
|
*
|
||||||
|
* The bus_dmamap_t includes one bus_dma_segment_t, hence
|
||||||
|
* the (nsegments - 1).
|
||||||
|
*/
|
||||||
|
mapsize = sizeof(struct sun68k_bus_dmamap) +
|
||||||
|
(sizeof(bus_dma_segment_t) * (nsegments - 1));
|
||||||
|
if ((mapstore = malloc(mapsize, M_DMAMAP,
|
||||||
|
(flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
bzero(mapstore, mapsize);
|
||||||
|
map = (struct sun68k_bus_dmamap *)mapstore;
|
||||||
|
map->_dm_size = size;
|
||||||
|
map->_dm_segcnt = nsegments;
|
||||||
|
map->_dm_maxsegsz = maxsegsz;
|
||||||
|
map->_dm_boundary = boundary;
|
||||||
|
map->_dm_align = PAGE_SIZE;
|
||||||
|
map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
|
||||||
|
map->dm_mapsize = 0; /* no valid mappings */
|
||||||
|
map->dm_nsegs = 0;
|
||||||
|
|
||||||
|
*dmamp = map;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for DMA map destruction. May be called by bus-specific
|
||||||
|
* DMA map destruction functions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_bus_dmamap_destroy(t, map)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the handle contains a valid mapping, unload it.
|
||||||
|
*/
|
||||||
|
if (map->dm_mapsize != 0)
|
||||||
|
bus_dmamap_unload(t, map);
|
||||||
|
|
||||||
|
free(map, M_DMAMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for DMA-safe memory allocation. May be called
|
||||||
|
* by bus-specific DMA memory allocation functions.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_bus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_size_t size, alignment, boundary;
|
||||||
|
bus_dma_segment_t *segs;
|
||||||
|
int nsegs;
|
||||||
|
int *rsegs;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
vaddr_t low, high;
|
||||||
|
struct pglist *mlist;
|
||||||
|
int error;
|
||||||
|
extern vm_offset_t avail_start;
|
||||||
|
extern vm_offset_t avail_end;
|
||||||
|
|
||||||
|
/* Always round the size. */
|
||||||
|
size = m68k_round_page(size);
|
||||||
|
low = avail_start;
|
||||||
|
high = avail_end;
|
||||||
|
|
||||||
|
if ((mlist = malloc(sizeof(*mlist), M_DEVBUF,
|
||||||
|
(flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate physical pages from the VM system.
|
||||||
|
*/
|
||||||
|
TAILQ_INIT(mlist);
|
||||||
|
error = uvm_pglistalloc(size, low, high, 0, 0,
|
||||||
|
mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simply keep a pointer around to the linked list, so
|
||||||
|
* bus_dmamap_free() can return it.
|
||||||
|
*
|
||||||
|
* NOBODY SHOULD TOUCH THE pageq FIELDS WHILE THESE PAGES
|
||||||
|
* ARE IN OUR CUSTODY.
|
||||||
|
*/
|
||||||
|
segs[0]._ds_mlist = mlist;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We now have physical pages, but no DVMA addresses yet. These
|
||||||
|
* will be allocated in bus_dmamap_load*() routines. Hence we
|
||||||
|
* save any alignment and boundary requirements in this dma
|
||||||
|
* segment.
|
||||||
|
*/
|
||||||
|
segs[0].ds_addr = 0;
|
||||||
|
segs[0].ds_len = 0;
|
||||||
|
segs[0]._ds_va = 0;
|
||||||
|
*rsegs = 1;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for freeing DMA-safe memory. May be called by
|
||||||
|
* bus-specific DMA memory free functions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_bus_dmamem_free(t, segs, nsegs)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dma_segment_t *segs;
|
||||||
|
int nsegs;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (nsegs != 1)
|
||||||
|
panic("bus_dmamem_free: nsegs = %d", nsegs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list of physical pages back to the VM system.
|
||||||
|
*/
|
||||||
|
uvm_pglistfree(segs[0]._ds_mlist);
|
||||||
|
free(segs[0]._ds_mlist, M_DEVBUF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for mapping DMA-safe memory. May be called by
|
||||||
|
* bus-specific DMA memory map functions.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_bus_dmamem_map(t, segs, nsegs, size, kvap, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dma_segment_t *segs;
|
||||||
|
int nsegs;
|
||||||
|
size_t size;
|
||||||
|
caddr_t *kvap;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
vm_page_t m;
|
||||||
|
vaddr_t va;
|
||||||
|
struct pglist *mlist;
|
||||||
|
|
||||||
|
if (nsegs != 1)
|
||||||
|
panic("_bus_dmamem_map: nsegs = %d", nsegs);
|
||||||
|
|
||||||
|
size = m68k_round_page(size);
|
||||||
|
|
||||||
|
va = uvm_km_valloc(kernel_map, size);
|
||||||
|
if (va == 0)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
segs[0]._ds_va = va;
|
||||||
|
*kvap = (caddr_t)va;
|
||||||
|
|
||||||
|
mlist = segs[0]._ds_mlist;
|
||||||
|
for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq)) {
|
||||||
|
paddr_t pa;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
panic("_bus_dmamem_map: size botch");
|
||||||
|
|
||||||
|
pa = VM_PAGE_TO_PHYS(m);
|
||||||
|
pmap_enter(pmap_kernel(), va, pa | PMAP_NC,
|
||||||
|
VM_PROT_READ | VM_PROT_WRITE,
|
||||||
|
VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
|
||||||
|
|
||||||
|
va += PAGE_SIZE;
|
||||||
|
size -= PAGE_SIZE;
|
||||||
|
}
|
||||||
|
pmap_update();
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for unmapping DMA-safe memory. May be called by
|
||||||
|
* bus-specific DMA memory unmapping functions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_bus_dmamem_unmap(t, kva, size)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
caddr_t kva;
|
||||||
|
size_t size;
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
if ((u_long)kva & PAGE_MASK)
|
||||||
|
panic("_bus_dmamem_unmap");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size = m68k_round_page(size);
|
||||||
|
uvm_unmap(kernel_map, (vaddr_t)kva, (vaddr_t)kva + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common functin for mmap(2)'ing DMA-safe memory. May be called by
|
||||||
|
* bus-specific DMA mmap(2)'ing functions.
|
||||||
|
*/
|
||||||
|
paddr_t
|
||||||
|
_bus_dmamem_mmap(t, segs, nsegs, off, prot, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dma_segment_t *segs;
|
||||||
|
int nsegs;
|
||||||
|
off_t off;
|
||||||
|
int prot, flags;
|
||||||
|
{
|
||||||
|
|
||||||
|
panic("_bus_dmamem_mmap: not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility to allocate an aligned kernel virtual address range
|
||||||
|
*/
|
||||||
|
vaddr_t
|
||||||
|
_bus_dma_valloc_skewed(size, boundary, align, skew)
|
||||||
|
size_t size;
|
||||||
|
u_long boundary;
|
||||||
|
u_long align;
|
||||||
|
u_long skew;
|
||||||
|
{
|
||||||
|
size_t oversize;
|
||||||
|
vaddr_t va, sva;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a region of kernel virtual addresses that is aligned
|
||||||
|
* to the given address modulo the requested alignment, i.e.
|
||||||
|
*
|
||||||
|
* (va - skew) == 0 mod align
|
||||||
|
*
|
||||||
|
* The following conditions apply to the arguments:
|
||||||
|
*
|
||||||
|
* - `size' must be a multiple of the VM page size
|
||||||
|
* - `align' must be a power of two
|
||||||
|
* and greater than or equal to the VM page size
|
||||||
|
* - `skew' must be smaller than `align'
|
||||||
|
* - `size' must be smaller than `boundary'
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
if ((size & PAGE_MASK) != 0)
|
||||||
|
panic("_bus_dma_valloc_skewed: invalid size %lx", (unsigned long) size);
|
||||||
|
if ((align & PAGE_MASK) != 0)
|
||||||
|
panic("_bus_dma_valloc_skewed: invalid alignment %lx", align);
|
||||||
|
if (align < skew)
|
||||||
|
panic("_bus_dma_valloc_skewed: align %lx < skew %lx",
|
||||||
|
align, skew);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* XXX - Implement this! */
|
||||||
|
if (boundary)
|
||||||
|
panic("_bus_dma_valloc_skewed: not implemented");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First, find a region large enough to contain any aligned chunk
|
||||||
|
*/
|
||||||
|
oversize = size + align - PAGE_SIZE;
|
||||||
|
sva = uvm_km_valloc(kernel_map, oversize);
|
||||||
|
if (sva == 0)
|
||||||
|
return (ENOMEM);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute start of aligned region
|
||||||
|
*/
|
||||||
|
va = sva;
|
||||||
|
va += (skew + align - va) & (align - 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return excess virtual addresses
|
||||||
|
*/
|
||||||
|
if (va != sva)
|
||||||
|
(void)uvm_unmap(kernel_map, sva, va);
|
||||||
|
if (va + size != sva + oversize)
|
||||||
|
(void)uvm_unmap(kernel_map, va + size, sva + oversize);
|
||||||
|
|
||||||
|
return (va);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like _bus_dmamap_load(), but for mbufs.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_bus_dmamap_load_mbuf(t, map, m, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
struct mbuf *m;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
|
||||||
|
panic("_bus_dmamap_load_mbuf: not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like _bus_dmamap_load(), but for uios.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_bus_dmamap_load_uio(t, map, uio, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
struct uio *uio;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
|
||||||
|
panic("_bus_dmamap_load_uio: not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common function for DMA map synchronization. May be called
|
||||||
|
* by bus-specific DMA map synchronization functions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_bus_dmamap_sync(t, map, offset, len, ops)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
bus_addr_t offset;
|
||||||
|
bus_size_t len;
|
||||||
|
int ops;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sun68k_bus_dma_tag mainbus_dma_tag = {
|
||||||
|
NULL,
|
||||||
|
_bus_dmamap_create,
|
||||||
|
_bus_dmamap_destroy,
|
||||||
|
_bus_dmamap_load,
|
||||||
|
_bus_dmamap_load_mbuf,
|
||||||
|
_bus_dmamap_load_uio,
|
||||||
|
_bus_dmamap_load_raw,
|
||||||
|
_bus_dmamap_unload,
|
||||||
|
_bus_dmamap_sync,
|
||||||
|
|
||||||
|
_bus_dmamem_alloc,
|
||||||
|
_bus_dmamem_free,
|
||||||
|
_bus_dmamem_map,
|
||||||
|
_bus_dmamem_unmap,
|
||||||
|
_bus_dmamem_mmap
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base bus space handlers.
|
||||||
|
*/
|
||||||
|
int sun68k_find_prom_map __P(( bus_addr_t, bus_type_t,
|
||||||
|
int, bus_space_handle_t *));
|
||||||
|
static int sun68k_bus_map __P(( bus_space_tag_t, bus_type_t, bus_addr_t,
|
||||||
|
bus_size_t, int, vaddr_t,
|
||||||
|
bus_space_handle_t *));
|
||||||
|
static int sun68k_bus_unmap __P((bus_space_tag_t, bus_space_handle_t,
|
||||||
|
bus_size_t));
|
||||||
|
static int sun68k_bus_subregion __P((bus_space_tag_t, bus_space_handle_t,
|
||||||
|
bus_size_t, bus_size_t,
|
||||||
|
bus_space_handle_t *));
|
||||||
|
static int sun68k_bus_mmap __P((bus_space_tag_t, bus_type_t,
|
||||||
|
bus_addr_t, int, bus_space_handle_t *));
|
||||||
|
static void *sun68k_mainbus_intr_establish __P((bus_space_tag_t, int, int,
|
||||||
|
int, int (*) __P((void *)),
|
||||||
|
void *));
|
||||||
|
static void sun68k_bus_barrier __P(( bus_space_tag_t, bus_space_handle_t,
|
||||||
|
bus_size_t, bus_size_t, int));
|
||||||
|
static int sun68k_bus_peek __P(( bus_space_tag_t, bus_space_handle_t,
|
||||||
|
bus_size_t, size_t, void *));
|
||||||
|
static int sun68k_bus_poke __P(( bus_space_tag_t, bus_space_handle_t,
|
||||||
|
bus_size_t, size_t, u_int32_t));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we can find a mapping that was established by the PROM, use it.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68k_find_prom_map(pa, iospace, len, hp)
|
||||||
|
bus_addr_t pa;
|
||||||
|
bus_type_t iospace;
|
||||||
|
int len;
|
||||||
|
bus_space_handle_t *hp;
|
||||||
|
{
|
||||||
|
u_long pf;
|
||||||
|
int pgtype;
|
||||||
|
u_long va, eva;
|
||||||
|
int sme;
|
||||||
|
u_long pte;
|
||||||
|
int saved_ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The mapping must fit entirely within one page.
|
||||||
|
*/
|
||||||
|
if ((((u_long)pa & PGOFSET) + len) > NBPG)
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
|
pf = PA_PGNUM(pa);
|
||||||
|
pgtype = iospace << PG_MOD_SHIFT;
|
||||||
|
saved_ctx = kernel_context();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk the PROM address space, looking for a page with the
|
||||||
|
* mapping we want.
|
||||||
|
*/
|
||||||
|
for (va = SUN_MONSTART; va < SUN_MONEND; ) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure this segment is mapped.
|
||||||
|
*/
|
||||||
|
sme = get_segmap(va);
|
||||||
|
if (sme == SEGINV) {
|
||||||
|
va += NBSG;
|
||||||
|
continue; /* next segment */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk the pages of this segment.
|
||||||
|
*/
|
||||||
|
for(eva = va + NBSG; va < eva; va += NBPG) {
|
||||||
|
pte = get_pte(va);
|
||||||
|
|
||||||
|
if ((pte & (PG_VALID | PG_TYPE)) ==
|
||||||
|
(PG_VALID | pgtype) &&
|
||||||
|
PG_PFNUM(pte) == pf)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Found the PROM mapping.
|
||||||
|
* note: preserve page offset
|
||||||
|
*/
|
||||||
|
*hp = (bus_space_handle_t)(va | ((u_long)pa & PGOFSET));
|
||||||
|
restore_context(saved_ctx);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
restore_context(saved_ctx);
|
||||||
|
return (ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_bus_map(t, iospace, addr, size, flags, vaddr, hp)
|
||||||
|
bus_space_tag_t t;
|
||||||
|
bus_type_t iospace;
|
||||||
|
bus_addr_t addr;
|
||||||
|
bus_size_t size;
|
||||||
|
vaddr_t vaddr;
|
||||||
|
bus_space_handle_t *hp;
|
||||||
|
{
|
||||||
|
bus_size_t offset;
|
||||||
|
vaddr_t v;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we suspect there might be one, try to find
|
||||||
|
* and use a PROM mapping.
|
||||||
|
*/
|
||||||
|
if ((flags & _SUN68K_BUS_MAP_USE_PROM) != 0 &&
|
||||||
|
sun68k_find_prom_map(addr, iospace, size, hp) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust the user's request to be page-aligned.
|
||||||
|
*/
|
||||||
|
offset = addr & PGOFSET;
|
||||||
|
addr -= offset;
|
||||||
|
size += offset;
|
||||||
|
size = m68k_round_page(size);
|
||||||
|
if (size == 0) {
|
||||||
|
printf("sun68k_bus_map: zero size\n");
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get some kernel virtual address space. */
|
||||||
|
if (vaddr)
|
||||||
|
v = vaddr;
|
||||||
|
else
|
||||||
|
v = uvm_km_valloc_wait(kernel_map, size);
|
||||||
|
if (v == 0)
|
||||||
|
panic("sun68k_bus_map: no memory");
|
||||||
|
|
||||||
|
/* note: preserve page offset */
|
||||||
|
*hp = (bus_space_handle_t)(v | offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map the device.
|
||||||
|
*/
|
||||||
|
addr |= iospace | PMAP_NC;
|
||||||
|
pmap_map(v, addr, addr + size, VM_PROT_ALL);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_bus_unmap(t, bh, size)
|
||||||
|
bus_space_tag_t t;
|
||||||
|
bus_size_t size;
|
||||||
|
bus_space_handle_t bh;
|
||||||
|
{
|
||||||
|
bus_size_t offset;
|
||||||
|
vaddr_t va = (vaddr_t)bh;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust the user's request to be page-aligned.
|
||||||
|
*/
|
||||||
|
offset = va & PGOFSET;
|
||||||
|
va -= offset;
|
||||||
|
size += offset;
|
||||||
|
size = m68k_round_page(size);
|
||||||
|
if (size == 0) {
|
||||||
|
printf("sun68k_bus_unmap: zero size\n");
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any part of the request is in the PROM's address space,
|
||||||
|
* don't unmap it.
|
||||||
|
*/
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
if ((va >= SUN_MONSTART && va < SUN_MONEND) !=
|
||||||
|
((va + size) >= SUN_MONSTART && (va + size) < SUN_MONEND))
|
||||||
|
panic("sun_bus_unmap: bad PROM mapping\n");
|
||||||
|
#endif
|
||||||
|
if (va >= SUN_MONSTART && va < SUN_MONEND)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
uvm_km_free_wakeup(kernel_map, va, size);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_bus_subregion(tag, handle, offset, size, nhandlep)
|
||||||
|
bus_space_tag_t tag;
|
||||||
|
bus_space_handle_t handle;
|
||||||
|
bus_size_t offset;
|
||||||
|
bus_size_t size;
|
||||||
|
bus_space_handle_t *nhandlep;
|
||||||
|
{
|
||||||
|
*nhandlep = handle + offset;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_bus_mmap(t, iospace, paddr, flags, hp)
|
||||||
|
bus_space_tag_t t;
|
||||||
|
bus_type_t iospace;
|
||||||
|
bus_addr_t paddr;
|
||||||
|
int flags;
|
||||||
|
bus_space_handle_t *hp;
|
||||||
|
{
|
||||||
|
*hp = (bus_space_handle_t)(paddr | iospace | PMAP_NC);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These assist in device probes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern label_t *nofault;
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_bus_peek(tag, handle, offset, size, vp)
|
||||||
|
bus_space_tag_t tag;
|
||||||
|
bus_space_handle_t handle;
|
||||||
|
bus_size_t offset;
|
||||||
|
size_t size;
|
||||||
|
void *vp;
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
label_t faultbuf;
|
||||||
|
u_int32_t junk;
|
||||||
|
|
||||||
|
if (vp == NULL)
|
||||||
|
vp = &junk;
|
||||||
|
|
||||||
|
nofault = &faultbuf;
|
||||||
|
if (setjmp(&faultbuf))
|
||||||
|
result = -1;
|
||||||
|
else {
|
||||||
|
switch(size) {
|
||||||
|
case 1:
|
||||||
|
*((u_int8_t *) vp) = bus_space_read_1(tag, handle, offset);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*((u_int16_t *) vp) = bus_space_read_2(tag, handle, offset);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*((u_int32_t *) vp) = bus_space_read_4(tag, handle, offset);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("_bus_space_peek: bad size\n");
|
||||||
|
}
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nofault = NULL;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_bus_poke(tag, handle, offset, size, v)
|
||||||
|
bus_space_tag_t tag;
|
||||||
|
bus_space_handle_t handle;
|
||||||
|
bus_size_t offset;
|
||||||
|
size_t size;
|
||||||
|
u_int32_t v;
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
label_t faultbuf;
|
||||||
|
|
||||||
|
nofault = &faultbuf;
|
||||||
|
if (setjmp(&faultbuf))
|
||||||
|
result = -1;
|
||||||
|
else {
|
||||||
|
switch(size) {
|
||||||
|
case 1:
|
||||||
|
bus_space_write_1(tag, handle, offset, (u_int8_t) v);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bus_space_write_2(tag, handle, offset, (u_int16_t) v);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
bus_space_write_4(tag, handle, offset, (u_int32_t) v);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("_bus_space_poke: bad size\n");
|
||||||
|
}
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nofault = NULL;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
sun68k_mainbus_intr_establish(t, pil, level, flags, handler, arg)
|
||||||
|
bus_space_tag_t t;
|
||||||
|
int pil;
|
||||||
|
int level;
|
||||||
|
int flags;
|
||||||
|
int (*handler)__P((void *));
|
||||||
|
void *arg;
|
||||||
|
{
|
||||||
|
isr_add_autovect(handler, arg, pil);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sun68k_bus_barrier (t, h, offset, size, flags)
|
||||||
|
bus_space_tag_t t;
|
||||||
|
bus_space_handle_t h;
|
||||||
|
bus_size_t offset;
|
||||||
|
bus_size_t size;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
/* No default barrier action defined */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sun68k_bus_space_tag mainbus_space_tag = {
|
||||||
|
NULL, /* cookie */
|
||||||
|
NULL, /* parent bus tag */
|
||||||
|
sun68k_bus_map, /* bus_space_map */
|
||||||
|
sun68k_bus_unmap, /* bus_space_unmap */
|
||||||
|
sun68k_bus_subregion, /* bus_space_subregion */
|
||||||
|
sun68k_bus_barrier, /* bus_space_barrier */
|
||||||
|
sun68k_bus_mmap, /* bus_space_mmap */
|
||||||
|
sun68k_mainbus_intr_establish, /* bus_intr_establish */
|
||||||
|
sun68k_bus_peek, /* bus_space_peek_N */
|
||||||
|
sun68k_bus_poke /* bus_space_poke_N */
|
||||||
|
};
|
362
sys/arch/sun68k/sun68k/isr.c
Normal file
362
sys/arch/sun68k/sun68k/isr.c
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
/* $NetBSD: isr.c,v 1.1 2001/06/27 02:48:32 fredette Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Adam Glass and Gordon W. Ross.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the NetBSD
|
||||||
|
* Foundation, Inc. and its contributors.
|
||||||
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This handles multiple attach of autovectored interrupts,
|
||||||
|
* and the handy software interrupt request register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/device.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/vmmeter.h>
|
||||||
|
|
||||||
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
|
#include <net/netisr.h>
|
||||||
|
|
||||||
|
#include <machine/autoconf.h>
|
||||||
|
#include <machine/cpu.h>
|
||||||
|
#include <machine/intr.h>
|
||||||
|
#include <machine/mon.h>
|
||||||
|
|
||||||
|
#include <sun68k/sun68k/vector.h>
|
||||||
|
|
||||||
|
extern int intrcnt[]; /* statistics */
|
||||||
|
|
||||||
|
#define NUM_LEVELS 8
|
||||||
|
|
||||||
|
struct isr {
|
||||||
|
struct isr *isr_next;
|
||||||
|
isr_func_t isr_intr;
|
||||||
|
void *isr_arg;
|
||||||
|
int isr_ipl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic soft interrupt support.
|
||||||
|
*/
|
||||||
|
struct softintr_head soft_level_heads[(_IPL_SOFT_LEVEL_MAX - _IPL_SOFT_LEVEL_MIN) + 1];
|
||||||
|
void *softnet_cookie;
|
||||||
|
static int softintr_handler __P((void *));
|
||||||
|
|
||||||
|
void set_vector_entry __P((int, void *));
|
||||||
|
void * get_vector_entry __P((int));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are called from locore. The "struct clockframe" arg
|
||||||
|
* is really just the normal H/W interrupt frame format.
|
||||||
|
* (kern_clock really wants it to be named that...)
|
||||||
|
*/
|
||||||
|
void isr_autovec __P((struct clockframe));
|
||||||
|
void isr_vectored __P((struct clockframe));
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
isr_add_custom(level, handler)
|
||||||
|
int level;
|
||||||
|
void *handler;
|
||||||
|
{
|
||||||
|
set_vector_entry(AUTOVEC_BASE + level, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* netisr junk...
|
||||||
|
* should use an array of chars instead of
|
||||||
|
* a bitmask to avoid atomicity locking issues.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void netintr()
|
||||||
|
{
|
||||||
|
int n, s;
|
||||||
|
|
||||||
|
s = splhigh();
|
||||||
|
n = netisr;
|
||||||
|
netisr = 0;
|
||||||
|
splx(s);
|
||||||
|
|
||||||
|
#define DONETISR(bit, fn) do { \
|
||||||
|
if (n & (1 << bit)) \
|
||||||
|
fn(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#include <net/netisr_dispatch.h>
|
||||||
|
|
||||||
|
#undef DONETISR
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct isr *isr_autovec_list[NUM_LEVELS];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called by the assembly routines
|
||||||
|
* for handling auto-vectored interupts.
|
||||||
|
*/
|
||||||
|
void isr_autovec(cf)
|
||||||
|
struct clockframe cf;
|
||||||
|
{
|
||||||
|
struct isr *isr;
|
||||||
|
register int n, ipl, vec;
|
||||||
|
|
||||||
|
vec = (cf.cf_vo & 0xFFF) >> 2;
|
||||||
|
if ((vec < AUTOVEC_BASE) || (vec >= (AUTOVEC_BASE+8)))
|
||||||
|
panic("isr_autovec: bad vec");
|
||||||
|
ipl = vec - AUTOVEC_BASE;
|
||||||
|
|
||||||
|
n = intrcnt[ipl];
|
||||||
|
intrcnt[ipl] = n+1;
|
||||||
|
uvmexp.intrs++;
|
||||||
|
|
||||||
|
isr = isr_autovec_list[ipl];
|
||||||
|
if (isr == NULL) {
|
||||||
|
if (n == 0)
|
||||||
|
printf("isr_autovec: ipl %d unexpected\n", ipl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give all the handlers a chance. */
|
||||||
|
n = 0;
|
||||||
|
while (isr) {
|
||||||
|
n |= isr->isr_intr(isr->isr_arg);
|
||||||
|
isr = isr->isr_next;
|
||||||
|
}
|
||||||
|
if (!n)
|
||||||
|
printf("isr_autovec: ipl %d not claimed\n", ipl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Establish an interrupt handler.
|
||||||
|
* Called by driver attach functions.
|
||||||
|
*/
|
||||||
|
void isr_add_autovect(handler, arg, level)
|
||||||
|
isr_func_t handler;
|
||||||
|
void *arg;
|
||||||
|
int level;
|
||||||
|
{
|
||||||
|
struct isr *new_isr;
|
||||||
|
|
||||||
|
if ((level < 0) || (level >= NUM_LEVELS))
|
||||||
|
panic("isr_add: bad level=%d", level);
|
||||||
|
new_isr = (struct isr *)
|
||||||
|
malloc(sizeof(struct isr), M_DEVBUF, M_NOWAIT);
|
||||||
|
if (!new_isr)
|
||||||
|
panic("isr_add: malloc failed");
|
||||||
|
|
||||||
|
new_isr->isr_intr = handler;
|
||||||
|
new_isr->isr_arg = arg;
|
||||||
|
new_isr->isr_ipl = level;
|
||||||
|
new_isr->isr_next = isr_autovec_list[level];
|
||||||
|
isr_autovec_list[level] = new_isr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vector_handler {
|
||||||
|
isr_func_t func;
|
||||||
|
void *arg;
|
||||||
|
};
|
||||||
|
static struct vector_handler isr_vector_handlers[192];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called by the assembly glue
|
||||||
|
* for handling vectored interupts.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
isr_vectored(cf)
|
||||||
|
struct clockframe cf;
|
||||||
|
{
|
||||||
|
struct vector_handler *vh;
|
||||||
|
register int ipl, vec;
|
||||||
|
|
||||||
|
vec = (cf.cf_vo & 0xFFF) >> 2;
|
||||||
|
ipl = _getsr();
|
||||||
|
ipl = (ipl >> 8) & 7;
|
||||||
|
|
||||||
|
intrcnt[ipl]++;
|
||||||
|
uvmexp.intrs++;
|
||||||
|
|
||||||
|
if (vec < 64 || vec >= 256) {
|
||||||
|
printf("isr_vectored: vector=0x%x (invalid)\n", vec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vh = &isr_vector_handlers[vec - 64];
|
||||||
|
if (vh->func == NULL) {
|
||||||
|
printf("isr_vectored: vector=0x%x (nul func)\n", vec);
|
||||||
|
set_vector_entry(vec, (void *)badtrap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, call the isr function. */
|
||||||
|
if (vh->func(vh->arg) == 0)
|
||||||
|
printf("isr_vectored: vector=0x%x (not claimed)\n", vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Establish an interrupt handler.
|
||||||
|
* Called by driver attach functions.
|
||||||
|
*/
|
||||||
|
extern void _isr_vectored __P((void));
|
||||||
|
void
|
||||||
|
isr_add_vectored(func, arg, level, vec)
|
||||||
|
isr_func_t func;
|
||||||
|
void *arg;
|
||||||
|
int level, vec;
|
||||||
|
{
|
||||||
|
struct vector_handler *vh;
|
||||||
|
|
||||||
|
if (vec < 64 || vec >= 256) {
|
||||||
|
printf("isr_add_vectored: vect=0x%x (invalid)\n", vec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vh = &isr_vector_handlers[vec - 64];
|
||||||
|
if (vh->func) {
|
||||||
|
printf("isr_add_vectored: vect=0x%x (in use)\n", vec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vh->func = func;
|
||||||
|
vh->arg = arg;
|
||||||
|
set_vector_entry(vec, (void *)_isr_vectored);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic soft interrupt support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The soft interrupt handler.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
softintr_handler(void *arg)
|
||||||
|
{
|
||||||
|
struct softintr_head *shd = arg;
|
||||||
|
struct softintr_handler *sh;
|
||||||
|
|
||||||
|
/* Clear the interrupt. */
|
||||||
|
isr_soft_clear(shd->shd_ipl);
|
||||||
|
uvmexp.softs++;
|
||||||
|
|
||||||
|
/* Dispatch any pending handlers. */
|
||||||
|
for(sh = LIST_FIRST(&shd->shd_intrs); sh != NULL; sh = LIST_NEXT(sh, sh_link)) {
|
||||||
|
if (sh->sh_pending) {
|
||||||
|
(*sh->sh_func)(sh->sh_arg);
|
||||||
|
sh->sh_pending = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This initializes soft interrupts.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
softintr_init(void)
|
||||||
|
{
|
||||||
|
int ipl;
|
||||||
|
struct softintr_head *shd;
|
||||||
|
|
||||||
|
for(ipl = _IPL_SOFT_LEVEL_MIN; ipl <= _IPL_SOFT_LEVEL_MAX; ipl++) {
|
||||||
|
shd = &soft_level_heads[ipl - _IPL_SOFT_LEVEL_MIN];
|
||||||
|
shd->shd_ipl = ipl;
|
||||||
|
LIST_INIT(&shd->shd_intrs);
|
||||||
|
isr_add_autovect(softintr_handler, shd, ipl);
|
||||||
|
}
|
||||||
|
|
||||||
|
softnet_cookie = softintr_establish(IPL_SOFTNET, (void (*) __P((void *))) netintr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This establishes a soft interrupt handler.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
softintr_establish(int ipl, void (*func)(void *), void *arg)
|
||||||
|
{
|
||||||
|
struct softintr_handler *sh;
|
||||||
|
struct softintr_head *shd;
|
||||||
|
|
||||||
|
if (ipl < _IPL_SOFT_LEVEL_MIN || ipl > _IPL_SOFT_LEVEL_MAX)
|
||||||
|
panic("softintr_establish: unsupported soft IPL");
|
||||||
|
|
||||||
|
shd = &soft_level_heads[ipl - _IPL_SOFT_LEVEL_MIN];
|
||||||
|
|
||||||
|
sh = malloc(sizeof(*sh), M_SOFTINTR, M_NOWAIT);
|
||||||
|
if (sh == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
LIST_INSERT_HEAD(&shd->shd_intrs, sh, sh_link);
|
||||||
|
sh->sh_head = shd;
|
||||||
|
sh->sh_pending = 0;
|
||||||
|
sh->sh_func = func;
|
||||||
|
sh->sh_arg = arg;
|
||||||
|
|
||||||
|
return sh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This disestablishes a soft interrupt handler.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
softintr_disestablish(void *arg)
|
||||||
|
{
|
||||||
|
struct softintr_handler *sh = arg;
|
||||||
|
LIST_REMOVE(sh, sh_link);
|
||||||
|
free(sh, M_SOFTINTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX - could just kill these...
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
set_vector_entry(entry, handler)
|
||||||
|
int entry;
|
||||||
|
void *handler;
|
||||||
|
{
|
||||||
|
if ((entry <0) || (entry >= NVECTORS))
|
||||||
|
panic("set_vector_entry: setting vector too high or low\n");
|
||||||
|
vector_table[entry] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
get_vector_entry(entry)
|
||||||
|
int entry;
|
||||||
|
{
|
||||||
|
if ((entry <0) || (entry >= NVECTORS))
|
||||||
|
panic("get_vector_entry: setting vector too high or low\n");
|
||||||
|
return ((void *) vector_table[entry]);
|
||||||
|
}
|
20
sys/arch/sun68k/sun68k/procfs_machdep.c
Normal file
20
sys/arch/sun68k/sun68k/procfs_machdep.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* $NetBSD: procfs_machdep.c,v 1.1 2001/06/27 02:48:32 fredette Exp $ */
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/vnode.h>
|
||||||
|
#include <miscfs/procfs/procfs.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linux-style /proc/cpuinfo.
|
||||||
|
* Only used when procfs is mounted with -o linux.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
procfs_getcpuinfstr(char *buf, int *len)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
423
sys/arch/sun68k/sun68k/vme_sun68k.c
Normal file
423
sys/arch/sun68k/sun68k/vme_sun68k.c
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
/* $NetBSD: vme_sun68k.c,v 1.1 2001/06/27 02:48:32 fredette Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Paul Kranenburg and Matthew Fredette.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the NetBSD
|
||||||
|
* Foundation, Inc. and its contributors.
|
||||||
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/extent.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/device.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syslog.h>
|
||||||
|
|
||||||
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
|
#define _SUN68K_BUS_DMA_PRIVATE
|
||||||
|
#include <machine/bus.h>
|
||||||
|
#include <machine/autoconf.h>
|
||||||
|
#include <machine/pmap.h>
|
||||||
|
#include <machine/dvma.h>
|
||||||
|
|
||||||
|
#include <dev/vme/vmereg.h>
|
||||||
|
#include <dev/vme/vmevar.h>
|
||||||
|
|
||||||
|
#include <sun68k/sun68k/vme_sun68k.h>
|
||||||
|
|
||||||
|
struct sun68kvme_softc {
|
||||||
|
struct device sc_dev; /* base device */
|
||||||
|
bus_space_tag_t sc_bustag;
|
||||||
|
bus_dma_tag_t sc_dmatag;
|
||||||
|
};
|
||||||
|
struct sun68kvme_softc *sun68kvme_sc;/*XXX*/
|
||||||
|
|
||||||
|
/* autoconfiguration driver */
|
||||||
|
static int sun68kvme_match __P((struct device *, struct cfdata *, void *));
|
||||||
|
static void sun68kvme_attach __P((struct device *, struct device *, void *));
|
||||||
|
|
||||||
|
static int sun68k_vme_probe __P((void *, vme_addr_t, vme_size_t,
|
||||||
|
vme_am_t, vme_datasize_t,
|
||||||
|
int (*) __P((void *, bus_space_tag_t, bus_space_handle_t)), void *));
|
||||||
|
static int sun68k_vme_map __P((void *, vme_addr_t, vme_size_t, vme_am_t,
|
||||||
|
vme_datasize_t, vme_swap_t,
|
||||||
|
bus_space_tag_t *, bus_space_handle_t *,
|
||||||
|
vme_mapresc_t *));
|
||||||
|
static void sun68k_vme_unmap __P((void *, vme_mapresc_t));
|
||||||
|
static int sun68k_vme_intr_map __P((void *, int, int, vme_intr_handle_t *));
|
||||||
|
static const struct evcnt *sun68k_vme_intr_evcnt __P((void *,
|
||||||
|
vme_intr_handle_t));
|
||||||
|
static void * sun68k_vme_intr_establish __P((void *, vme_intr_handle_t, int,
|
||||||
|
int (*) __P((void *)), void *));
|
||||||
|
static void sun68k_vme_intr_disestablish __P((void *, void *));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA functions.
|
||||||
|
*/
|
||||||
|
static void sun68k_vct_dmamap_destroy __P((void *, bus_dmamap_t));
|
||||||
|
|
||||||
|
static int sun68k_vct_dmamap_create __P((void *, vme_size_t, vme_am_t,
|
||||||
|
vme_datasize_t, vme_swap_t, int, vme_size_t, vme_addr_t,
|
||||||
|
int, bus_dmamap_t *));
|
||||||
|
static int sun68k_vme_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
|
||||||
|
bus_size_t, struct proc *, int));
|
||||||
|
static int sun68k_vme_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
|
||||||
|
bus_dma_segment_t *, int, bus_size_t, int));
|
||||||
|
|
||||||
|
int sun68k_vme_mmap_cookie __P((vme_addr_t, vme_am_t, bus_space_handle_t *));
|
||||||
|
|
||||||
|
struct cfattach sun68kvme_ca = {
|
||||||
|
sizeof(struct sun68kvme_softc), sun68kvme_match, sun68kvme_attach
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The VME bus logic on sun68k machines maps DMA requests in the first MB
|
||||||
|
* of VME space to the last MB of DVMA space. The base bus_dma code
|
||||||
|
* in machdep.c manages DVMA space; all we must do is adjust the DMA
|
||||||
|
* addresses returned by bus_dmamap_load*() by ANDing them with
|
||||||
|
* DVMA_VME_SLAVE_MASK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct vme_chipset_tag sun68k_vme_chipset_tag = {
|
||||||
|
NULL,
|
||||||
|
sun68k_vme_map,
|
||||||
|
sun68k_vme_unmap,
|
||||||
|
sun68k_vme_probe,
|
||||||
|
sun68k_vme_intr_map,
|
||||||
|
sun68k_vme_intr_evcnt,
|
||||||
|
sun68k_vme_intr_establish,
|
||||||
|
sun68k_vme_intr_disestablish,
|
||||||
|
sun68k_vct_dmamap_create,
|
||||||
|
sun68k_vct_dmamap_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sun68k_bus_dma_tag sun68k_vme_dma_tag;
|
||||||
|
|
||||||
|
/* Does this machine have a VME bus? */
|
||||||
|
extern int cpu_has_vme;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Probe the VME bus.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68kvme_match(parent, cf, aux)
|
||||||
|
struct device *parent;
|
||||||
|
struct cfdata *cf;
|
||||||
|
void *aux;
|
||||||
|
{
|
||||||
|
struct mainbus_attach_args *ma = aux;
|
||||||
|
|
||||||
|
return (cpu_has_vme && (ma->ma_name == NULL || strcmp(cf->cf_driver->cd_name, ma->ma_name) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach the VME bus.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sun68kvme_attach(parent, self, aux)
|
||||||
|
struct device *parent, *self;
|
||||||
|
void *aux;
|
||||||
|
{
|
||||||
|
struct mainbus_attach_args *ma = aux;
|
||||||
|
struct sun68kvme_softc *sc = (struct sun68kvme_softc *)self;
|
||||||
|
struct vmebus_attach_args vba;
|
||||||
|
|
||||||
|
if (self->dv_unit > 0) {
|
||||||
|
printf(" unsupported\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sun68kvme_sc = sc;
|
||||||
|
|
||||||
|
sc->sc_bustag = ma->ma_bustag;
|
||||||
|
sc->sc_dmatag = ma->ma_dmatag;
|
||||||
|
|
||||||
|
sun68k_vme_chipset_tag.cookie = self;
|
||||||
|
sun68k_vme_dma_tag = *ma->ma_dmatag;
|
||||||
|
sun68k_vme_dma_tag._cookie = self;
|
||||||
|
sun68k_vme_dma_tag._dmamap_load = sun68k_vme_dmamap_load;
|
||||||
|
sun68k_vme_dma_tag._dmamap_load_raw = sun68k_vme_dmamap_load_raw;
|
||||||
|
|
||||||
|
vba.va_vct = &sun68k_vme_chipset_tag;
|
||||||
|
vba.va_bdt = &sun68k_vme_dma_tag;
|
||||||
|
vba.va_slaveconfig = 0;
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
(void)config_found(self, &vba, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Probes for a device on the VME bus.
|
||||||
|
* Returns zero on success.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68k_vme_probe(cookie, addr, len, mod, datasize, callback, arg)
|
||||||
|
void *cookie;
|
||||||
|
vme_addr_t addr;
|
||||||
|
vme_size_t len;
|
||||||
|
vme_am_t mod;
|
||||||
|
vme_datasize_t datasize;
|
||||||
|
int (*callback) __P((void *, bus_space_tag_t, bus_space_handle_t));
|
||||||
|
void *arg;
|
||||||
|
{
|
||||||
|
struct sun68kvme_softc *sc = (struct sun68kvme_softc *)cookie;
|
||||||
|
bus_type_t iospace;
|
||||||
|
bus_addr_t paddr;
|
||||||
|
bus_space_handle_t handle;
|
||||||
|
bus_size_t size;
|
||||||
|
bus_size_t off, max_off;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
/* Map in the space. */
|
||||||
|
error = vmebus_translate(mod, addr, &iospace, &paddr);
|
||||||
|
if (error == 0)
|
||||||
|
error = bus_space_map2(sc->sc_bustag, iospace, paddr, len,
|
||||||
|
0, NULL, &handle);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
/* Probe the space. */
|
||||||
|
size = (datasize == VME_D8 ? 1 : (datasize == VME_D16 ? 2 : 4));
|
||||||
|
max_off = (callback ? size : len);
|
||||||
|
for (off = 0; off < max_off; off += size) {
|
||||||
|
error = _bus_space_peek(sc->sc_bustag, handle, off, size, NULL);
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (error == 0 && callback)
|
||||||
|
error = (*callback)(arg, sc->sc_bustag, handle);
|
||||||
|
|
||||||
|
/* Unmap the space. */
|
||||||
|
bus_space_unmap(sc->sc_bustag, handle, len);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maps in a device on the VME bus.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68k_vme_map(cookie, addr, size, mod, datasize, swap, tp, hp, rp)
|
||||||
|
void *cookie;
|
||||||
|
vme_addr_t addr;
|
||||||
|
vme_size_t size;
|
||||||
|
vme_am_t mod;
|
||||||
|
vme_datasize_t datasize;
|
||||||
|
vme_swap_t swap;
|
||||||
|
bus_space_tag_t *tp;
|
||||||
|
bus_space_handle_t *hp;
|
||||||
|
vme_mapresc_t *rp;
|
||||||
|
{
|
||||||
|
struct sun68kvme_softc *sc = (struct sun68kvme_softc *)cookie;
|
||||||
|
bus_type_t iospace;
|
||||||
|
bus_addr_t paddr;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = vmebus_translate(mod, addr, &iospace, &paddr);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
*tp = sc->sc_bustag;
|
||||||
|
return (bus_space_map2(sc->sc_bustag, iospace, paddr, size, 0, 0, hp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assists in mmap'ing a device on the VME bus.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68k_vme_mmap_cookie(addr, mod, hp)
|
||||||
|
vme_addr_t addr;
|
||||||
|
vme_am_t mod;
|
||||||
|
bus_space_handle_t *hp;
|
||||||
|
{
|
||||||
|
struct sun68kvme_softc *sc = sun68kvme_sc;
|
||||||
|
bus_type_t iospace;
|
||||||
|
bus_addr_t paddr;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = vmebus_translate(mod, addr, &iospace, &paddr);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
return (bus_space_mmap(sc->sc_bustag, iospace, paddr, 0, hp));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sun68k_vme_intr_handle {
|
||||||
|
int vec; /* VME interrupt vector */
|
||||||
|
int pri; /* VME interrupt priority */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This maps a VME interrupt level and vector pair into
|
||||||
|
* a data structure that can subsequently be used to
|
||||||
|
* establish an interrupt handler.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sun68k_vme_intr_map(cookie, level, vec, ihp)
|
||||||
|
void *cookie;
|
||||||
|
int level;
|
||||||
|
int vec;
|
||||||
|
vme_intr_handle_t *ihp;
|
||||||
|
{
|
||||||
|
struct sun68k_vme_intr_handle *svih;
|
||||||
|
|
||||||
|
svih = (vme_intr_handle_t)
|
||||||
|
malloc(sizeof(struct sun68k_vme_intr_handle), M_DEVBUF, M_NOWAIT);
|
||||||
|
svih->pri = level;
|
||||||
|
svih->vec = vec;
|
||||||
|
*ihp = svih;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct evcnt *
|
||||||
|
sun68k_vme_intr_evcnt(cookie, vih)
|
||||||
|
void *cookie;
|
||||||
|
vme_intr_handle_t vih;
|
||||||
|
{
|
||||||
|
|
||||||
|
/* XXX for now, no evcnt parent reported */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Establish a VME bus interrupt.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
sun68k_vme_intr_establish(cookie, vih, pri, func, arg)
|
||||||
|
void *cookie;
|
||||||
|
vme_intr_handle_t vih;
|
||||||
|
int pri;
|
||||||
|
int (*func) __P((void *));
|
||||||
|
void *arg;
|
||||||
|
{
|
||||||
|
struct sun68k_vme_intr_handle *svih =
|
||||||
|
(struct sun68k_vme_intr_handle *)vih;
|
||||||
|
|
||||||
|
/* Install interrupt handler. */
|
||||||
|
isr_add_vectored(func, (void *)arg,
|
||||||
|
svih->pri, svih->vec);
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sun68k_vme_unmap(cookie, resc)
|
||||||
|
void * cookie;
|
||||||
|
vme_mapresc_t resc;
|
||||||
|
{
|
||||||
|
/* Not implemented */
|
||||||
|
panic("sun68k_vme_unmap");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sun68k_vme_intr_disestablish(cookie, a)
|
||||||
|
void *cookie;
|
||||||
|
void *a;
|
||||||
|
{
|
||||||
|
/* Not implemented */
|
||||||
|
panic("sun68k_vme_intr_disestablish");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VME DMA functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sun68k_vct_dmamap_destroy(cookie, map)
|
||||||
|
void *cookie;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
{
|
||||||
|
struct sun68kvme_softc *sc = (struct sun68kvme_softc *)cookie;
|
||||||
|
bus_dmamap_destroy(sc->sc_dmatag, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sun68k_vct_dmamap_create(cookie, size, am, datasize, swap, nsegments, maxsegsz,
|
||||||
|
boundary, flags, dmamp)
|
||||||
|
void *cookie;
|
||||||
|
vme_size_t size;
|
||||||
|
vme_am_t am;
|
||||||
|
vme_datasize_t datasize;
|
||||||
|
vme_swap_t swap;
|
||||||
|
int nsegments;
|
||||||
|
vme_size_t maxsegsz;
|
||||||
|
vme_addr_t boundary;
|
||||||
|
int flags;
|
||||||
|
bus_dmamap_t *dmamp;
|
||||||
|
{
|
||||||
|
struct sun68kvme_softc *sc = (struct sun68kvme_softc *)cookie;
|
||||||
|
|
||||||
|
/* Allocate a base map through parent bus ops */
|
||||||
|
return (bus_dmamap_create(sc->sc_dmatag, size, nsegments, maxsegsz,
|
||||||
|
boundary, flags, dmamp));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_vme_dmamap_load(t, map, buf, buflen, p, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
void *buf;
|
||||||
|
bus_size_t buflen;
|
||||||
|
struct proc *p;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = _bus_dmamap_load(t, map, buf, buflen, p, flags);
|
||||||
|
if (error == 0)
|
||||||
|
map->dm_segs[0].ds_addr &= DVMA_VME_SLAVE_MASK;
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sun68k_vme_dmamap_load_raw(t, map, segs, nsegs, size, flags)
|
||||||
|
bus_dma_tag_t t;
|
||||||
|
bus_dmamap_t map;
|
||||||
|
bus_dma_segment_t *segs;
|
||||||
|
int nsegs;
|
||||||
|
bus_size_t size;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = _bus_dmamap_load_raw(t, map, segs, nsegs, size, flags);
|
||||||
|
if (error == 0)
|
||||||
|
map->dm_segs[0].ds_addr &= DVMA_VME_SLAVE_MASK;
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
41
sys/arch/sun68k/sun68k/vme_sun68k.h
Normal file
41
sys/arch/sun68k/sun68k/vme_sun68k.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* $NetBSD: vme_sun68k.h,v 1.1 2001/06/27 02:48:32 fredette Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Matt Fredette.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the NetBSD
|
||||||
|
* Foundation, Inc. and its contributors.
|
||||||
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int vmebus_translate __P((vme_am_t, vme_addr_t,
|
||||||
|
bus_type_t *, bus_addr_t *));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user