diff options
author | Pasha <pasha@member.fsf.org> | 2024-02-20 18:49:50 +0000 |
---|---|---|
committer | Pasha <pasha@member.fsf.org> | 2024-02-20 18:49:50 +0000 |
commit | 5e0b8d508ed51004bd836384293be00950ee62c9 (patch) | |
tree | e3f16b1aa8b7177032ce3ec429fbad2b1d92a876 /chips | |
download | gnumach-riscv-5e0b8d508ed51004bd836384293be00950ee62c9.tar.gz gnumach-riscv-5e0b8d508ed51004bd836384293be00950ee62c9.tar.bz2 |
init gnumach copy
Diffstat (limited to 'chips')
-rw-r--r-- | chips/busses.c | 232 | ||||
-rw-r--r-- | chips/busses.h | 154 |
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_ */ |