summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2000-03-18 07:42:13 +0000
committermjacob <mjacob@FreeBSD.org>2000-03-18 07:42:13 +0000
commit1de0f61bdd3198ba0fc0609362eb8a9bd8245409 (patch)
treee58c004d8f13d2cfd5f4db8d01dad334b41d3909 /sys
parent0b099e7dbd1118cf430c1b95a2fae8947002c941 (diff)
downloadFreeBSD-src-1de0f61bdd3198ba0fc0609362eb8a9bd8245409.zip
FreeBSD-src-1de0f61bdd3198ba0fc0609362eb8a9bd8245409.tar.gz
Alpha 8200: Some minor formatting tweaks and removal of clause 3 of licence.
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/tlsb/tlsb.c283
1 files changed, 130 insertions, 153 deletions
diff --git a/sys/alpha/tlsb/tlsb.c b/sys/alpha/tlsb/tlsb.c
index b6790f7..a293457 100644
--- a/sys/alpha/tlsb/tlsb.c
+++ b/sys/alpha/tlsb/tlsb.c
@@ -2,7 +2,7 @@
/* $NetBSD: tlsb.c,v 1.10 1998/05/14 00:01:32 thorpej Exp $ */
/*
- * Copyright (c) 1997 by Matthew Jacob
+ * Copyright (c) 1997, 2000 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
@@ -18,8 +18,6 @@
* 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -54,52 +52,35 @@
#include <alpha/tlsb/tlsbreg.h>
#include <alpha/tlsb/tlsbvar.h>
-/* #include "locators.h" */
-
-extern int cputype;
+struct tlsb_device *tlsb_primary_cpu = NULL;
#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
-/*
- * The structure used to attach devices to the TurboLaser.
- */
-struct tlsb_device {
- int td_node; /* node number */
- u_int16_t td_dtype; /* device type */
- u_int8_t td_swrev; /* software revision */
- u_int8_t td_hwrev; /* hardware revision */
-};
-#define DEVTOTLSB(dev) ((struct tlsb_device*) device_get_ivars(dev))
-
-struct intr_mapping {
- STAILQ_ENTRY(intr_mapping) queue;
- driver_intr_t* intr;
- void* arg;
-};
-
struct tlsb_softc {
- STAILQ_HEAD(, intr_mapping) intr_handlers;
+ driver_intr_t * zsc_intr;
+ void * zsc_arg;
+ driver_intr_t * sub_intr;
+ device_t tlsb_dev;
+ int tlsb_map;
};
-static char *tlsb_node_type_str(u_int32_t);
-static void tlsb_intr(void* frame, u_long vector);
+static void tlsb_add_child(struct tlsb_softc *, struct tlsb_device *);
+static char *tlsb_node_type_str(u_int32_t);
+static void tlsb_intr(void *, u_long);
-/* There can be only one. */
-static int tlsb_found;
-static struct tlsb_softc* tlsb0_softc;
+static struct tlsb_softc * tlsb0_softc = NULL;
static devclass_t tlsb_devclass;
/*
* Device methods
*/
-static int tlsb_probe(device_t dev);
-static int tlsb_print_child(device_t dev, device_t child);
-static int tlsb_read_ivar(device_t dev, device_t child, int which, u_long* result);
-static int tlsb_setup_intr(device_t dev, device_t child,
- struct resource *irq, int flags,
- driver_intr_t *intr, void *arg, void **cookiep);
-static int tlsb_teardown_intr(device_t dev, device_t child,
- struct resource *irq, void *cookie);
+static int tlsb_probe(device_t);
+static int tlsb_print_child(device_t, device_t);
+static int tlsb_read_ivar(device_t, device_t, int, u_long *);
+static int tlsb_setup_intr(device_t, device_t, struct resource *, int,
+ driver_intr_t *, void *, void **);
+static int
+tlsb_teardown_intr(device_t, device_t, struct resource *, void *);
static device_method_t tlsb_methods[] = {
/* Device interface */
@@ -119,9 +100,7 @@ static device_method_t tlsb_methods[] = {
};
static driver_t tlsb_driver = {
- "tlsb",
- tlsb_methods,
- sizeof(struct tlsb_softc),
+ "tlsb", tlsb_methods, sizeof (struct tlsb_softc),
};
/*
@@ -132,103 +111,57 @@ static driver_t tlsb_driver = {
static int
tlsb_probe(device_t dev)
{
- struct tlsb_softc* sc = device_get_softc(dev);
+ struct tlsb_softc *sc = device_get_softc(dev);
struct tlsb_device *tdev;
u_int32_t tldev;
- u_int8_t vid;
int node;
- device_t child;
- device_set_desc(dev, "TurboLaser bus");
+ device_set_desc(dev, "TurboLaser Backplane Bus");
- STAILQ_INIT(&sc->intr_handlers);
+ sc->tlsb_dev = dev;
tlsb0_softc = sc;
-
set_iointr(tlsb_intr);
- printf("Probing for devices on the TurboLaser bus:\n");
-
- tlsb_found = 1;
-
/*
* Attempt to find all devices on the bus, including
* CPUs, memory modules, and I/O modules.
*/
- /*
- * Sigh. I would like to just start off nicely,
- * but I need to treat I/O modules differently-
- * The highest priority I/O node has to be in
- * node #8, and I want to find it *first*, since
- * it will have the primary disks (most likely)
- * on it.
- */
- /*
- * XXX dfr: I don't see why I need to do this
- */
for (node = 0; node <= TLSB_NODE_MAX; ++node) {
/*
- * Check for invalid address. This may not really
- * be necessary, but what the heck...
+ * Check for invalid address.
*/
+#ifdef SIMOS
+ if (node != 0 && node != 8) {
+ continue;
+ } else if (node == 0) {
+ tldev = TLDEV_DTYPE_SCPU4;
+ } else {
+ tldev = TLDEV_DTYPE_KFTIA;
+ }
+#else
if (badaddr(TLSB_NODE_REG_ADDR(node, TLDEV), sizeof(u_int32_t)))
continue;
tldev = TLSB_GET_NODEREG(node, TLDEV);
-#ifdef SIMOS
- if (node != 0 && node != 8)
- continue;
#endif
if (tldev == 0) {
/* Nothing at this node. */
continue;
}
-#if 0
- if (TLDEV_ISIOPORT(tldev))
- continue; /* not interested right now */
-#endif
-
- tdev = (struct tlsb_device*)
- malloc(sizeof(struct tlsb_device),
- M_DEVBUF, M_NOWAIT);
+ tdev = (struct tlsb_device *)
+ malloc(sizeof (struct tlsb_device), M_DEVBUF, M_NOWAIT);
- if (!tdev)
+ if (!tdev) {
+ printf("tlsb_probe: unable to malloc softc\n");
continue;
+ }
+ sc->tlsb_map |= (1 << node);
tdev->td_node = node;
-#ifdef SIMOS
- if (node == 0)
- tdev->td_dtype = TLDEV_DTYPE_SCPU4;
- else if (node == 8)
- tdev->td_dtype = TLDEV_DTYPE_KFTIA;
-#else
- tdev->td_dtype = TLDEV_DTYPE(tldev);
-#endif
- tdev->td_swrev = TLDEV_SWREV(tldev);
- tdev->td_hwrev = TLDEV_HWREV(tldev);
-
- child = device_add_child(dev, NULL, -1);
- device_set_ivars(child, tdev);
- device_set_desc(child, tlsb_node_type_str(tdev->td_dtype));
-
- /*
- * Deal with hooking CPU instances to TurboLaser nodes.
- */
- if (TLDEV_ISCPU(tldev)) {
- printf("%s%d node %d: %s",
- device_get_name(dev), device_get_unit(dev),
- node, tlsb_node_type_str(tldev));
-
- /*
- * Hook in the first CPU unit.
- */
- vid = (TLSB_GET_NODEREG(node, TLVID) &
- TLVID_VIDA_MASK) >> TLVID_VIDA_SHIFT;
- printf(", VID %d\n", vid);
- TLSB_PUT_NODEREG(node, TLCPUMASK, (1<<vid));
- }
+ tdev->td_tldev = tldev;
+ tlsb_add_child(sc, tdev);
}
-
- return 0;
+ return (0);
}
static int
@@ -238,17 +171,15 @@ tlsb_print_child(device_t dev, device_t child)
int retval = 0;
retval += bus_print_child_header(dev, child);
- retval += printf(" at %s node %d\n", device_get_nameunit(dev),
- tdev->td_node);
-
+ retval += printf(" at %s node %d\n",
+ device_get_nameunit(dev), tdev->td_node);
return (retval);
}
static int
-tlsb_read_ivar(device_t dev, device_t child,
- int index, u_long* result)
+tlsb_read_ivar(device_t dev, device_t child, int index, u_long *result)
{
- struct tlsb_device* tdev = DEVTOTLSB(child);
+ struct tlsb_device *tdev = DEVTOTLSB(child);
switch (index) {
case TLSB_IVAR_NODE:
@@ -256,70 +187,116 @@ tlsb_read_ivar(device_t dev, device_t child,
break;
case TLSB_IVAR_DTYPE:
- *result = tdev->td_dtype;
+ *result = TLDEV_DTYPE(tdev->td_tldev);
break;
case TLSB_IVAR_SWREV:
- *result = tdev->td_swrev;
+ *result = TLDEV_SWREV(tdev->td_tldev);
break;
case TLSB_IVAR_HWREV:
- *result = tdev->td_hwrev;
+ *result = TLDEV_HWREV(tdev->td_tldev);
break;
}
- return ENOENT;
+ return (ENOENT);
}
static int
-tlsb_setup_intr(device_t dev, device_t child,
- struct resource *irq, int flags,
- driver_intr_t *intr, void *arg, void **cookiep)
+tlsb_setup_intr(device_t dev, device_t child, struct resource *i, int f,
+ driver_intr_t *intr, void *arg, void **c)
{
- struct tlsb_softc* sc = device_get_softc(dev);
- struct intr_mapping* i;
- i = malloc(sizeof(struct intr_mapping), M_DEVBUF, M_NOWAIT);
- if (!i)
- return ENOMEM;
- i->intr = intr;
- i->arg = arg;
- STAILQ_INSERT_TAIL(&sc->intr_handlers, i, queue);
- *cookiep = i;
- return 0;
+ if (strncmp(device_get_name(child), "zsc", 3) == 0) {
+ if (tlsb0_softc->zsc_intr)
+ return (EBUSY);
+ tlsb0_softc->zsc_intr = intr;
+ tlsb0_softc->zsc_arg = arg;
+ return (0);
+ } else if (strncmp(device_get_name(child), "dwlpx", 5) == 0) {
+ if (tlsb0_softc->sub_intr == NULL)
+ tlsb0_softc->sub_intr = intr;
+ return (0);
+ } else {
+ return (ENXIO);
+ }
}
static int
-tlsb_teardown_intr(device_t dev, device_t child,
- struct resource *irq, void *cookie)
+tlsb_teardown_intr(device_t dev, device_t child, struct resource *i, void *c)
{
- struct tlsb_softc* sc = device_get_softc(dev);
- struct intr_mapping* i = cookie;
+ if (strncmp(device_get_name(child), "zsc", 3) == 0) {
+ tlsb0_softc->zsc_intr = NULL;
+ return (0);
+ } else if (strncmp(device_get_name(dev), "dwlpx", 5) == 0) {
+ tlsb0_softc->sub_intr = NULL;
+ return (0);
+ } else {
+ return (ENXIO);
+ }
+}
- STAILQ_REMOVE(&sc->intr_handlers, i, intr_mapping, queue);
- free(i, M_DEVBUF);
- return 0;
+static void
+tlsb_intr(void *frame, u_long vector)
+{
+ if (vector && tlsb0_softc->sub_intr)
+ (*tlsb0_softc->sub_intr)((void *)vector);
}
static void
-tlsb_intr(void* frame, u_long vector)
+tlsb_add_child(struct tlsb_softc *tlsb, struct tlsb_device *tdev)
{
- struct tlsb_softc* sc = tlsb0_softc;
- struct intr_mapping* i;
+ static int kftproto, memproto, cpuproto;
+ u_int32_t dtype = tdev->td_tldev & TLDEV_DTYPE_MASK;
+ int i, unit, ordr, units = 1;
+ char *dn;
+ device_t cd;
/*
- * XXX for SimOS, broadcast the interrupt. A real implementation
- * will decode the vector to extract node and host etc.
+ * We want CPU and Memory boards to configure first, and we want the
+ * I/O boards to configure in reverse slot number order. This is
+ * further complicated by the possibility of dual CPU nodes.
*/
- for (i = STAILQ_FIRST(&sc->intr_handlers);
- i; i = STAILQ_NEXT(i, queue))
- i->intr(i->arg);
-}
+ ordr = tdev->td_node << 1;
-DRIVER_MODULE(tlsb, root, tlsb_driver, tlsb_devclass, 0, 0);
+ switch (dtype) {
+ case TLDEV_DTYPE_KFTHA:
+ case TLDEV_DTYPE_KFTIA:
+ ordr = 16 + (TLSB_NODE_MAX - tdev->td_node);
+ dn = "kft";
+ unit = kftproto++;
+ break;
+ case TLDEV_DTYPE_MS7CC:
+ dn = "tlsbmem";
+ unit = memproto++;
+ break;
+ case TLDEV_DTYPE_SCPU4:
+ case TLDEV_DTYPE_SCPU16:
+ dn = "tlsbcpu";
+ unit = cpuproto++;
+ break;
+ case TLDEV_DTYPE_DCPU4:
+ case TLDEV_DTYPE_DCPU16:
+ units = 2;
+ dn = "tlsbcpu";
+ unit = cpuproto;
+ cpuproto += 2;
+ break;
+ default:
+ return;
+ }
+
+ for (i = 0; i < units; i++, unit++) {
+ cd = device_add_child_ordered(tlsb->tlsb_dev, ordr, dn, unit);
+ if (cd == NULL)
+ return;
+ device_set_ivars(cd, tdev);
+ device_set_desc(cd, tlsb_node_type_str(dtype));
+ }
+}
static char *
tlsb_node_type_str(u_int32_t dtype)
{
- static char tlsb_line[64];
+ static char tmp[64];
switch (dtype & TLDEV_DTYPE_MASK) {
case TLDEV_DTYPE_KFTHA:
@@ -344,10 +321,10 @@ tlsb_node_type_str(u_int32_t dtype)
return ("Dual CPU, 16MB cache");
default:
- bzero(tlsb_line, sizeof(tlsb_line));
- snprintf(tlsb_line, sizeof(tlsb_line),
- "unknown, dtype 0x%x", dtype);
- return (tlsb_line);
+ bzero(tmp, sizeof(tmp));
+ snprintf(tmp, sizeof(tmp), "unknown, type 0x%x", dtype);
+ return (tmp);
}
/* NOTREACHED */
}
+DRIVER_MODULE(tlsb, root, tlsb_driver, tlsb_devclass, 0, 0);
OpenPOWER on IntegriCloud