port the openbsd central and fhc drivers, and the clock/zs attachments.

doesn't quite work yet, crashes when central_attach() calls
config_attach() (faulting address is 0xf8000000.)
This commit is contained in:
mrg 2011-07-29 08:37:36 +00:00
parent 311f859cdd
commit 39a57b1caa
12 changed files with 1072 additions and 13 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.141 2011/07/23 21:12:58 jakllsch Exp $
# $NetBSD: GENERIC,v 1.142 2011/07/29 08:37:37 mrg Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/sparc64/conf/std.sparc64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.141 $"
#ident "GENERIC-$Revision: 1.142 $"
maxusers 64
@ -240,11 +240,14 @@ sbus* at mainbus0 # SBus-based systems
psycho* at mainbus0 # PCI-based systems
schizo* at mainbus?
pyro* at mainbus?
central* at mainbus?
fhc* at mainbus?
pci* at psycho?
pci* at schizo?
pci* at pyro?
pci* at ppb?
ppb* at pci? # `APB' support.
ppb* at pci?
fhc* at central?
ebus* at mainbus0 # ebus devices
ebus* at pci? # ebus devices
# XXX 'puc's aren't really bridges, but there's no better place for them here
@ -266,6 +269,7 @@ lpt* at ebus? # parallel port
## Mostek clock found on sbus on Ultra-1,2 systems
## and found on ebus on Ultra-5 and other systems.
clock* at sbus? slot ? offset ?
clock* at fhc?
clock* at ebus?
## DS1287 compatible clock found on ebus on Netra X1 and other systems.
@ -279,7 +283,8 @@ timer* at mainbus0 # sun4c
## Zilog 8530 serial chips. Each has two-channels.
## zs0 is ttya and ttyb. zs1 is the keyboard and mouse.
zs* at sbus? slot ? offset ?
zstty* at zs? channel ? # ttya
zs* at fhc?
zstty* at zs? channel ? # ttys
kbd0 at zstty?
ms0 at zstty?

View File

@ -1,4 +1,4 @@
# $NetBSD: files.sparc64,v 1.133 2011/06/12 03:35:47 rmind Exp $
# $NetBSD: files.sparc64,v 1.134 2011/07/29 08:37:37 mrg Exp $
# @(#)files.sparc64 8.1 (Berkeley) 7/19/93
# sparc64-specific configuration info
@ -42,6 +42,19 @@ file arch/sparc64/dev/schizo.c schizo
file arch/sparc64/dev/pyro.c pyro
file arch/sparc64/dev/pci_machdep.c psycho | schizo | pyro
define central {}
device central: central
attach central at mainbus
file arch/sparc64/dev/central.c central
define fhc {}
device fhc: fhc
attach fhc at mainbus with fhc_mainbus
attach fhc at central with fhc_central
file arch/sparc64/dev/fhc.c fhc
file arch/sparc64/dev/fhc_central.c fhc_central
file arch/sparc64/dev/fhc_mainbus.c fhc_mainbus
# IOMMU is for both
file arch/sparc64/dev/iommu.c sbus | psycho | schizo | pyro
@ -56,6 +69,7 @@ file arch/sparc64/dev/ebus_mainbus.c ebus_mainbus
device clock: mk48txx
attach clock at sbus with mkclock_sbus
attach clock at ebus with mkclock_ebus
attach clock at fhc with mkclock_fhc
file arch/sparc64/dev/mkclock.c clock
device rtc: mc146818
@ -125,7 +139,7 @@ file arch/sparc64/sparc64/rbus_machdep.c cardbus
#
device zs {channel = -1}
attach zs at sbus
attach zs at sbus, fhc
file arch/sparc64/dev/zs.c zs needs-flag
file dev/ic/z8530sc.c zs

View File

@ -0,0 +1,201 @@
/* $NetBSD: central.c,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: central.c,v 1.7 2010/11/11 17:58:23 miod Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <machine/autoconf.h>
#include <machine/openfirm.h>
#include <sparc64/dev/centralvar.h>
struct central_softc {
bus_space_tag_t sc_bt;
bus_space_tag_t sc_cbt;
int sc_node;
int sc_nrange;
struct central_range *sc_range;
};
static int central_match(device_t, cfdata_t, void *);
static void central_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(central, sizeof(struct central_softc),
central_match, central_attach, NULL, NULL);
static int central_print(void *, const char *);
static int central_get_string(int, const char *, char **);
static bus_space_tag_t central_alloc_bus_tag(struct central_softc *);
static int _central_bus_map(
bus_space_tag_t,
bus_addr_t, /*offset*/
bus_size_t, /*size*/
int, /*flags*/
vaddr_t, /* XXX unused -- compat w/sparc */
bus_space_handle_t *);
static int
central_match(device_t parent, cfdata_t match, void *aux)
{
struct mainbus_attach_args *ma = aux;
if (strcmp(ma->ma_name, "central") == 0)
return (1);
return (0);
}
static void
central_attach(device_t parent, device_t self, void *aux)
{
struct central_softc *sc = (struct central_softc *)self;
struct mainbus_attach_args *ma = aux;
int node0, node;
sc->sc_bt = ma->ma_bustag;
sc->sc_node = ma->ma_node;
sc->sc_cbt = central_alloc_bus_tag(sc);
prom_getprop(sc->sc_node, "ranges", sizeof(struct central_range),
&sc->sc_nrange, (void **)&sc->sc_range);
printf("\n");
node0 = firstchild(sc->sc_node);
for (node = node0; node; node = nextsibling(node)) {
struct central_attach_args ca;
bzero(&ca, sizeof(ca));
ca.ca_node = node;
ca.ca_bustag = sc->sc_cbt;
if (central_get_string(ca.ca_node, "name", &ca.ca_name)) {
printf("can't fetch name for node 0x%x\n", node);
continue;
}
prom_getprop(node, "reg", sizeof(struct central_reg),
&ca.ca_nreg, (void **)&ca.ca_reg);
(void)config_found(self, (void *)&ca, central_print);
if (ca.ca_name != NULL)
free(ca.ca_name, M_DEVBUF);
}
}
static int
central_get_string(int node, const char *name, char **buf)
{
int len;
len = prom_getproplen(node, name);
if (len < 0)
return (len);
*buf = (char *)malloc(len + 1, M_DEVBUF, M_NOWAIT);
if (*buf == NULL)
return (-1);
if (len != 0)
prom_getpropstringA(node, name, *buf, len + 1);
(*buf)[len] = '\0';
return (0);
}
static int
central_print(void *args, const char *busname)
{
struct central_attach_args *ca = args;
char *class;
if (busname != NULL) {
printf("\"%s\" at %s", ca->ca_name, busname);
class = prom_getpropstring(ca->ca_node, "device_type");
if (*class != '\0')
printf(" class %s", class);
}
return (UNCONF);
}
static bus_space_tag_t
central_alloc_bus_tag(struct central_softc *sc)
{
struct sparc_bus_space_tag *bt;
bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT | M_ZERO);
if (bt == NULL)
panic("central: couldn't alloc bus tag");
bt->cookie = sc;
bt->parent = sc->sc_bt;
#if 0
bt->asi = bt->parent->asi;
bt->sasi = bt->parent->sasi;
#endif
bt->sparc_bus_map = _central_bus_map;
/* XXX bt->sparc_bus_mmap = central_bus_mmap; */
/* XXX bt->sparc_intr_establish = upa_intr_establish; */
return (bt);
}
static int
_central_bus_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, int flags,
vaddr_t v, bus_space_handle_t *hp)
{
struct central_softc *sc = t->cookie;
int64_t slot = BUS_ADDR_IOSPACE(addr);
int64_t offset = BUS_ADDR_PADDR(addr);
int i;
if (t->parent == NULL || t->parent->sparc_bus_map == NULL) {
printf("\ncentral_bus_map: invalid parent");
return (EINVAL);
}
for (i = 0; i < sc->sc_nrange; i++) {
bus_addr_t paddr;
if (sc->sc_range[i].cspace != slot)
continue;
paddr = offset - sc->sc_range[i].coffset;
paddr += sc->sc_range[i].poffset;
paddr |= ((bus_addr_t)sc->sc_range[i].pspace << 32);
return bus_space_map(t->parent, paddr, size, flags, hp);
}
return (EINVAL);
}

View File

@ -0,0 +1,53 @@
/* $NetBSD: centralvar.h,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: centralvar.h,v 1.1 2004/09/22 21:31:51 jason Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
struct central_reg {
u_int32_t cbr_slot;
u_int32_t cbr_offset;
u_int32_t cbr_size;
};
struct central_attach_args {
char *ca_name;
bus_space_tag_t ca_bustag;
struct central_reg *ca_reg;
int ca_node;
int ca_nreg;
};
struct central_range {
u_int32_t cspace; /* Client space */
u_int32_t coffset; /* Client offset */
u_int32_t pspace; /* Parent space */
u_int32_t poffset; /* Parent offset */
u_int32_t size; /* Size in bytes of this range */
};
#define central_bus_map(t, slot, offset, sz, flags, hp) \
bus_space_map(t, BUS_ADDR(slot, offset), sz, flags, hp)

283
sys/arch/sparc64/dev/fhc.c Normal file
View File

@ -0,0 +1,283 @@
/* $NetBSD: fhc.c,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: fhc.c,v 1.17 2010/11/11 17:58:23 miod Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <machine/autoconf.h>
#include <machine/openfirm.h>
#include <sparc64/dev/fhcreg.h>
#include <sparc64/dev/fhcvar.h>
#include <sparc64/dev/iommureg.h>
int fhc_print(void *, const char *);
bus_space_tag_t fhc_alloc_bus_tag(struct fhc_softc *);
int _fhc_bus_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, vaddr_t,
bus_space_handle_t *);
void *fhc_intr_establish(bus_space_tag_t, int, int,
int (*)(void *), void *, void (*)(void));
bus_space_handle_t *fhc_find_intr_handle(struct fhc_softc *, int);
void
fhc_attach(struct fhc_softc *sc)
{
int node0, node;
u_int32_t ctrl;
printf(" board %d: %s\n", sc->sc_board,
prom_getpropstring(sc->sc_node, "board-model"));
sc->sc_cbt = fhc_alloc_bus_tag(sc);
sc->sc_ign = sc->sc_board << 1;
bus_space_write_4(sc->sc_bt, sc->sc_ireg, FHC_I_IGN, sc->sc_ign);
sc->sc_ign = bus_space_read_4(sc->sc_bt, sc->sc_ireg, FHC_I_IGN);
ctrl = bus_space_read_4(sc->sc_bt, sc->sc_preg, FHC_P_CTRL);
if (!sc->sc_is_central)
ctrl |= FHC_P_CTRL_IXIST;
ctrl &= ~(FHC_P_CTRL_AOFF | FHC_P_CTRL_BOFF | FHC_P_CTRL_SLINE);
bus_space_write_4(sc->sc_bt, sc->sc_preg, FHC_P_CTRL, ctrl);
bus_space_read_4(sc->sc_bt, sc->sc_preg, FHC_P_CTRL);
/* clear interrupts */
bus_space_write_4(sc->sc_bt, sc->sc_freg, FHC_F_ICLR, 0);
bus_space_read_4(sc->sc_bt, sc->sc_freg, FHC_F_ICLR);
bus_space_write_4(sc->sc_bt, sc->sc_sreg, FHC_S_ICLR, 0);
bus_space_read_4(sc->sc_bt, sc->sc_sreg, FHC_S_ICLR);
bus_space_write_4(sc->sc_bt, sc->sc_ureg, FHC_U_ICLR, 0);
bus_space_read_4(sc->sc_bt, sc->sc_ureg, FHC_U_ICLR);
bus_space_write_4(sc->sc_bt, sc->sc_treg, FHC_T_ICLR, 0);
bus_space_read_4(sc->sc_bt, sc->sc_treg, FHC_T_ICLR);
prom_getprop(sc->sc_node, "ranges", sizeof(struct fhc_range),
&sc->sc_nrange, (void **)&sc->sc_range);
node0 = firstchild(sc->sc_node);
for (node = node0; node; node = nextsibling(node)) {
struct fhc_attach_args fa;
#if 0
if (!checkstatus(node))
continue;
#endif
bzero(&fa, sizeof(fa));
fa.fa_node = node;
fa.fa_bustag = sc->sc_cbt;
if (fhc_get_string(fa.fa_node, "name", &fa.fa_name)) {
printf("can't fetch name for node 0x%x\n", node);
continue;
}
prom_getprop(node, "reg", sizeof(struct fhc_reg),
&fa.fa_nreg, (void **)&fa.fa_reg);
prom_getprop(node, "interrupts", sizeof(int),
&fa.fa_nintr, (void **)&fa.fa_intr);
prom_getprop(node, "address", sizeof(*fa.fa_promvaddrs),
&fa.fa_npromvaddrs, (void **)&fa.fa_promvaddrs);
(void)config_found(sc->sc_dev, (void *)&fa, fhc_print);
if (fa.fa_name != NULL)
free(fa.fa_name, M_DEVBUF);
if (fa.fa_reg != NULL)
free(fa.fa_reg, M_DEVBUF);
if (fa.fa_intr != NULL)
free(fa.fa_intr, M_DEVBUF);
if (fa.fa_promvaddrs != NULL)
free(fa.fa_promvaddrs, M_DEVBUF);
}
}
int
fhc_print(void *args, const char *busname)
{
struct fhc_attach_args *fa = args;
char *class;
if (busname != NULL) {
printf("\"%s\" at %s", fa->fa_name, busname);
class = prom_getpropstring(fa->fa_node, "device_type");
if (*class != '\0')
printf(" class %s", class);
}
return (UNCONF);
}
int
fhc_get_string(int node, const char *name, char **buf)
{
int len;
len = prom_getproplen(node, name);
if (len < 0)
return (len);
*buf = (char *)malloc(len + 1, M_DEVBUF, M_NOWAIT);
if (*buf == NULL)
return (-1);
if (len != 0)
prom_getpropstringA(node, name, *buf, len + 1);
(*buf)[len] = '\0';
return (0);
}
bus_space_tag_t
fhc_alloc_bus_tag(struct fhc_softc *sc)
{
struct sparc_bus_space_tag *bt;
bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT | M_ZERO);
if (bt == NULL)
panic("fhc: couldn't alloc bus tag");
bt->cookie = sc;
bt->parent = sc->sc_bt;
bt->type = 0; /* XXX asi? */
bt->sparc_bus_map = _fhc_bus_map;
/* XXX bt->sparc_bus_mmap = fhc_bus_mmap; */
bt->sparc_intr_establish = fhc_intr_establish;
return (bt);
}
int
_fhc_bus_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
int flags, vaddr_t unused, bus_space_handle_t *hp)
{
struct fhc_softc *sc = t->cookie;
int64_t slot = BUS_ADDR_IOSPACE(addr);
int64_t offset = BUS_ADDR_PADDR(addr);
int i;
if (t->parent == NULL || t->parent->sparc_bus_map == NULL) {
printf("\n_fhc_bus_map: invalid parent");
return (EINVAL);
}
for (i = 0; i < sc->sc_nrange; i++) {
bus_addr_t paddr;
if (sc->sc_range[i].cspace != slot)
continue;
paddr = offset - sc->sc_range[i].coffset;
paddr += sc->sc_range[i].poffset;
paddr |= ((bus_addr_t)sc->sc_range[i].pspace << 32);
return bus_space_map(t->parent, paddr, size, flags, hp);
}
return (EINVAL);
}
bus_space_handle_t *
fhc_find_intr_handle(struct fhc_softc *sc, int ino)
{
switch (FHC_INO(ino)) {
case FHC_F_INO:
return &sc->sc_freg;
case FHC_S_INO:
return &sc->sc_sreg;
case FHC_U_INO:
return &sc->sc_ureg;
case FHC_T_INO:
return &sc->sc_treg;
default:
break;
}
return (NULL);
}
void *
fhc_intr_establish(bus_space_tag_t t, int ihandle, int level,
int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */)
{
struct fhc_softc *sc = t->cookie;
volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL;
struct intrhand *ih;
long vec;
bus_space_handle_t *hp;
struct fhc_intr_reg *intrregs;
hp = fhc_find_intr_handle(sc, ihandle);
if (hp == NULL) {
printf(": can't find intr handle\n");
return (NULL);
}
intrregs = bus_space_vaddr(sc->sc_bt, *hp);
intrmapptr = &intrregs->imap;
intrclrptr = &intrregs->iclr;
vec = ((sc->sc_ign << INTMAP_IGN_SHIFT) & INTMAP_IGN) |
INTINO(ihandle);
ih = (struct intrhand *)
malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT);
if (ih == NULL)
return (NULL);
ih->ih_ivec = ihandle;
/* Register the map and clear intr registers */
ih->ih_map = intrmapptr;
ih->ih_clr = intrclrptr;
ih->ih_fun = handler;
ih->ih_arg = arg;
ih->ih_pil = level;
ih->ih_number = vec;
intr_establish(ih->ih_pil, level != IPL_VM, ih);
/*
* XXXX --- we really should use bus_space for this.
*/
if (intrmapptr != NULL) {
u_int64_t r;
r = *intrmapptr;
r |= INTMAP_V;
*intrmapptr = r;
r = *intrmapptr;
ih->ih_number |= r & INTMAP_INR;
}
return (ih);
}

View File

@ -0,0 +1,120 @@
/* $NetBSD: fhc_central.c,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: fhc_central.c,v 1.5 2004/09/27 18:32:35 jason Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net).
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/bus.h>
#include <machine/autoconf.h>
#include <machine/openfirm.h>
#include <sparc64/dev/centralvar.h>
#include <sparc64/dev/fhcreg.h>
#include <sparc64/dev/fhcvar.h>
int fhc_central_match(device_t, cfdata_t, void *);
void fhc_central_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(fhc_central, sizeof(struct fhc_softc),
fhc_central_match, fhc_central_attach, NULL, NULL);
int
fhc_central_match(device_t parent, cfdata_t match, void *aux)
{
struct central_attach_args *ca = aux;
if (strcmp(ca->ca_name, "fhc") == 0)
return (1);
return (0);
}
void
fhc_central_attach(device_t parent, device_t self, void *aux)
{
struct fhc_softc *sc = (struct fhc_softc *)self;
struct central_attach_args *ca = aux;
u_int32_t board;
sc->sc_node = ca->ca_node;
sc->sc_bt = ca->ca_bustag;
sc->sc_is_central = 1;
if (central_bus_map(sc->sc_bt, ca->ca_reg[0].cbr_slot,
ca->ca_reg[0].cbr_offset, ca->ca_reg[0].cbr_size, 0,
&sc->sc_preg)) {
printf(": failed to map preg\n");
return;
}
if (central_bus_map(sc->sc_bt, ca->ca_reg[1].cbr_slot,
ca->ca_reg[1].cbr_offset, ca->ca_reg[1].cbr_size, 0,
&sc->sc_ireg)) {
printf(": failed to map ireg\n");
return;
}
if (central_bus_map(sc->sc_bt, ca->ca_reg[2].cbr_slot,
ca->ca_reg[2].cbr_offset, ca->ca_reg[2].cbr_size,
BUS_SPACE_MAP_LINEAR, &sc->sc_freg)) {
printf(": failed to map freg\n");
return;
}
if (central_bus_map(sc->sc_bt, ca->ca_reg[3].cbr_slot,
ca->ca_reg[3].cbr_offset, ca->ca_reg[3].cbr_size,
BUS_SPACE_MAP_LINEAR, &sc->sc_sreg)) {
printf(": failed to map sreg\n");
return;
}
if (central_bus_map(sc->sc_bt, ca->ca_reg[4].cbr_slot,
ca->ca_reg[4].cbr_offset, ca->ca_reg[4].cbr_size,
BUS_SPACE_MAP_LINEAR, &sc->sc_ureg)) {
printf(": failed to map ureg\n");
return;
}
if (central_bus_map(sc->sc_bt, ca->ca_reg[5].cbr_slot,
ca->ca_reg[5].cbr_offset, ca->ca_reg[5].cbr_size,
BUS_SPACE_MAP_LINEAR, &sc->sc_treg)) {
printf(": failed to map treg\n");
return;
}
board = bus_space_read_4(sc->sc_bt, sc->sc_preg, FHC_P_BSR);
sc->sc_board = ((board >> 16) & 0x1) | ((board >> 12) & 0xe);
sc->sc_dev = self;
fhc_attach(sc);
return;
}

View File

@ -0,0 +1,111 @@
/* $NetBSD: fhc_mainbus.c,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: fhc_mainbus.c,v 1.4 2004/09/27 18:32:35 jason Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net).
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/bus.h>
#include <machine/autoconf.h>
#include <machine/openfirm.h>
#include <sparc64/dev/fhcvar.h>
int fhc_mainbus_match(device_t, cfdata_t, void *);
void fhc_mainbus_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(fhc_mainbus, sizeof(struct fhc_softc),
fhc_mainbus_match, fhc_mainbus_attach, NULL, NULL);
int
fhc_mainbus_match(device_t parent, cfdata_t match, void *aux)
{
struct mainbus_attach_args *ma = aux;
if (strcmp(ma->ma_name, "fhc") == 0)
return (1);
return (0);
}
void
fhc_mainbus_attach(device_t parent, device_t self, void *aux)
{
struct fhc_softc *sc = (struct fhc_softc *)self;
struct mainbus_attach_args *ma = aux;
sc->sc_node = ma->ma_node;
sc->sc_bt = ma->ma_bustag;
sc->sc_is_central = 0;
if (bus_space_map(sc->sc_bt, ma->ma_reg[0].ur_paddr,
ma->ma_reg[0].ur_len, 0, &sc->sc_preg)) {
printf(": failed to map preg\n");
return;
}
if (bus_space_map(sc->sc_bt, ma->ma_reg[1].ur_paddr,
ma->ma_reg[1].ur_len, 0, &sc->sc_ireg)) {
printf(": failed to map ireg\n");
return;
}
if (bus_space_map(sc->sc_bt, ma->ma_reg[2].ur_paddr,
ma->ma_reg[2].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_freg)) {
printf(": failed to map freg\n");
return;
}
if (bus_space_map(sc->sc_bt, ma->ma_reg[3].ur_paddr,
ma->ma_reg[3].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_sreg)) {
printf(": failed to map sreg\n");
return;
}
if (bus_space_map(sc->sc_bt, ma->ma_reg[4].ur_paddr,
ma->ma_reg[4].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_ureg)) {
printf(": failed to map ureg\n");
return;
}
if (bus_space_map(sc->sc_bt, ma->ma_reg[5].ur_paddr,
ma->ma_reg[5].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_treg)) {
printf(": failed to map treg\n");
return;
}
sc->sc_board = prom_getpropint(sc->sc_node, "board#", -1);
sc->sc_dev = self;
fhc_attach(sc);
return;
}

View File

@ -0,0 +1,79 @@
/* $NetBSD: fhcreg.h,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: fhcreg.h,v 1.4 2007/05/01 19:44:56 kettenis Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net).
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#define FHC_P_ID 0x00000000 /* ID */
#define FHC_P_RCS 0x00000010 /* reset ctrl/status */
#define FHC_P_CTRL 0x00000020 /* control */
#define FHC_P_BSR 0x00000030 /* board status */
#define FHC_P_ECC 0x00000040 /* ECC control */
#define FHC_P_JCTRL 0x000000f0 /* JTAG control */
#define FHC_P_CTRL_ICS 0x00100000 /* ignore centerplane sigs */
#define FHC_P_CTRL_FRST 0x00080000 /* fatal error reset enable */
#define FHC_P_CTRL_LFAT 0x00080000 /* AC/DC local error */
#define FHC_P_CTRL_SLINE 0x00010000 /* firmware sync line */
#define FHC_P_CTRL_DCD 0x00008000 /* DC/DC converter disable */
#define FHC_P_CTRL_POFF 0x00004000 /* AC/DC ctlr PLL disable */
#define FHC_P_CTRL_FOFF 0x00002000 /* FHC ctlr PLL disable */
#define FHC_P_CTRL_AOFF 0x00001000 /* cpu a sram low pwr mode */
#define FHC_P_CTRL_BOFF 0x00000800 /* cpu b sram low pwr mode */
#define FHC_P_CTRL_PSOFF 0x00000400 /* disable fhc power supply */
#define FHC_P_CTRL_IXIST 0x00000200 /* fhc notifies clock-board */
#define FHC_P_CTRL_XMSTR 0x00000100 /* xir master enable */
#define FHC_P_CTRL_LLED 0x00000040 /* left led (reversed) */
#define FHC_P_CTRL_MLED 0x00000020 /* middle led */
#define FHC_P_CTRL_RLED 0x00000010 /* right led */
#define FHC_P_CTRL_BPINS 0x00000003 /* spare bidir pins */
#define FHC_I_IGN 0x00000000 /* IGN register */
#define FHC_F_IMAP 0x00000000 /* fanfail intr map */
#define FHC_F_ICLR 0x00000010 /* fanfail intr clr */
#define FHC_S_IMAP 0x00000000 /* system intr map */
#define FHC_S_ICLR 0x00000010 /* system intr clr */
#define FHC_U_IMAP 0x00000000 /* uart intr map */
#define FHC_U_ICLR 0x00000010 /* uart intr clr */
#define FHC_T_IMAP 0x00000000 /* tod intr map */
#define FHC_T_ICLR 0x00000010 /* tod intr clr */
struct fhc_intr_reg {
u_int64_t imap;
u_int64_t unused_0;
u_int64_t iclr;
u_int64_t unused_1;
};
#define FHC_INO(ino) ((ino) & 0x7)
#define FHC_S_INO 0
#define FHC_U_INO 1
#define FHC_T_INO 2
#define FHC_F_INO 3

View File

@ -0,0 +1,78 @@
/* $NetBSD: fhcvar.h,v 1.1 2011/07/29 08:37:36 mrg Exp $ */
/* $OpenBSD: fhcvar.h,v 1.8 2004/10/01 18:18:49 jason Exp $ */
/*
* Copyright (c) 2004 Jason L. Wright (jason@thought.net).
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
struct fhc_reg {
u_int32_t fbr_slot;
u_int32_t fbr_offset;
u_int32_t fbr_size;
};
struct fhc_range {
u_int32_t cspace; /* Client space */
u_int32_t coffset; /* Client offset */
u_int32_t pspace; /* Parent space */
u_int32_t poffset; /* Parent offset */
u_int32_t size; /* Size in bytes of this range */
};
struct fhc_softc {
device_t sc_dev;
int sc_node;
int sc_is_central; /* parent is central */
int sc_board;
u_int32_t sc_ign;
bus_space_tag_t sc_bt;
bus_space_tag_t sc_cbt;
int sc_nrange;
struct fhc_range *sc_range;
bus_space_handle_t sc_preg; /* internal regs */
bus_space_handle_t sc_ireg; /* ign regs */
bus_space_handle_t sc_freg; /* fanfail regs */
bus_space_handle_t sc_sreg; /* system regs */
bus_space_handle_t sc_ureg; /* uart regs */
bus_space_handle_t sc_treg; /* tod regs */
};
void fhc_attach(struct fhc_softc *);
int fhc_get_string(int, const char *, char **);
struct fhc_attach_args {
bus_space_tag_t fa_bustag;
char *fa_name;
int *fa_intr;
struct fhc_reg *fa_reg;
u_int32_t *fa_promvaddrs;
int fa_node;
int fa_nreg;
int fa_nintr;
int fa_npromvaddrs;
};
#define fhc_bus_map(t, slot, offset, sz, flags, hp) \
bus_space_map(t, BUS_ADDR(slot, offset), sz, flags, hp)

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkclock.c,v 1.8 2011/07/01 18:48:36 dyoung Exp $ */
/* $NetBSD: mkclock.c,v 1.9 2011/07/29 08:37:36 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mkclock.c,v 1.8 2011/07/01 18:48:36 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: mkclock.c,v 1.9 2011/07/29 08:37:36 mrg Exp $");
/*
* Clock driver for 'mkclock' - Mostek MK48Txx TOD clock.
@ -84,6 +84,8 @@ __KERNEL_RCSID(0, "$NetBSD: mkclock.c,v 1.8 2011/07/01 18:48:36 dyoung Exp $");
#include <dev/ebus/ebusreg.h>
#include <dev/ebus/ebusvar.h>
#include <sparc64/dev/fhcvar.h>
/*
* clock (eeprom) attaches at the sbus or the ebus (PCI)
*/
@ -93,6 +95,9 @@ static void mkclock_sbus_attach(device_t, device_t, void *);
static int mkclock_ebus_match(device_t, cfdata_t, void *);
static void mkclock_ebus_attach(device_t, device_t, void *);
static int mkclock_fhc_match(device_t, cfdata_t, void *);
static void mkclock_fhc_attach(device_t, device_t, void *);
static void mkclock_attach(struct mk48txx_softc *, int);
static int mkclock_wenable(struct todr_chip_handle *, int);
@ -104,6 +109,9 @@ CFATTACH_DECL_NEW(mkclock_sbus, sizeof(struct mk48txx_softc),
CFATTACH_DECL_NEW(mkclock_ebus, sizeof(struct mk48txx_softc),
mkclock_ebus_match, mkclock_ebus_attach, NULL, NULL);
CFATTACH_DECL_NEW(mkclock_fhc, sizeof(struct mk48txx_softc),
mkclock_fhc_match, mkclock_fhc_attach, NULL, NULL);
/*
* The OPENPROM calls the clock the "eeprom", so we have to have our
* own special match function to call it the "clock".
@ -124,6 +132,14 @@ mkclock_ebus_match(device_t parent, cfdata_t cf, void *aux)
return (strcmp("eeprom", ea->ea_name) == 0);
}
static int
mkclock_fhc_match(device_t parent, cfdata_t cf, void *aux)
{
struct fhc_attach_args *fa = aux;
return (strcmp("eeprom", fa->fa_name) == 0);
}
/*
* Attach a clock (really `eeprom') to the sbus or ebus.
*
@ -199,6 +215,28 @@ mkclock_ebus_attach(struct device *parent, struct device *self, void *aux)
mkclock_attach(sc, ea->ea_node);
}
/* ARGSUSED */
static void
mkclock_fhc_attach(struct device *parent, struct device *self, void *aux)
{
struct mk48txx_softc *sc = device_private(self);
struct fhc_attach_args *fa = aux;
sc->sc_dev = self;
sc->sc_bst = fa->fa_bustag;
if (fhc_bus_map(sc->sc_bst,
fa->fa_reg[0].fbr_slot,
(fa->fa_reg[0].fbr_offset & ~NBPG),
fa->fa_reg[0].fbr_size,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bsh) != 0) {
aprint_error(": can't map register\n");
return;
}
mkclock_attach(sc, fa->fa_node);
}
static void
mkclock_attach(struct mk48txx_softc *sc, int node)

View File

@ -1,4 +1,4 @@
/* $NetBSD: sbus.c,v 1.89 2011/07/20 12:06:00 macallan Exp $ */
/* $NetBSD: sbus.c,v 1.90 2011/07/29 08:37:36 mrg Exp $ */
/*
* Copyright (c) 1999-2002 Eduardo Horvath
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sbus.c,v 1.89 2011/07/20 12:06:00 macallan Exp $");
__KERNEL_RCSID(0, "$NetBSD: sbus.c,v 1.90 2011/07/29 08:37:36 mrg Exp $");
#include "opt_ddb.h"
@ -79,7 +79,7 @@ static int _sbus_bus_map(
bus_addr_t, /*offset*/
bus_size_t, /*size*/
int, /*flags*/
vaddr_t, /* XXX unused -- compat w/sparc */
vaddr_t, /* XXX unused -- compat w/sparc */
bus_space_handle_t *);
static void *sbus_intr_establish(
bus_space_tag_t,

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.70 2011/03/12 11:43:38 nakayama Exp $ */
/* $NetBSD: zs.c,v 1.71 2011/07/29 08:37:36 mrg Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.70 2011/03/12 11:43:38 nakayama Exp $");
__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.71 2011/07/29 08:37:36 mrg Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@ -69,6 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.70 2011/03/12 11:43:38 nakayama Exp $");
#include <ddb/db_output.h>
#include <dev/sbus/sbusvar.h>
#include <sparc64/dev/fhcvar.h>
#include <sparc64/dev/cons.h>
#include "ioconf.h"
@ -154,12 +155,18 @@ struct consdev zs_consdev = {
static int zs_match_sbus(device_t, cfdata_t, void *);
static void zs_attach_sbus(device_t, device_t, void *);
static int zs_match_fhc(device_t, cfdata_t, void *);
static void zs_attach_fhc(device_t, device_t, void *);
static void zs_attach(struct zsc_softc *, struct zsdevice *, int);
static int zs_print(void *, const char *);
CFATTACH_DECL_NEW(zs, sizeof(struct zsc_softc),
zs_match_sbus, zs_attach_sbus, NULL, NULL);
CFATTACH_DECL_NEW(zs_fhc, sizeof(struct zsc_softc),
zs_match_fhc, zs_attach_fhc, NULL, NULL);
/* Interrupt handlers. */
int zscheckintr(void *);
static int zshard(void *);
@ -191,6 +198,17 @@ zs_match_sbus(device_t parent, cfdata_t cf, void *aux)
return (1);
}
static int
zs_match_fhc(device_t parent, cfdata_t cf, void *aux)
{
struct fhc_attach_args *fa = aux;
if (strcmp(cf->cf_name, fa->fa_name) != 0)
return (0);
return (1);
}
static void
zs_attach_sbus(device_t parent, device_t self, void *aux)
{
@ -244,6 +262,65 @@ zs_attach_sbus(device_t parent, device_t self, void *aux)
zs_attach(zsc, zsaddr[zs_unit], sa->sa_pri);
}
static void
zs_attach_fhc(device_t parent, device_t self, void *aux)
{
struct zsc_softc *zsc = device_private(self);
struct fhc_attach_args *fa = aux;
bus_space_handle_t bh;
int zs_unit;
zsc->zsc_dev = self;
zs_unit = device_unit(self);
if (fa->fa_nreg < 1 && fa->fa_npromvaddrs < 1) {
printf(": no registers\n");
return;
}
if (fa->fa_nintr == 0) {
aprint_error(": no interrupt lines\n");
return;
}
/* Use the mapping setup by the Sun PROM if possible. */
if (zsaddr[zs_unit] == NULL) {
/* Only map registers once. */
if (fa->fa_npromvaddrs) {
/*
* We're converting from a 32-bit pointer to a 64-bit
* pointer. Since the 32-bit entity is negative, but
* the kernel is still mapped into the lower 4GB
* range, this needs to be zero-extended.
*
* XXXXX If we map the kernel and devices into the
* high 4GB range, this needs to be changed to
* sign-extend the address.
*/
sparc_promaddr_to_handle(fa->fa_bustag,
fa->fa_promvaddrs[0], &bh);
} else {
if (fhc_bus_map(fa->fa_bustag,
fa->fa_reg[0].fbr_slot,
fa->fa_reg[0].fbr_offset,
fa->fa_reg[0].fbr_size,
BUS_SPACE_MAP_LINEAR,
&bh) != 0) {
aprint_error(": cannot map registers\n");
return;
}
}
zsaddr[zs_unit] = bus_space_vaddr(fa->fa_bustag, bh);
}
zsc->zsc_bustag = fa->fa_bustag;
zsc->zsc_dmatag = NULL;
zsc->zsc_promunit = prom_getpropint(fa->fa_node, "slave", -2);
zsc->zsc_node = fa->fa_node;
zs_attach(zsc, zsaddr[zs_unit], fa->fa_intr[0]);
}
/*
* Attach a found zs.
*