aboutsummaryrefslogtreecommitdiff
path: root/chips
diff options
context:
space:
mode:
authorPasha <pasha@member.fsf.org>2024-02-20 18:49:50 +0000
committerPasha <pasha@member.fsf.org>2024-02-20 18:49:50 +0000
commit5e0b8d508ed51004bd836384293be00950ee62c9 (patch)
treee3f16b1aa8b7177032ce3ec429fbad2b1d92a876 /chips
downloadgnumach-riscv-5e0b8d508ed51004bd836384293be00950ee62c9.tar.gz
gnumach-riscv-5e0b8d508ed51004bd836384293be00950ee62c9.tar.bz2
init gnumach copy
Diffstat (limited to 'chips')
-rw-r--r--chips/busses.c232
-rw-r--r--chips/busses.h154
2 files changed, 386 insertions, 0 deletions
diff --git a/chips/busses.c b/chips/busses.c
new file mode 100644
index 0000000..3811d0c
--- /dev/null
+++ b/chips/busses.c
@@ -0,0 +1,232 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * File: busses.c
+ * Author: Alessandro Forin, Carnegie Mellon University
+ * Date: 4/90
+ *
+ * Generic autoconfiguration functions,
+ * usable to probe and attach devices
+ * on any bus that suits the generic bus
+ * structure, such as VME, TURBOChannel,
+ * and all the VAX busses.
+ *
+ */
+
+#include <string.h>
+#include <kern/printf.h>
+#include <mach/boolean.h>
+#include <mach/std_types.h>
+#include <chips/busses.h>
+
+
+
+
+/*
+ * configure_bus_master
+ *
+ * Given the name of a bus_ctlr, look it up in the
+ * init table. If found, probe it. If there can be
+ * slaves attached, walk the device's init table
+ * for those that might be attached to this controller.
+ * Call the 'slave' function on each one to see if
+ * ok, then the 'attach' one.
+ *
+ * Returns 0 if the controller is not there.
+ *
+ */
+boolean_t configure_bus_master(
+ const char *name,
+ vm_offset_t virt,
+ vm_offset_t phys,
+ int adpt_no,
+ const char *bus_name)
+{
+ struct bus_device *device;
+ struct bus_ctlr *master;
+ struct bus_driver *driver;
+
+ boolean_t found = FALSE;
+
+ /*
+ * Match the name in the table, then pick the entry that has the
+ * right adaptor number, or one that has it wildcarded. Entries
+ * already allocated are marked alive, skip them.
+ */
+ for (master = bus_master_init; master->driver; master++) {
+ if (master->alive)
+ continue;
+ if (((master->adaptor == adpt_no) || (master->adaptor == '?')) &&
+ (strcmp(master->name, name) == 0)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return FALSE;
+
+ /*
+ * Found a match, probe it
+ */
+ driver = master->driver;
+ if ((*driver->probe) (virt, master) == 0)
+ return FALSE;
+
+ master->alive = 1;
+ master->adaptor = adpt_no;
+
+ /*
+ * Remember which controller this device is attached to
+ */
+ driver->minfo[master->unit] = master;
+
+ printf("%s%d: at %s%d\n", master->name, master->unit, bus_name, adpt_no);
+
+ /*
+ * Now walk all devices to check those that might be attached to this
+ * controller. We match the unallocated ones that have the right
+ * controller number, or that have a widcarded controller number.
+ */
+ for (device = bus_device_init; device->driver; device++) {
+ int ctlr;
+ if (device->alive || device->driver != driver ||
+ (device->adaptor != '?' && device->adaptor != adpt_no))
+ continue;
+ ctlr = device->ctlr;
+ if (ctlr == '?') device->ctlr = master->unit;
+ /*
+ * A matching entry. See if the slave-probing routine is
+ * happy.
+ */
+ if ((device->ctlr != master->unit) ||
+ ((*driver->slave) (device, virt) == 0)) {
+ device->ctlr = ctlr;
+ continue;
+ }
+
+ device->alive = 1;
+ device->adaptor = adpt_no;
+ device->ctlr = master->unit;
+
+ /*
+ * Save a backpointer to the controller
+ */
+ device->mi = master;
+
+ /*
+ * ..and to the device
+ */
+ driver->dinfo[device->unit] = device;
+
+ if (device->slave >= 0)
+ printf(" %s%d: at %s%d slave %d",
+ device->name, device->unit,
+ driver->mname, master->unit, device->slave);
+ else
+ printf(" %s%d: at %s%d",
+ device->name, device->unit,
+ driver->mname, master->unit);
+
+ /*
+ * Now attach this slave
+ */
+ (*driver->attach) (device);
+ printf("\n");
+ }
+ return TRUE;
+}
+
+/*
+ * configure_bus_device
+ *
+ * Given the name of a bus_device, look it up in the
+ * init table. If found, probe it. If it is present,
+ * call the driver's 'attach' function.
+ *
+ * Returns 0 if the device is not there.
+ *
+ */
+boolean_t configure_bus_device(
+ const char *name,
+ vm_offset_t virt,
+ vm_offset_t phys,
+ int adpt_no,
+ const char *bus_name)
+{
+ struct bus_device *device;
+ struct bus_driver *driver;
+
+ boolean_t found = FALSE;
+
+ /*
+ * Walk all devices to find one with the right name
+ * and adaptor number (or wildcard). The entry should
+ * be unallocated, and also the slave number should
+ * be wildcarded.
+ */
+ for (device = bus_device_init; device->driver; device++) {
+ if (device->alive)
+ continue;
+ if (((device->adaptor == adpt_no) || (device->adaptor == '?')) &&
+ (device->slave == -1) &&
+ ((!device->phys_address) ||
+ ((device->phys_address == phys) && (device->address == virt))) &&
+ (strcmp(device->name, name) == 0)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return FALSE;
+
+ /*
+ * Found an entry, probe the device
+ */
+ driver = device->driver;
+ if ((*driver->probe) (virt, (struct bus_ctlr *)device) == 0)
+ return FALSE;
+
+ device->alive = 1;
+ device->adaptor = adpt_no;
+
+ printf("%s%d: at %s%d", device->name, device->unit, bus_name, adpt_no);
+
+ /*
+ * Remember which driver this device is attached to
+ */
+ driver->dinfo[device->unit] = device;
+
+ /*
+ * Attach the device
+ */
+ (*driver->attach) (device);
+ printf("\n");
+
+ return TRUE;
+}
+
diff --git a/chips/busses.h b/chips/busses.h
new file mode 100644
index 0000000..90eebc6
--- /dev/null
+++ b/chips/busses.h
@@ -0,0 +1,154 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1994-1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * File: busses.h
+ * Author: Alessandro Forin, Carnegie Mellon University
+ * Date: 4/90
+ *
+ * Structures used by configuration routines to
+ * explore a given bus structure.
+ */
+
+#ifndef _CHIPS_BUSSES_H_
+#define _CHIPS_BUSSES_H_
+
+#include <mach/boolean.h>
+#include <mach/machine/vm_types.h>
+
+/*
+ *
+ * This is mildly modeled after the Unibus on Vaxen,
+ * one of the most complicated bus structures.
+ * Therefore, let's hope this can be done once and for all.
+ *
+ * At the bottom level there is a "bus_device", which
+ * might exist in isolation (e.g. a clock on the CPU
+ * board) or be a standard component of an architecture
+ * (e.g. the bitmap display on some workstations).
+ *
+ * Disk devices and communication lines support multiple
+ * units, hence the "bus_driver" structure which is more
+ * flexible and allows probing and dynamic configuration
+ * of the number and type of attached devices.
+ *
+ * At the top level there is a "bus_ctlr" structure, used
+ * in systems where the I/O bus(ses) are separate from
+ * the memory bus(ses), and/or when memory boards can be
+ * added to the main bus (and they must be config-ed
+ * and/or can interrupt the processor for ECC errors).
+ *
+ * The autoconfiguration process typically starts at
+ * the top level and walks down tables that are
+ * defined either in a generic file or are specially
+ * created by config.
+ */
+
+/*
+ * Per-controller structure.
+ */
+struct bus_ctlr {
+ struct bus_driver *driver; /* myself, as a device */
+ char *name; /* readability */
+ int unit; /* index in driver */
+ void (*intr)(int); /* interrupt handler(s) */
+ vm_offset_t address; /* device virtual address */
+ int am; /* address modifier */
+ vm_offset_t phys_address;/* device phys address */
+ char adaptor; /* slot where found */
+ char alive; /* probed successfully */
+ char flags; /* any special conditions */
+ vm_offset_t sysdep; /* On some systems, queue of
+ * operations in-progress */
+ natural_t sysdep1; /* System dependent */
+};
+
+
+/*
+ * Per-``device'' structure
+ */
+struct bus_device {
+ struct bus_driver *driver; /* autoconf info */
+ char *name; /* my name */
+ int unit;
+ void (*intr)(int);
+ vm_offset_t address; /* device address */
+ int am; /* address modifier */
+ vm_offset_t phys_address;/* device phys address */
+ char adaptor;
+ char alive;
+ char ctlr;
+ char slave;
+ int flags;
+ struct bus_ctlr *mi; /* backpointer to controller */
+ struct bus_device *next; /* optional chaining */
+ vm_offset_t sysdep; /* System dependent */
+ natural_t sysdep1; /* System dependent */
+};
+
+/*
+ * General flag definitions
+ */
+#define BUS_INTR_B4_PROBE 0x01 /* enable interrupts before probe */
+#define BUS_INTR_DISABLED 0x02 /* ignore all interrupts */
+#define BUS_CTLR 0x04 /* descriptor for a bus adaptor */
+#define BUS_XCLU 0x80 /* want exclusive use of bdp's */
+
+/*
+ * Per-driver structure.
+ *
+ * Each bus driver defines entries for a set of routines
+ * that are used at boot time by the configuration program.
+ */
+struct bus_driver {
+ int (*probe)( /* see if the driver is there */
+ vm_offset_t address,
+ struct bus_ctlr *);
+ int (*slave)( /* see if any slave is there */
+ struct bus_device *,
+ vm_offset_t);
+ void (*attach)( /* setup driver after probe */
+ struct bus_device *);
+ int (*dgo)(struct bus_device *); /* start transfer */
+ vm_offset_t *addr; /* device csr addresses */
+ char *dname; /* name of a device */
+ struct bus_device **dinfo; /* backpointers to init structs */
+ char *mname; /* name of a controller */
+ struct bus_ctlr **minfo; /* backpointers to init structs */
+ int flags;
+};
+
+#ifdef KERNEL
+extern struct bus_ctlr bus_master_init[];
+extern struct bus_device bus_device_init[];
+
+extern boolean_t configure_bus_master(const char *, vm_offset_t, vm_offset_t,
+ int, const char * );
+extern boolean_t configure_bus_device(const char *, vm_offset_t, vm_offset_t,
+ int, const char * );
+#endif /* KERNEL */
+
+
+#endif /* _CHIPS_BUSSES_H_ */