Initial Spring 2016 commit.
This commit is contained in:
55
kern/dev/lamebus/beep_ltimer.c
Normal file
55
kern/dev/lamebus/beep_ltimer.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Attachment code for having the generic beep device use the LAMEbus
|
||||
* ltimer device for beeping.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <generic/beep.h>
|
||||
#include <lamebus/ltimer.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
struct beep_softc *
|
||||
attach_beep_to_ltimer(int beepno, struct ltimer_softc *ls)
|
||||
{
|
||||
struct beep_softc *bs = kmalloc(sizeof(struct beep_softc));
|
||||
if (bs==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)beepno; // unused
|
||||
|
||||
bs->bs_devdata = ls;
|
||||
bs->bs_beep = ltimer_beep;
|
||||
|
||||
return bs;
|
||||
}
|
59
kern/dev/lamebus/con_lscreen.c
Normal file
59
kern/dev/lamebus/con_lscreen.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Attachment code for having the generic console device use the LAMEbus
|
||||
* screen device.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <generic/console.h>
|
||||
#include <lamebus/lscreen.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
struct con_softc *
|
||||
attach_con_to_lscreen(int consno, struct lscreen_softc *ls)
|
||||
{
|
||||
struct con_softc *cs = kmalloc(sizeof(struct con_softc));
|
||||
if (cs==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cs->cs_devdata = ls;
|
||||
cs->cs_send = lscreen_write;
|
||||
cs->cs_sendpolled = lscreen_write;
|
||||
|
||||
ls->ls_devdata = cs;
|
||||
ls->ls_start = con_start;
|
||||
ls->ls_input = con_input;
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
61
kern/dev/lamebus/con_lser.c
Normal file
61
kern/dev/lamebus/con_lser.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Attachment code for having the generic console device use the LAMEbus
|
||||
* serial device.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <generic/console.h>
|
||||
#include <lamebus/lser.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
struct con_softc *
|
||||
attach_con_to_lser(int consno, struct lser_softc *ls)
|
||||
{
|
||||
struct con_softc *cs = kmalloc(sizeof(struct con_softc));
|
||||
if (cs==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)consno; // unused
|
||||
|
||||
cs->cs_devdata = ls;
|
||||
cs->cs_send = lser_write;
|
||||
cs->cs_sendpolled = lser_writepolled;
|
||||
|
||||
ls->ls_devdata = cs;
|
||||
ls->ls_start = con_start;
|
||||
ls->ls_input = con_input;
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
57
kern/dev/lamebus/conf.lamebus
Normal file
57
kern/dev/lamebus/conf.lamebus
Normal file
@@ -0,0 +1,57 @@
|
||||
#
|
||||
# Kernel config definitions for LAMEbus devices.
|
||||
#
|
||||
# See conf/conf.kern for more information.
|
||||
#
|
||||
|
||||
# System main bus.
|
||||
defdevice lamebus dev/lamebus/lamebus.c
|
||||
|
||||
# Timer.
|
||||
defdevice ltimer dev/lamebus/ltimer.c
|
||||
defattach ltimer* lamebus* dev/lamebus/ltimer_att.c
|
||||
|
||||
# Random.
|
||||
defdevice lrandom dev/lamebus/lrandom.c
|
||||
defattach lrandom* lamebus* dev/lamebus/lrandom_att.c
|
||||
|
||||
# Disk.
|
||||
defdevice lhd dev/lamebus/lhd.c
|
||||
defattach lhd* lamebus* dev/lamebus/lhd_att.c
|
||||
|
||||
# Serial port.
|
||||
defdevice lser dev/lamebus/lser.c
|
||||
defattach lser* lamebus* dev/lamebus/lser_att.c
|
||||
|
||||
# Text screen.
|
||||
defdevice lscreen dev/lamebus/lscreen.c
|
||||
defattach lscreen* lamebus* dev/lamebus/lscreen_att.c
|
||||
|
||||
# Network interface.
|
||||
defdevice lnet dev/lamebus/lnet.c
|
||||
defattach lnet* lamebus* dev/lamebus/lnet_att.c
|
||||
|
||||
# Trace control device.
|
||||
defdevice ltrace dev/lamebus/ltrace.c
|
||||
defattach ltrace* lamebus* dev/lamebus/ltrace_att.c
|
||||
|
||||
# Emulator passthrough filesystem.
|
||||
defdevice emu dev/lamebus/emu.c
|
||||
defattach emu* lamebus* dev/lamebus/emu_att.c
|
||||
|
||||
#
|
||||
# Attachments to generic interface devices
|
||||
#
|
||||
|
||||
# Consoles.
|
||||
defattach con0 lser* dev/lamebus/con_lser.c
|
||||
defattach con0 lscreen* dev/lamebus/con_lscreen.c
|
||||
|
||||
# Beeper.
|
||||
defattach beep* ltimer* dev/lamebus/beep_ltimer.c
|
||||
|
||||
# Clock.
|
||||
defattach rtclock* ltimer* dev/lamebus/rtclock_ltimer.c
|
||||
|
||||
# Random.
|
||||
defattach random0 lrandom* dev/lamebus/random_lrandom.c
|
1357
kern/dev/lamebus/emu.c
Normal file
1357
kern/dev/lamebus/emu.c
Normal file
File diff suppressed because it is too large
Load Diff
62
kern/dev/lamebus/emu.h
Normal file
62
kern/dev/lamebus/emu.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_EMU_H_
|
||||
#define _LAMEBUS_EMU_H_
|
||||
|
||||
|
||||
#define EMU_MAXIO 16384
|
||||
#define EMU_ROOTHANDLE 0
|
||||
|
||||
/*
|
||||
* The per-device data used by the emufs device driver.
|
||||
* (Note that this is only a small portion of its actual data;
|
||||
* all the filesystem stuff goes elsewhere.
|
||||
*/
|
||||
|
||||
struct emu_softc {
|
||||
/* Initialized by lower-level attach code */
|
||||
void *e_busdata;
|
||||
uint32_t e_buspos;
|
||||
int e_unit;
|
||||
|
||||
/* Initialized by config_emu() */
|
||||
struct lock *e_lock;
|
||||
struct semaphore *e_sem;
|
||||
void *e_iobuf;
|
||||
|
||||
/* Written by the interrupt handler */
|
||||
uint32_t e_result;
|
||||
};
|
||||
|
||||
/* Functions called by lower-level drivers */
|
||||
void emu_irq(/*struct emu_softc*/ void *);
|
||||
|
||||
|
||||
#endif /* _LAMEBUS_EMU_H_ */
|
66
kern/dev/lamebus/emu_att.c
Normal file
66
kern/dev/lamebus/emu_att.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code for probe/attach of the emu device to lamebus.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/emu.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
|
||||
struct emu_softc *
|
||||
attach_emu_to_lamebus(int emuno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct emu_softc *es;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_EMUFS,
|
||||
LOW_VERSION, NULL);
|
||||
if (slot < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
es = kmalloc(sizeof(struct emu_softc));
|
||||
if (es==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
es->e_busdata = sc;
|
||||
es->e_buspos = slot;
|
||||
es->e_unit = emuno;
|
||||
|
||||
lamebus_mark(sc, slot);
|
||||
lamebus_attach_interrupt(sc, slot, es, emu_irq);
|
||||
|
||||
return es;
|
||||
}
|
665
kern/dev/lamebus/lamebus.c
Normal file
665
kern/dev/lamebus/lamebus.c
Normal file
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-independent LAMEbus code.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <cpu.h>
|
||||
#include <membar.h>
|
||||
#include <spinlock.h>
|
||||
#include <current.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
|
||||
/* Register offsets within each config region */
|
||||
#define CFGREG_VID 0 /* Vendor ID */
|
||||
#define CFGREG_DID 4 /* Device ID */
|
||||
#define CFGREG_DRL 8 /* Device Revision Level */
|
||||
|
||||
/* LAMEbus controller private registers (offsets within its config region) */
|
||||
#define CTLREG_RAMSZ 0x200
|
||||
#define CTLREG_IRQS 0x204
|
||||
#define CTLREG_PWR 0x208
|
||||
#define CTLREG_IRQE 0x20c
|
||||
#define CTLREG_CPUS 0x210
|
||||
#define CTLREG_CPUE 0x214
|
||||
#define CTLREG_SELF 0x218
|
||||
|
||||
/* LAMEbus CPU control registers (offsets within each per-cpu region) */
|
||||
#define CTLCPU_CIRQE 0x000
|
||||
#define CTLCPU_CIPI 0x004
|
||||
#define CTLCPU_CRAM 0x300
|
||||
|
||||
|
||||
/*
|
||||
* Read a config register for the given slot.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
uint32_t
|
||||
read_cfg_register(struct lamebus_softc *lb, int slot, uint32_t offset)
|
||||
{
|
||||
/* Note that lb might be NULL on some platforms in some contexts. */
|
||||
offset += LB_CONFIG_SIZE*slot;
|
||||
return lamebus_read_register(lb, LB_CONTROLLER_SLOT, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a config register for a given slot.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
void
|
||||
write_cfg_register(struct lamebus_softc *lb, int slot, uint32_t offset,
|
||||
uint32_t val)
|
||||
{
|
||||
offset += LB_CONFIG_SIZE*slot;
|
||||
lamebus_write_register(lb, LB_CONTROLLER_SLOT, offset, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read one of the bus controller's registers.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
uint32_t
|
||||
read_ctl_register(struct lamebus_softc *lb, uint32_t offset)
|
||||
{
|
||||
/* Note that lb might be NULL on some platforms in some contexts. */
|
||||
return read_cfg_register(lb, LB_CONTROLLER_SLOT, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one of the bus controller's registers.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
void
|
||||
write_ctl_register(struct lamebus_softc *lb, uint32_t offset, uint32_t val)
|
||||
{
|
||||
write_cfg_register(lb, LB_CONTROLLER_SLOT, offset, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one of the bus controller's CPU control registers.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
void
|
||||
write_ctlcpu_register(struct lamebus_softc *lb, unsigned hw_cpunum,
|
||||
uint32_t offset, uint32_t val)
|
||||
{
|
||||
offset += LB_CTLCPU_OFFSET + hw_cpunum * LB_CTLCPU_SIZE;
|
||||
lamebus_write_register(lb, LB_CONTROLLER_SLOT, offset, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find and create secondary CPUs.
|
||||
*/
|
||||
void
|
||||
lamebus_find_cpus(struct lamebus_softc *lamebus)
|
||||
{
|
||||
uint32_t mainboard_vid, mainboard_did;
|
||||
uint32_t cpumask, self, bit, val;
|
||||
unsigned i, numcpus, bootcpu;
|
||||
unsigned hwnum[32];
|
||||
|
||||
mainboard_vid = read_cfg_register(lamebus, LB_CONTROLLER_SLOT,
|
||||
CFGREG_VID);
|
||||
mainboard_did = read_cfg_register(lamebus, LB_CONTROLLER_SLOT,
|
||||
CFGREG_DID);
|
||||
if (mainboard_vid == LB_VENDOR_CS161 &&
|
||||
mainboard_did == LBCS161_UPBUSCTL) {
|
||||
/* Old uniprocessor mainboard; no cpu registers. */
|
||||
lamebus->ls_uniprocessor = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
cpumask = read_ctl_register(lamebus, CTLREG_CPUS);
|
||||
self = read_ctl_register(lamebus, CTLREG_SELF);
|
||||
|
||||
numcpus = 0;
|
||||
bootcpu = 0;
|
||||
for (i=0; i<32; i++) {
|
||||
bit = (uint32_t)1 << i;
|
||||
if ((cpumask & bit) != 0) {
|
||||
if (self & bit) {
|
||||
bootcpu = numcpus;
|
||||
curcpu->c_hardware_number = i;
|
||||
}
|
||||
hwnum[numcpus] = i;
|
||||
numcpus++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<numcpus; i++) {
|
||||
if (i != bootcpu) {
|
||||
cpu_create(hwnum[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* By default, route all interrupts only to the boot cpu. We
|
||||
* could be arbitrarily more elaborate, up to things like
|
||||
* dynamic load balancing.
|
||||
*/
|
||||
|
||||
for (i=0; i<numcpus; i++) {
|
||||
if (i != bootcpu) {
|
||||
val = 0;
|
||||
}
|
||||
else {
|
||||
val = 0xffffffff;
|
||||
}
|
||||
write_ctlcpu_register(lamebus, hwnum[i], CTLCPU_CIRQE, val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start up secondary CPUs.
|
||||
*
|
||||
* The first word of the CRAM area is set to the entry point for new
|
||||
* CPUs; the second to the (software) CPU number. Note that the logic
|
||||
* here assumes the boot CPU is CPU 0 and the others are 1-N as
|
||||
* created in the function above. This is fine if all CPUs are on
|
||||
* LAMEbus; if in some environment there are other CPUs about as well
|
||||
* this logic will have to be made more complex.
|
||||
*/
|
||||
void
|
||||
lamebus_start_cpus(struct lamebus_softc *lamebus)
|
||||
{
|
||||
uint32_t cpumask, self, bit;
|
||||
uint32_t ctlcpuoffset;
|
||||
uint32_t *cram;
|
||||
unsigned i;
|
||||
unsigned cpunum;
|
||||
|
||||
if (lamebus->ls_uniprocessor) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpumask = read_ctl_register(lamebus, CTLREG_CPUS);
|
||||
self = read_ctl_register(lamebus, CTLREG_SELF);
|
||||
|
||||
/* Poke in the startup address. */
|
||||
cpunum = 1;
|
||||
for (i=0; i<32; i++) {
|
||||
bit = (uint32_t)1 << i;
|
||||
if ((cpumask & bit) != 0) {
|
||||
if (self & bit) {
|
||||
continue;
|
||||
}
|
||||
ctlcpuoffset = LB_CTLCPU_OFFSET + i * LB_CTLCPU_SIZE;
|
||||
cram = lamebus_map_area(lamebus,
|
||||
LB_CONTROLLER_SLOT,
|
||||
ctlcpuoffset + CTLCPU_CRAM);
|
||||
cram[0] = (uint32_t)cpu_start_secondary;
|
||||
cram[1] = cpunum++;
|
||||
}
|
||||
}
|
||||
/* Ensure all the above writes get flushed. */
|
||||
membar_store_store();
|
||||
|
||||
/* Now, enable them all. */
|
||||
write_ctl_register(lamebus, CTLREG_CPUE, cpumask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe function.
|
||||
*
|
||||
* Given a LAMEbus, look for a device that's not already been marked
|
||||
* in use, has the specified IDs, and has a device revision level at
|
||||
* least as high as the minimum specified.
|
||||
*
|
||||
* Returns the slot number found (0-31) or -1 if nothing suitable was
|
||||
* found.
|
||||
*
|
||||
* If VERSION_RET is not null, return the device version found. This
|
||||
* allows drivers to blacklist specific versions or otherwise conduct
|
||||
* more specific checks.
|
||||
*/
|
||||
|
||||
int
|
||||
lamebus_probe(struct lamebus_softc *sc,
|
||||
uint32_t vendorid, uint32_t deviceid,
|
||||
uint32_t lowver, uint32_t *version_ret)
|
||||
{
|
||||
int slot;
|
||||
uint32_t val;
|
||||
|
||||
/*
|
||||
* Because the slot information in sc is used when dispatching
|
||||
* interrupts, disable interrupts while working with it.
|
||||
*/
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
for (slot=0; slot<LB_NSLOTS; slot++) {
|
||||
if (sc->ls_slotsinuse & (1<<slot)) {
|
||||
/* Slot already in use; skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
val = read_cfg_register(sc, slot, CFGREG_VID);
|
||||
if (val!=vendorid) {
|
||||
/* Wrong vendor id */
|
||||
continue;
|
||||
}
|
||||
|
||||
val = read_cfg_register(sc, slot, CFGREG_DID);
|
||||
if (val != deviceid) {
|
||||
/* Wrong device id */
|
||||
continue;
|
||||
}
|
||||
|
||||
val = read_cfg_register(sc, slot, CFGREG_DRL);
|
||||
if (val < lowver) {
|
||||
/* Unsupported device revision */
|
||||
continue;
|
||||
}
|
||||
if (version_ret != NULL) {
|
||||
*version_ret = val;
|
||||
}
|
||||
|
||||
/* Found something */
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
return slot;
|
||||
}
|
||||
|
||||
/* Found nothing */
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark that a slot is in use.
|
||||
* This prevents the probe routine from returning the same device over
|
||||
* and over again.
|
||||
*/
|
||||
void
|
||||
lamebus_mark(struct lamebus_softc *sc, int slot)
|
||||
{
|
||||
uint32_t mask = ((uint32_t)1) << slot;
|
||||
KASSERT(slot>=0 && slot < LB_NSLOTS);
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
if ((sc->ls_slotsinuse & mask)!=0) {
|
||||
panic("lamebus_mark: slot %d already in use\n", slot);
|
||||
}
|
||||
|
||||
sc->ls_slotsinuse |= mask;
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark that a slot is no longer in use.
|
||||
*/
|
||||
void
|
||||
lamebus_unmark(struct lamebus_softc *sc, int slot)
|
||||
{
|
||||
uint32_t mask = ((uint32_t)1) << slot;
|
||||
KASSERT(slot>=0 && slot < LB_NSLOTS);
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
if ((sc->ls_slotsinuse & mask)==0) {
|
||||
panic("lamebus_mark: slot %d not marked in use\n", slot);
|
||||
}
|
||||
|
||||
sc->ls_slotsinuse &= ~mask;
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a function (and a device context pointer) to be called
|
||||
* when a particular slot signals an interrupt.
|
||||
*/
|
||||
void
|
||||
lamebus_attach_interrupt(struct lamebus_softc *sc, int slot,
|
||||
void *devdata,
|
||||
void (*irqfunc)(void *devdata))
|
||||
{
|
||||
uint32_t mask = ((uint32_t)1) << slot;
|
||||
KASSERT(slot>=0 && slot < LB_NSLOTS);
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
if ((sc->ls_slotsinuse & mask)==0) {
|
||||
panic("lamebus_attach_interrupt: slot %d not marked in use\n",
|
||||
slot);
|
||||
}
|
||||
|
||||
KASSERT(sc->ls_devdata[slot]==NULL);
|
||||
KASSERT(sc->ls_irqfuncs[slot]==NULL);
|
||||
|
||||
sc->ls_devdata[slot] = devdata;
|
||||
sc->ls_irqfuncs[slot] = irqfunc;
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unregister a function that was being called when a particular slot
|
||||
* signaled an interrupt.
|
||||
*/
|
||||
void
|
||||
lamebus_detach_interrupt(struct lamebus_softc *sc, int slot)
|
||||
{
|
||||
uint32_t mask = ((uint32_t)1) << slot;
|
||||
KASSERT(slot>=0 && slot < LB_NSLOTS);
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
if ((sc->ls_slotsinuse & mask)==0) {
|
||||
panic("lamebus_detach_interrupt: slot %d not marked in use\n",
|
||||
slot);
|
||||
}
|
||||
|
||||
KASSERT(sc->ls_irqfuncs[slot]!=NULL);
|
||||
|
||||
sc->ls_devdata[slot] = NULL;
|
||||
sc->ls_irqfuncs[slot] = NULL;
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask/unmask an interrupt using the global IRQE register.
|
||||
*/
|
||||
void
|
||||
lamebus_mask_interrupt(struct lamebus_softc *lamebus, int slot)
|
||||
{
|
||||
uint32_t bits, mask = ((uint32_t)1) << slot;
|
||||
KASSERT(slot >= 0 && slot < LB_NSLOTS);
|
||||
|
||||
spinlock_acquire(&lamebus->ls_lock);
|
||||
bits = read_ctl_register(lamebus, CTLREG_IRQE);
|
||||
bits &= ~mask;
|
||||
write_ctl_register(lamebus, CTLREG_IRQE, bits);
|
||||
spinlock_release(&lamebus->ls_lock);
|
||||
}
|
||||
|
||||
void
|
||||
lamebus_unmask_interrupt(struct lamebus_softc *lamebus, int slot)
|
||||
{
|
||||
uint32_t bits, mask = ((uint32_t)1) << slot;
|
||||
KASSERT(slot >= 0 && slot < LB_NSLOTS);
|
||||
|
||||
spinlock_acquire(&lamebus->ls_lock);
|
||||
bits = read_ctl_register(lamebus, CTLREG_IRQE);
|
||||
bits |= mask;
|
||||
write_ctl_register(lamebus, CTLREG_IRQE, bits);
|
||||
spinlock_release(&lamebus->ls_lock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LAMEbus interrupt handling function. (Machine-independent!)
|
||||
*/
|
||||
void
|
||||
lamebus_interrupt(struct lamebus_softc *lamebus)
|
||||
{
|
||||
/*
|
||||
* Note that despite the fact that "spl" stands for "set
|
||||
* priority level", we don't actually support interrupt
|
||||
* priorities. When an interrupt happens, we look through the
|
||||
* slots to find the first interrupting device and call its
|
||||
* interrupt routine, no matter what that device is.
|
||||
*
|
||||
* Note that the entire LAMEbus uses only one on-cpu interrupt line.
|
||||
* Thus, we do not use any on-cpu interrupt priority system either.
|
||||
*/
|
||||
|
||||
int slot;
|
||||
uint32_t mask;
|
||||
uint32_t irqs;
|
||||
void (*handler)(void *);
|
||||
void *data;
|
||||
|
||||
/* For keeping track of how many bogus things happen in a row. */
|
||||
static int duds = 0;
|
||||
int duds_this_time = 0;
|
||||
|
||||
/* and we better have a valid bus instance. */
|
||||
KASSERT(lamebus != NULL);
|
||||
|
||||
/* Lock the softc */
|
||||
spinlock_acquire(&lamebus->ls_lock);
|
||||
|
||||
/*
|
||||
* Read the LAMEbus controller register that tells us which
|
||||
* slots are asserting an interrupt condition.
|
||||
*/
|
||||
irqs = read_ctl_register(lamebus, CTLREG_IRQS);
|
||||
|
||||
if (irqs == 0) {
|
||||
/*
|
||||
* Huh? None of them? Must be a glitch.
|
||||
*/
|
||||
kprintf("lamebus: stray interrupt on cpu %u\n",
|
||||
curcpu->c_number);
|
||||
duds++;
|
||||
duds_this_time++;
|
||||
|
||||
/*
|
||||
* We could just return now, but instead we'll
|
||||
* continue ahead. Because irqs == 0, nothing in the
|
||||
* loop will execute, and passing through it gets us
|
||||
* to the code that checks how many duds we've
|
||||
* seen. This is important, because we just might get
|
||||
* a stray interrupt that latches itself on. If that
|
||||
* happens, we're pretty much toast, but it's better
|
||||
* to panic and hopefully reset the system than to
|
||||
* loop forever printing "stray interrupt".
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through the bits in the value we got back to see which
|
||||
* ones are set.
|
||||
*/
|
||||
|
||||
for (mask=1, slot=0; slot<LB_NSLOTS; mask<<=1, slot++) {
|
||||
if ((irqs & mask) == 0) {
|
||||
/* Nope. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* This slot is signalling an interrupt.
|
||||
*/
|
||||
|
||||
if ((lamebus->ls_slotsinuse & mask)==0) {
|
||||
/*
|
||||
* No device driver is using this slot.
|
||||
*/
|
||||
duds++;
|
||||
duds_this_time++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lamebus->ls_irqfuncs[slot]==NULL) {
|
||||
/*
|
||||
* The device driver hasn't installed an interrupt
|
||||
* handler.
|
||||
*/
|
||||
duds++;
|
||||
duds_this_time++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the interrupt handler. Release the spinlock
|
||||
* while we do so, in case other CPUs are handling
|
||||
* interrupts on other devices.
|
||||
*/
|
||||
handler = lamebus->ls_irqfuncs[slot];
|
||||
data = lamebus->ls_devdata[slot];
|
||||
spinlock_release(&lamebus->ls_lock);
|
||||
|
||||
handler(data);
|
||||
|
||||
spinlock_acquire(&lamebus->ls_lock);
|
||||
|
||||
/*
|
||||
* Reload the mask of pending IRQs - if we just called
|
||||
* hardclock, we might not have come back to this
|
||||
* context for some time, and it might have changed.
|
||||
*/
|
||||
|
||||
irqs = read_ctl_register(lamebus, CTLREG_IRQS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we get interrupts for a slot with no driver or no
|
||||
* interrupt handler, it's fairly serious. Because LAMEbus
|
||||
* uses level-triggered interrupts, if we don't shut off the
|
||||
* condition, we'll keep getting interrupted continuously and
|
||||
* the system will make no progress. But we don't know how to
|
||||
* do that if there's no driver or no interrupt handler.
|
||||
*
|
||||
* So, if we get too many dud interrupts, panic, since it's
|
||||
* better to panic and reset than to hang.
|
||||
*
|
||||
* If we get through here without seeing any duds this time,
|
||||
* the condition, whatever it was, has gone away. It might be
|
||||
* some stupid device we don't have a driver for, or it might
|
||||
* have been an electrical transient. In any case, warn and
|
||||
* clear the dud count.
|
||||
*/
|
||||
|
||||
if (duds_this_time == 0 && duds > 0) {
|
||||
kprintf("lamebus: %d dud interrupts\n", duds);
|
||||
duds = 0;
|
||||
}
|
||||
|
||||
if (duds > 10000) {
|
||||
panic("lamebus: too many (%d) dud interrupts\n", duds);
|
||||
}
|
||||
|
||||
/* Unlock the softc */
|
||||
spinlock_release(&lamebus->ls_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Have the bus controller power the system off.
|
||||
*/
|
||||
void
|
||||
lamebus_poweroff(struct lamebus_softc *lamebus)
|
||||
{
|
||||
/*
|
||||
* Write 0 to the power register to shut the system off.
|
||||
*/
|
||||
|
||||
cpu_irqoff();
|
||||
write_ctl_register(lamebus, CTLREG_PWR, 0);
|
||||
|
||||
/* The power doesn't go off instantly... so halt the cpu. */
|
||||
cpu_halt();
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask the bus controller how much memory we have.
|
||||
*/
|
||||
uint32_t
|
||||
lamebus_ramsize(void)
|
||||
{
|
||||
/*
|
||||
* Note that this has to work before bus initialization.
|
||||
* On machines where lamebus_read_register doesn't work
|
||||
* before bus initialization, this function can't be used
|
||||
* for initial RAM size lookup.
|
||||
*/
|
||||
|
||||
return read_ctl_register(NULL, CTLREG_RAMSZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn on or off the interprocessor interrupt line for a given CPU.
|
||||
*/
|
||||
void
|
||||
lamebus_assert_ipi(struct lamebus_softc *lamebus, struct cpu *target)
|
||||
{
|
||||
if (lamebus->ls_uniprocessor) {
|
||||
return;
|
||||
}
|
||||
write_ctlcpu_register(lamebus, target->c_hardware_number,
|
||||
CTLCPU_CIPI, 1);
|
||||
}
|
||||
|
||||
void
|
||||
lamebus_clear_ipi(struct lamebus_softc *lamebus, struct cpu *target)
|
||||
{
|
||||
if (lamebus->ls_uniprocessor) {
|
||||
return;
|
||||
}
|
||||
write_ctlcpu_register(lamebus, target->c_hardware_number,
|
||||
CTLCPU_CIPI, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial setup.
|
||||
* Should be called from mainbus_bootstrap().
|
||||
*/
|
||||
struct lamebus_softc *
|
||||
lamebus_init(void)
|
||||
{
|
||||
struct lamebus_softc *lamebus;
|
||||
int i;
|
||||
|
||||
/* Allocate space for lamebus data */
|
||||
lamebus = kmalloc(sizeof(struct lamebus_softc));
|
||||
if (lamebus==NULL) {
|
||||
panic("lamebus_init: Out of memory\n");
|
||||
}
|
||||
|
||||
spinlock_init(&lamebus->ls_lock);
|
||||
|
||||
/*
|
||||
* Initialize the LAMEbus data structure.
|
||||
*/
|
||||
lamebus->ls_slotsinuse = 1 << LB_CONTROLLER_SLOT;
|
||||
|
||||
for (i=0; i<LB_NSLOTS; i++) {
|
||||
lamebus->ls_devdata[i] = NULL;
|
||||
lamebus->ls_irqfuncs[i] = NULL;
|
||||
}
|
||||
|
||||
lamebus->ls_uniprocessor = 0;
|
||||
|
||||
return lamebus;
|
||||
}
|
182
kern/dev/lamebus/lamebus.h
Normal file
182
kern/dev/lamebus/lamebus.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_H_
|
||||
#define _LAMEBUS_H_
|
||||
|
||||
#include <cpu.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
/*
|
||||
* Linear Always Mapped Extents
|
||||
*
|
||||
* Machine-independent definitions.
|
||||
*/
|
||||
|
||||
|
||||
/* Vendors */
|
||||
#define LB_VENDOR_CS161 1
|
||||
|
||||
/* CS161 devices */
|
||||
#define LBCS161_UPBUSCTL 1
|
||||
#define LBCS161_TIMER 2
|
||||
#define LBCS161_DISK 3
|
||||
#define LBCS161_SERIAL 4
|
||||
#define LBCS161_SCREEN 5
|
||||
#define LBCS161_NET 6
|
||||
#define LBCS161_EMUFS 7
|
||||
#define LBCS161_TRACE 8
|
||||
#define LBCS161_RANDOM 9
|
||||
#define LBCS161_MPBUSCTL 10
|
||||
|
||||
/* LAMEbus controller always goes in slot 31 */
|
||||
#define LB_CONTROLLER_SLOT 31
|
||||
|
||||
/* Number of slots */
|
||||
#define LB_NSLOTS 32
|
||||
|
||||
/* LAMEbus controller per-slot config space */
|
||||
#define LB_CONFIG_SIZE 1024
|
||||
|
||||
/* LAMEbus controller per-cpu control space */
|
||||
#define LB_CTLCPU_SIZE 1024
|
||||
|
||||
/* LAMEbus controller slot offset to per-cpu control space */
|
||||
#define LB_CTLCPU_OFFSET 32768
|
||||
|
||||
/* LAMEbus mapping size per slot */
|
||||
#define LB_SLOT_SIZE 65536
|
||||
|
||||
/* Pointer to kind of function called on interrupt */
|
||||
typedef void (*lb_irqfunc)(void *devdata);
|
||||
|
||||
/*
|
||||
* Driver data
|
||||
*/
|
||||
struct lamebus_softc {
|
||||
struct spinlock ls_lock;
|
||||
|
||||
/* Accessed from interrupts; synchronized with ls_lock */
|
||||
uint32_t ls_slotsinuse;
|
||||
void *ls_devdata[LB_NSLOTS];
|
||||
lb_irqfunc ls_irqfuncs[LB_NSLOTS];
|
||||
|
||||
/* Read-only once set early in boot */
|
||||
unsigned ls_uniprocessor;
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate and set up a lamebus_softc for the system.
|
||||
*/
|
||||
struct lamebus_softc *lamebus_init(void);
|
||||
|
||||
/*
|
||||
* Search for and create cpu structures for the CPUs on the mainboard.
|
||||
*/
|
||||
void lamebus_find_cpus(struct lamebus_softc *lamebus);
|
||||
|
||||
/*
|
||||
* Start up secondary CPUs.
|
||||
*/
|
||||
void lamebus_start_cpus(struct lamebus_softc *lamebus);
|
||||
|
||||
/*
|
||||
* Look for a not-in-use slot containing a device whose vendor and device
|
||||
* ids match those provided, and whose version is in the range between
|
||||
* lowver and highver, inclusive.
|
||||
*
|
||||
* Returns a slot number (0-31) or -1 if no such device is found.
|
||||
*/
|
||||
int lamebus_probe(struct lamebus_softc *,
|
||||
uint32_t vendorid, uint32_t deviceid,
|
||||
uint32_t lowver, uint32_t *version_ret);
|
||||
|
||||
/*
|
||||
* Mark a slot in-use (that is, has a device driver attached to it),
|
||||
* or unmark it. It is a fatal error to mark a slot that is already
|
||||
* in use, or unmark a slot that is not in use.
|
||||
*/
|
||||
void lamebus_mark(struct lamebus_softc *, int slot);
|
||||
void lamebus_unmark(struct lamebus_softc *, int slot);
|
||||
|
||||
/*
|
||||
* Attach to an interrupt.
|
||||
*/
|
||||
void lamebus_attach_interrupt(struct lamebus_softc *, int slot,
|
||||
void *devdata,
|
||||
void (*irqfunc)(void *devdata));
|
||||
/*
|
||||
* Detach from interrupt.
|
||||
*/
|
||||
void lamebus_detach_interrupt(struct lamebus_softc *, int slot);
|
||||
|
||||
/*
|
||||
* Mask/unmask an interrupt.
|
||||
*/
|
||||
void lamebus_mask_interrupt(struct lamebus_softc *, int slot);
|
||||
void lamebus_unmask_interrupt(struct lamebus_softc *, int slot);
|
||||
|
||||
/*
|
||||
* Function to call to handle a LAMEbus interrupt.
|
||||
*/
|
||||
void lamebus_interrupt(struct lamebus_softc *);
|
||||
|
||||
/*
|
||||
* Have the LAMEbus controller power the system off.
|
||||
*/
|
||||
void lamebus_poweroff(struct lamebus_softc *);
|
||||
|
||||
/*
|
||||
* Ask the bus controller how much memory we have.
|
||||
*/
|
||||
size_t lamebus_ramsize(void);
|
||||
|
||||
/*
|
||||
* Turn on or off the inter-processor interrupt line to a CPU.
|
||||
*/
|
||||
void lamebus_assert_ipi(struct lamebus_softc *, struct cpu *targetcpu);
|
||||
void lamebus_clear_ipi(struct lamebus_softc *, struct cpu *targetcpu);
|
||||
|
||||
/*
|
||||
* Read/write 32-bit register at offset OFFSET within slot SLOT.
|
||||
* (Machine dependent.)
|
||||
*/
|
||||
uint32_t lamebus_read_register(struct lamebus_softc *, int slot,
|
||||
uint32_t offset);
|
||||
void lamebus_write_register(struct lamebus_softc *, int slot,
|
||||
uint32_t offset, uint32_t val);
|
||||
|
||||
/*
|
||||
* Map a buffer that starts at offset OFFSET within slot SLOT.
|
||||
*/
|
||||
void *lamebus_map_area(struct lamebus_softc *, int slot,
|
||||
uint32_t offset);
|
||||
|
||||
|
||||
#endif /* _LAMEBUS_H_ */
|
308
kern/dev/lamebus/lhd.c
Normal file
308
kern/dev/lamebus/lhd.c
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* LAMEbus hard disk (lhd) driver.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <kern/errno.h>
|
||||
#include <lib.h>
|
||||
#include <uio.h>
|
||||
#include <membar.h>
|
||||
#include <synch.h>
|
||||
#include <platform/bus.h>
|
||||
#include <vfs.h>
|
||||
#include <lamebus/lhd.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Registers (offsets within slot) */
|
||||
#define LHD_REG_NSECT 0 /* Number of sectors */
|
||||
#define LHD_REG_STAT 4 /* Status */
|
||||
#define LHD_REG_SECT 8 /* Sector for I/O */
|
||||
#define LHD_REG_RPM 12 /* Disk rotation speed (revs per minute) */
|
||||
|
||||
/* Status codes */
|
||||
#define LHD_IDLE 0 /* Device idle */
|
||||
#define LHD_WORKING 1 /* Operation in progress */
|
||||
#define LHD_OK 4 /* Operation succeeded */
|
||||
#define LHD_INVSECT 12 /* Invalid sector requested */
|
||||
#define LHD_MEDIA 20 /* Media error */
|
||||
#define LHD_ISWRITE 2 /* OR with above: I/O is a write */
|
||||
#define LHD_STATEMASK 0x1d /* mask for masking out LHD_ISWRITE */
|
||||
|
||||
/* Buffer (offset within slot) */
|
||||
#define LHD_BUFFER 32768
|
||||
|
||||
/*
|
||||
* Shortcut for reading a register.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
uint32_t lhd_rdreg(struct lhd_softc *lh, uint32_t reg)
|
||||
{
|
||||
return bus_read_register(lh->lh_busdata, lh->lh_buspos, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shortcut for writing a register.
|
||||
*/
|
||||
static
|
||||
inline
|
||||
void lhd_wreg(struct lhd_softc *lh, uint32_t reg, uint32_t val)
|
||||
{
|
||||
bus_write_register(lh->lh_busdata, lh->lh_buspos, reg, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a result code from the hardware to an errno value.
|
||||
*/
|
||||
static
|
||||
int lhd_code_to_errno(struct lhd_softc *lh, int code)
|
||||
{
|
||||
switch (code & LHD_STATEMASK) {
|
||||
case LHD_OK: return 0;
|
||||
case LHD_INVSECT: return EINVAL;
|
||||
case LHD_MEDIA: return EIO;
|
||||
}
|
||||
kprintf("lhd%d: Unknown result code %d\n", lh->lh_unit, code);
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record that an I/O has completed: save the result and poke the
|
||||
* completion semaphore.
|
||||
*/
|
||||
static
|
||||
void
|
||||
lhd_iodone(struct lhd_softc *lh, int err)
|
||||
{
|
||||
lh->lh_result = err;
|
||||
V(lh->lh_done);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler for lhd.
|
||||
* Read the status register; if an operation finished, clear the status
|
||||
* register and report completion.
|
||||
*/
|
||||
void
|
||||
lhd_irq(void *vlh)
|
||||
{
|
||||
struct lhd_softc *lh = vlh;
|
||||
uint32_t val;
|
||||
|
||||
val = lhd_rdreg(lh, LHD_REG_STAT);
|
||||
|
||||
switch (val & LHD_STATEMASK) {
|
||||
case LHD_IDLE:
|
||||
case LHD_WORKING:
|
||||
break;
|
||||
case LHD_OK:
|
||||
case LHD_INVSECT:
|
||||
case LHD_MEDIA:
|
||||
lhd_wreg(lh, LHD_REG_STAT, 0);
|
||||
lhd_iodone(lh, lhd_code_to_errno(lh, val));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function called when we are open()'d.
|
||||
*/
|
||||
static
|
||||
int
|
||||
lhd_eachopen(struct device *d, int openflags)
|
||||
{
|
||||
/*
|
||||
* Don't need to do anything.
|
||||
*/
|
||||
(void)d;
|
||||
(void)openflags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function for handling ioctls.
|
||||
*/
|
||||
static
|
||||
int
|
||||
lhd_ioctl(struct device *d, int op, userptr_t data)
|
||||
{
|
||||
/*
|
||||
* We don't support any ioctls.
|
||||
*/
|
||||
(void)d;
|
||||
(void)op;
|
||||
(void)data;
|
||||
return EIOCTL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Reset the device.
|
||||
* This could be used, for instance, on timeout, if you implement suitable
|
||||
* facilities.
|
||||
*/
|
||||
static
|
||||
void
|
||||
lhd_reset(struct lhd_softc *lh)
|
||||
{
|
||||
lhd_wreg(lh, LHD_REG_STAT, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I/O function (for both reads and writes)
|
||||
*/
|
||||
static
|
||||
int
|
||||
lhd_io(struct device *d, struct uio *uio)
|
||||
{
|
||||
struct lhd_softc *lh = d->d_data;
|
||||
|
||||
uint32_t sector = uio->uio_offset / LHD_SECTSIZE;
|
||||
uint32_t sectoff = uio->uio_offset % LHD_SECTSIZE;
|
||||
uint32_t len = uio->uio_resid / LHD_SECTSIZE;
|
||||
uint32_t lenoff = uio->uio_resid % LHD_SECTSIZE;
|
||||
uint32_t i;
|
||||
uint32_t statval = LHD_WORKING;
|
||||
int result;
|
||||
|
||||
/* Don't allow I/O that isn't sector-aligned. */
|
||||
if (sectoff != 0 || lenoff != 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Don't allow I/O past the end of the disk. */
|
||||
/* XXX this check can overflow */
|
||||
if (sector+len > lh->lh_dev.d_blocks) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Set up the value to write into the status register. */
|
||||
if (uio->uio_rw==UIO_WRITE) {
|
||||
statval |= LHD_ISWRITE;
|
||||
}
|
||||
|
||||
/* Loop over all the sectors we were asked to do. */
|
||||
for (i=0; i<len; i++) {
|
||||
|
||||
/* Wait until nobody else is using the device. */
|
||||
P(lh->lh_clear);
|
||||
|
||||
/*
|
||||
* Are we writing? If so, transfer the data to the
|
||||
* on-card buffer.
|
||||
*/
|
||||
if (uio->uio_rw == UIO_WRITE) {
|
||||
result = uiomove(lh->lh_buf, LHD_SECTSIZE, uio);
|
||||
membar_store_store();
|
||||
if (result) {
|
||||
V(lh->lh_clear);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell it what sector we want... */
|
||||
lhd_wreg(lh, LHD_REG_SECT, sector+i);
|
||||
|
||||
/* and start the operation. */
|
||||
lhd_wreg(lh, LHD_REG_STAT, statval);
|
||||
|
||||
/* Now wait until the interrupt handler tells us we're done. */
|
||||
P(lh->lh_done);
|
||||
|
||||
/* Get the result value saved by the interrupt handler. */
|
||||
result = lh->lh_result;
|
||||
|
||||
/*
|
||||
* Are we reading? If so, and if we succeeded,
|
||||
* transfer the data out of the on-card buffer.
|
||||
*/
|
||||
if (result==0 && uio->uio_rw==UIO_READ) {
|
||||
membar_load_load();
|
||||
result = uiomove(lh->lh_buf, LHD_SECTSIZE, uio);
|
||||
}
|
||||
|
||||
/* Tell another thread it's cleared to go ahead. */
|
||||
V(lh->lh_clear);
|
||||
|
||||
/* If we failed, return the error. */
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct device_ops lhd_devops = {
|
||||
.devop_eachopen = lhd_eachopen,
|
||||
.devop_io = lhd_io,
|
||||
.devop_ioctl = lhd_ioctl,
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup routine called by autoconf.c when an lhd is found.
|
||||
*/
|
||||
int
|
||||
config_lhd(struct lhd_softc *lh, int lhdno)
|
||||
{
|
||||
char name[32];
|
||||
|
||||
/* Figure out what our name is. */
|
||||
snprintf(name, sizeof(name), "lhd%d", lhdno);
|
||||
|
||||
/* Get a pointer to the on-chip buffer. */
|
||||
lh->lh_buf = bus_map_area(lh->lh_busdata, lh->lh_buspos, LHD_BUFFER);
|
||||
|
||||
/* Create the semaphores. */
|
||||
lh->lh_clear = sem_create("lhd-clear", 1);
|
||||
if (lh->lh_clear == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
lh->lh_done = sem_create("lhd-done", 0);
|
||||
if (lh->lh_done == NULL) {
|
||||
sem_destroy(lh->lh_clear);
|
||||
lh->lh_clear = NULL;
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* Set up the VFS device structure. */
|
||||
lh->lh_dev.d_ops = &lhd_devops;
|
||||
lh->lh_dev.d_blocks = bus_read_register(lh->lh_busdata, lh->lh_buspos,
|
||||
LHD_REG_NSECT);
|
||||
lh->lh_dev.d_blocksize = LHD_SECTSIZE;
|
||||
lh->lh_dev.d_data = lh;
|
||||
|
||||
/* Add the VFS device structure to the VFS device list. */
|
||||
return vfs_adddev(name, &lh->lh_dev, 1);
|
||||
}
|
64
kern/dev/lamebus/lhd.h
Normal file
64
kern/dev/lamebus/lhd.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_LHD_H_
|
||||
#define _LAMEBUS_LHD_H_
|
||||
|
||||
#include <device.h>
|
||||
|
||||
/*
|
||||
* Our sector size
|
||||
*/
|
||||
#define LHD_SECTSIZE 512
|
||||
|
||||
/*
|
||||
* Hardware device data associated with lhd (LAMEbus hard disk)
|
||||
*/
|
||||
struct lhd_softc {
|
||||
/* Initialized by lower-level attach code */
|
||||
void *lh_busdata; /* The bus we're on */
|
||||
uint32_t lh_buspos; /* Our slot on that bus */
|
||||
int lh_unit; /* What number lhd we are */
|
||||
|
||||
/*
|
||||
* Initialized by config_lhd
|
||||
*/
|
||||
|
||||
void *lh_buf; /* Pointer to on-card I/O buffer */
|
||||
int lh_result; /* Result from I/O operation */
|
||||
struct semaphore *lh_clear; /* Synchronization */
|
||||
struct semaphore *lh_done;
|
||||
|
||||
struct device lh_dev; /* VFS device structure */
|
||||
};
|
||||
|
||||
/* Functions called by lower-level drivers */
|
||||
void lhd_irq(/*struct lhd_softc*/ void *); /* Interrupt handler */
|
||||
|
||||
#endif /* _LAMEBUS_LHD_H_ */
|
69
kern/dev/lamebus/lhd_att.c
Normal file
69
kern/dev/lamebus/lhd_att.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code for probe/attach of lhd to LAMEbus.
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/lhd.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 2
|
||||
|
||||
struct lhd_softc *
|
||||
attach_lhd_to_lamebus(int lhdno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct lhd_softc *lh;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_DISK,
|
||||
LOW_VERSION, NULL);
|
||||
if (slot < 0) {
|
||||
/* None found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lh = kmalloc(sizeof(struct lhd_softc));
|
||||
if (lh==NULL) {
|
||||
/* Out of memory */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Record what the lhd is attached to */
|
||||
lh->lh_busdata = sc;
|
||||
lh->lh_buspos = slot;
|
||||
lh->lh_unit = lhdno;
|
||||
|
||||
/* Mark the slot in use and collect interrupts */
|
||||
lamebus_mark(sc, slot);
|
||||
lamebus_attach_interrupt(sc, slot, lh, lhd_irq);
|
||||
|
||||
return lh;
|
||||
}
|
46
kern/dev/lamebus/lnet.c
Normal file
46
kern/dev/lamebus/lnet.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <kern/errno.h>
|
||||
#include <lib.h>
|
||||
/*#include <lamebus/lnet.h>*/ /* not yet */
|
||||
#include "autoconf.h"
|
||||
|
||||
int
|
||||
config_lnet(struct lnet_softc *sc, int lnetno)
|
||||
{
|
||||
(void)sc;
|
||||
|
||||
kprintf("lnet%d: No network support in system\n", lnetno);
|
||||
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
|
52
kern/dev/lamebus/lnet_att.c
Normal file
52
kern/dev/lamebus/lnet_att.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
/* Highest revision we support */
|
||||
#define HIGH_VERSION 1
|
||||
|
||||
struct lnet_softc *
|
||||
attach_lnet_to_lamebus(int lnetno, struct lamebus_softc *sc)
|
||||
{
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_NET,
|
||||
LOW_VERSION, HIGH_VERSION);
|
||||
if (slot < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kprintf("lnet%d: No network support in system\n", lnetno);
|
||||
|
||||
return NULL;
|
||||
}
|
85
kern/dev/lamebus/lrandom.c
Normal file
85
kern/dev/lamebus/lrandom.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for LAMEbus random generator card
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <uio.h>
|
||||
#include <platform/bus.h>
|
||||
#include <lamebus/lrandom.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Registers (offsets within slot) */
|
||||
#define LR_REG_RAND 0 /* random register */
|
||||
|
||||
/* Constants */
|
||||
#define LR_RANDMAX 0xffffffff
|
||||
|
||||
int
|
||||
config_lrandom(struct lrandom_softc *lr, int lrandomno)
|
||||
{
|
||||
(void)lrandomno;
|
||||
(void)lr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lrandom_random(void *devdata)
|
||||
{
|
||||
struct lrandom_softc *lr = devdata;
|
||||
return bus_read_register(lr->lr_bus, lr->lr_buspos, LR_REG_RAND);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
lrandom_randmax(void *devdata)
|
||||
{
|
||||
(void)devdata;
|
||||
return LR_RANDMAX;
|
||||
}
|
||||
|
||||
int
|
||||
lrandom_read(void *devdata, struct uio *uio)
|
||||
{
|
||||
struct lrandom_softc *lr = devdata;
|
||||
uint32_t val;
|
||||
int result;
|
||||
|
||||
while (uio->uio_resid > 0) {
|
||||
val = bus_read_register(lr->lr_bus, lr->lr_buspos,
|
||||
LR_REG_RAND);
|
||||
result = uiomove(&val, sizeof(val), uio);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
46
kern/dev/lamebus/lrandom.h
Normal file
46
kern/dev/lamebus/lrandom.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_LRANDOM_H_
|
||||
#define _LAMEBUS_LRANDOM_H_
|
||||
|
||||
struct uio;
|
||||
|
||||
struct lrandom_softc {
|
||||
/* Initialized by lower-level attach routine */
|
||||
void *lr_bus;
|
||||
uint32_t lr_buspos;
|
||||
};
|
||||
|
||||
/* Functions called by higher-level drivers */
|
||||
uint32_t lrandom_random(/*struct lrandom_softc*/ void *devdata);
|
||||
uint32_t lrandom_randmax(/*struct lrandom_softc*/ void *devdata);
|
||||
int lrandom_read(/*struct lrandom_softc*/ void *, struct uio *);
|
||||
|
||||
#endif /* _LAMEBUS_LRANDOM_H_ */
|
62
kern/dev/lamebus/lrandom_att.c
Normal file
62
kern/dev/lamebus/lrandom_att.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/lrandom.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
|
||||
struct lrandom_softc *
|
||||
attach_lrandom_to_lamebus(int lrandomno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct lrandom_softc *lr;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_RANDOM,
|
||||
LOW_VERSION, NULL);
|
||||
if (slot < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lr = kmalloc(sizeof(struct lrandom_softc));
|
||||
if (lr==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)lrandomno; // unused
|
||||
|
||||
lr->lr_bus = sc;
|
||||
lr->lr_buspos = slot;
|
||||
|
||||
lamebus_mark(sc, slot);
|
||||
|
||||
return lr;
|
||||
}
|
225
kern/dev/lamebus/lscreen.c
Normal file
225
kern/dev/lamebus/lscreen.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for full-screen console.
|
||||
*
|
||||
* As of this writing the full-screen console is not supported in
|
||||
* System/161, so this driver is untested and probably broken.
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <spinlock.h>
|
||||
#include <platform/bus.h>
|
||||
#include <lamebus/lscreen.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Registers (offsets within slot) */
|
||||
#define LSCR_REG_POSN 0 /* Cursor position */
|
||||
#define LSCR_REG_SIZE 4 /* Display size */
|
||||
#define LSCR_REG_CHAR 8 /* Character in */
|
||||
#define LSCR_REG_RIRQ 12 /* Read interrupt status */
|
||||
|
||||
/* Bits in the IRQ registers */
|
||||
#define LSCR_IRQ_ENABLE 1
|
||||
#define LSCR_IRQ_ACTIVE 2
|
||||
|
||||
/* Offset within slot of screen buffer */
|
||||
#define LSCR_SCREEN 32768
|
||||
|
||||
/* Convert a 32-bit X/Y pair to X and Y coordinates. */
|
||||
static
|
||||
inline
|
||||
void
|
||||
splitxy(uint32_t xy, unsigned *x, unsigned *y)
|
||||
{
|
||||
*x = xy >> 16;
|
||||
*y = xy & 0xffff;
|
||||
}
|
||||
|
||||
/* Convert X and Y coordinates to a single 32-bit value. */
|
||||
static
|
||||
inline
|
||||
uint32_t
|
||||
mergexy(unsigned x, unsigned y)
|
||||
{
|
||||
uint32_t val = x;
|
||||
|
||||
return (val << 16) | y;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Interrupt handler.
|
||||
*/
|
||||
void
|
||||
lscreen_irq(void *vsc)
|
||||
{
|
||||
struct lscreen_softc *sc = vsc;
|
||||
uint32_t ch, x;
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSCR_REG_RIRQ);
|
||||
if (x & LSCR_IRQ_ACTIVE) {
|
||||
ch = bus_read_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_REG_CHAR);
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_REG_RIRQ, LSCR_IRQ_ENABLE);
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
if (sc->ls_input) {
|
||||
sc->ls_input(sc->ls_devdata, ch);
|
||||
}
|
||||
}
|
||||
else {
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Handle a newline on the screen.
|
||||
*/
|
||||
static
|
||||
void
|
||||
lscreen_newline(struct lscreen_softc *sc)
|
||||
{
|
||||
if (sc->ls_cy >= sc->ls_height-1) {
|
||||
/*
|
||||
* Scroll
|
||||
*/
|
||||
|
||||
memmove(sc->ls_screen, sc->ls_screen + sc->ls_width,
|
||||
sc->ls_width * (sc->ls_height-1));
|
||||
bzero(sc->ls_screen + sc->ls_width * (sc->ls_height-1),
|
||||
sc->ls_width);
|
||||
}
|
||||
else {
|
||||
sc->ls_cy++;
|
||||
}
|
||||
sc->ls_cx=0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a printable character being written to the screen.
|
||||
*/
|
||||
static
|
||||
void
|
||||
lscreen_char(struct lscreen_softc *sc, int ch)
|
||||
{
|
||||
if (sc->ls_cx >= sc->ls_width) {
|
||||
lscreen_newline(sc);
|
||||
}
|
||||
|
||||
sc->ls_screen[sc->ls_cy*sc->ls_width + sc->ls_cx] = ch;
|
||||
sc->ls_cx++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a character to the screen.
|
||||
* This should probably know about backspace and tab.
|
||||
*/
|
||||
void
|
||||
lscreen_write(void *vsc, int ch)
|
||||
{
|
||||
struct lscreen_softc *sc = vsc;
|
||||
int ccx, ccy;
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
switch (ch) {
|
||||
case '\n': lscreen_newline(sc); break;
|
||||
default: lscreen_char(sc, ch); break;
|
||||
}
|
||||
|
||||
/*
|
||||
* ccx/ccy = corrected cursor position
|
||||
* (The cursor marks the next space text will appear in. But
|
||||
* at the very end of the line, it should not move off the edge.)
|
||||
*/
|
||||
ccx = sc->ls_cx;
|
||||
ccy = sc->ls_cy;
|
||||
if (ccx==sc->ls_width) {
|
||||
ccx--;
|
||||
}
|
||||
|
||||
/* Set the cursor position */
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_REG_POSN, mergexy(ccx, ccy));
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Setup routine called by autoconf.c when an lscreen is found.
|
||||
*/
|
||||
int
|
||||
config_lscreen(struct lscreen_softc *sc, int lscreenno)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
(void)lscreenno;
|
||||
|
||||
spinlock_init(&sc->ls_lock);
|
||||
|
||||
/*
|
||||
* Enable interrupting.
|
||||
*/
|
||||
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_REG_RIRQ, LSCR_IRQ_ENABLE);
|
||||
|
||||
/*
|
||||
* Get screen size.
|
||||
*/
|
||||
val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_REG_SIZE);
|
||||
splitxy(val, &sc->ls_width, &sc->ls_height);
|
||||
|
||||
/*
|
||||
* Get cursor position.
|
||||
*/
|
||||
val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_REG_POSN);
|
||||
splitxy(val, &sc->ls_cx, &sc->ls_cy);
|
||||
|
||||
/*
|
||||
* Get a pointer to the memory-mapped screen area.
|
||||
*/
|
||||
sc->ls_screen = bus_map_area(sc->ls_busdata, sc->ls_buspos,
|
||||
LSCR_SCREEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
59
kern/dev/lamebus/lscreen.h
Normal file
59
kern/dev/lamebus/lscreen.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_LSCREEN_H_
|
||||
#define _LAMEBUS_LSCREEN_H_
|
||||
|
||||
/*
|
||||
* Hardware device data for memory-mapped fullscreen text console.
|
||||
*/
|
||||
struct lscreen_softc {
|
||||
/* Initialized by config function */
|
||||
struct spinlock ls_lock; // protects data and device regs
|
||||
unsigned ls_width, ls_height; // screen size
|
||||
unsigned ls_cx, ls_cy; // cursor position
|
||||
char *ls_screen; // memory-mapped screen buffer
|
||||
|
||||
/* Initialized by lower-level attachment function */
|
||||
void *ls_busdata; // bus we're on
|
||||
uint32_t ls_buspos; // position on that bus
|
||||
|
||||
/* Initialized by higher-level attachment function */
|
||||
void *ls_devdata; // data and functions for
|
||||
void (*ls_start)(void *devdata); // upper device (perhaps
|
||||
void (*ls_input)(void *devdata, int ch); // console)
|
||||
};
|
||||
|
||||
/* Functions called by lower-level drivers */
|
||||
void lscreen_irq(/*struct lser_softc*/ void *sc); // interrupt handler
|
||||
|
||||
/* Functions called by higher-level drivers */
|
||||
void lscreen_write(/*struct lser_softc*/ void *sc, int ch); // output function
|
||||
|
||||
#endif /* _LAMEBUS_LSCREEN_H_ */
|
70
kern/dev/lamebus/lscreen_att.c
Normal file
70
kern/dev/lamebus/lscreen_att.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code for probe/attach of lscreen to LAMEbus.
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/lscreen.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
/* Highest revision we support */
|
||||
#define HIGH_VERSION 1
|
||||
|
||||
struct lscreen_softc *
|
||||
attach_lscreen_to_lamebus(int lscreenno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct lscreen_softc *ls;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_SCREEN,
|
||||
LOW_VERSION, HIGH_VERSION);
|
||||
if (slot < 0) {
|
||||
/* Not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ls = kmalloc(sizeof(struct lscreen_softc));
|
||||
if (ls==NULL) {
|
||||
/* Out of memory */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Record what it's attached to */
|
||||
ls->ls_busdata = sc;
|
||||
ls->ls_buspos = slot;
|
||||
|
||||
/* Mark the slot in use and hook the interrupt */
|
||||
lamebus_mark(sc, slot);
|
||||
lamebus_attach_interrupt(sc, slot, ls, lscreen_irq);
|
||||
|
||||
return ls;
|
||||
}
|
192
kern/dev/lamebus/lser.c
Normal file
192
kern/dev/lamebus/lser.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <lib.h>
|
||||
#include <spinlock.h>
|
||||
#include <platform/bus.h>
|
||||
#include <lamebus/lser.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Registers (offsets within slot) */
|
||||
#define LSER_REG_CHAR 0 /* Character in/out */
|
||||
#define LSER_REG_WIRQ 4 /* Write interrupt status */
|
||||
#define LSER_REG_RIRQ 8 /* Read interrupt status */
|
||||
|
||||
/* Bits in the IRQ registers */
|
||||
#define LSER_IRQ_ENABLE 1
|
||||
#define LSER_IRQ_ACTIVE 2
|
||||
#define LSER_IRQ_FORCE 4
|
||||
|
||||
void
|
||||
lser_irq(void *vsc)
|
||||
{
|
||||
struct lser_softc *sc = vsc;
|
||||
uint32_t x;
|
||||
bool clear_to_write = false;
|
||||
bool got_a_read = false;
|
||||
uint32_t ch = 0;
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_WIRQ);
|
||||
if (x & LSER_IRQ_ACTIVE) {
|
||||
x = LSER_IRQ_ENABLE;
|
||||
sc->ls_wbusy = 0;
|
||||
clear_to_write = true;
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_WIRQ, x);
|
||||
}
|
||||
|
||||
x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_RIRQ);
|
||||
if (x & LSER_IRQ_ACTIVE) {
|
||||
x = LSER_IRQ_ENABLE;
|
||||
ch = bus_read_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_CHAR);
|
||||
got_a_read = true;
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_RIRQ, x);
|
||||
}
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
|
||||
if (clear_to_write && sc->ls_start != NULL) {
|
||||
sc->ls_start(sc->ls_devdata);
|
||||
}
|
||||
if (got_a_read && sc->ls_input != NULL) {
|
||||
sc->ls_input(sc->ls_devdata, ch);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lser_write(void *vls, int ch)
|
||||
{
|
||||
struct lser_softc *ls = vls;
|
||||
|
||||
spinlock_acquire(&ls->ls_lock);
|
||||
|
||||
if (ls->ls_wbusy) {
|
||||
/*
|
||||
* We're not clear to write.
|
||||
*
|
||||
* This should not happen. It's the job of the driver
|
||||
* attached to us to not write until we call
|
||||
* ls->ls_start.
|
||||
*
|
||||
* (Note: if we're the console, the panic will go to
|
||||
* lser_writepolled for printing, because we hold a
|
||||
* spinlock and interrupts are off; it won't recurse.)
|
||||
*/
|
||||
panic("lser: Not clear to write\n");
|
||||
}
|
||||
ls->ls_wbusy = true;
|
||||
|
||||
bus_write_register(ls->ls_busdata, ls->ls_buspos, LSER_REG_CHAR, ch);
|
||||
|
||||
spinlock_release(&ls->ls_lock);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lser_poll_until_write(struct lser_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
KASSERT(spinlock_do_i_hold(&sc->ls_lock));
|
||||
|
||||
do {
|
||||
val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_WIRQ);
|
||||
}
|
||||
while ((val & LSER_IRQ_ACTIVE) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
lser_writepolled(void *vsc, int ch)
|
||||
{
|
||||
struct lser_softc *sc = vsc;
|
||||
bool irqpending;
|
||||
|
||||
spinlock_acquire(&sc->ls_lock);
|
||||
|
||||
if (sc->ls_wbusy) {
|
||||
irqpending = true;
|
||||
lser_poll_until_write(sc);
|
||||
/* Clear the ready condition, but leave the IRQ asserted */
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_WIRQ,
|
||||
LSER_IRQ_FORCE|LSER_IRQ_ENABLE);
|
||||
}
|
||||
else {
|
||||
irqpending = false;
|
||||
/* Clear the interrupt enable bit */
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_WIRQ, 0);
|
||||
}
|
||||
|
||||
/* Send the character. */
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos, LSER_REG_CHAR, ch);
|
||||
|
||||
/* Wait until it's done. */
|
||||
lser_poll_until_write(sc);
|
||||
|
||||
/*
|
||||
* If there wasn't already an IRQ pending, clear the ready
|
||||
* condition and turn interruption back on. But if there was,
|
||||
* leave the register alone, with the ready condition set (and
|
||||
* the force bit still on); in due course we'll get to the
|
||||
* interrupt handler and they'll be cleared.
|
||||
*/
|
||||
if (!irqpending) {
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_WIRQ, LSER_IRQ_ENABLE);
|
||||
}
|
||||
|
||||
spinlock_release(&sc->ls_lock);
|
||||
}
|
||||
|
||||
int
|
||||
config_lser(struct lser_softc *sc, int lserno)
|
||||
{
|
||||
(void)lserno;
|
||||
|
||||
/*
|
||||
* Enable interrupting.
|
||||
*/
|
||||
|
||||
spinlock_init(&sc->ls_lock);
|
||||
sc->ls_wbusy = false;
|
||||
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_RIRQ, LSER_IRQ_ENABLE);
|
||||
bus_write_register(sc->ls_busdata, sc->ls_buspos,
|
||||
LSER_REG_WIRQ, LSER_IRQ_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
57
kern/dev/lamebus/lser.h
Normal file
57
kern/dev/lamebus/lser.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_LSER_H_
|
||||
#define _LAMEBUS_LSER_H_
|
||||
|
||||
#include <spinlock.h>
|
||||
|
||||
struct lser_softc {
|
||||
/* Initialized by config function */
|
||||
struct spinlock ls_lock; /* protects ls_wbusy and device regs */
|
||||
volatile bool ls_wbusy; /* true if write in progress */
|
||||
|
||||
/* Initialized by lower-level attachment function */
|
||||
void *ls_busdata;
|
||||
uint32_t ls_buspos;
|
||||
|
||||
/* Initialized by higher-level attachment function */
|
||||
void *ls_devdata;
|
||||
void (*ls_start)(void *devdata);
|
||||
void (*ls_input)(void *devdata, int ch);
|
||||
};
|
||||
|
||||
/* Functions called by lower-level drivers */
|
||||
void lser_irq(/*struct lser_softc*/ void *sc);
|
||||
|
||||
/* Functions called by higher-level drivers */
|
||||
void lser_write(/*struct lser_softc*/ void *sc, int ch);
|
||||
void lser_writepolled(/*struct lser_softc*/ void *sc, int ch);
|
||||
|
||||
#endif /* _LAMEBUS_LSER_H_ */
|
63
kern/dev/lamebus/lser_att.c
Normal file
63
kern/dev/lamebus/lser_att.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/lser.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
|
||||
struct lser_softc *
|
||||
attach_lser_to_lamebus(int lserno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct lser_softc *ls;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_SERIAL,
|
||||
LOW_VERSION, NULL);
|
||||
if (slot < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ls = kmalloc(sizeof(struct lser_softc));
|
||||
if (ls==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)lserno; // unused
|
||||
|
||||
ls->ls_busdata = sc;
|
||||
ls->ls_buspos = slot;
|
||||
|
||||
lamebus_mark(sc, slot);
|
||||
lamebus_attach_interrupt(sc, slot, ls, lser_irq);
|
||||
|
||||
return ls;
|
||||
}
|
187
kern/dev/lamebus/ltimer.c
Normal file
187
kern/dev/lamebus/ltimer.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for LAMEbus clock/timer card
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <spl.h>
|
||||
#include <clock.h>
|
||||
#include <platform/bus.h>
|
||||
#include <lamebus/ltimer.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Registers (offsets within slot) */
|
||||
#define LT_REG_SEC 0 /* time of day: seconds */
|
||||
#define LT_REG_NSEC 4 /* time of day: nanoseconds */
|
||||
#define LT_REG_ROE 8 /* Restart On countdown-timer Expiry flag */
|
||||
#define LT_REG_IRQ 12 /* Interrupt status register */
|
||||
#define LT_REG_COUNT 16 /* Time for countdown timer (usec) */
|
||||
#define LT_REG_SPKR 20 /* Beep control */
|
||||
|
||||
/* Granularity of countdown timer (usec) */
|
||||
#define LT_GRANULARITY 1000000
|
||||
|
||||
static bool havetimerclock;
|
||||
|
||||
/*
|
||||
* Setup routine called by autoconf stuff when an ltimer is found.
|
||||
*/
|
||||
int
|
||||
config_ltimer(struct ltimer_softc *lt, int ltimerno)
|
||||
{
|
||||
/*
|
||||
* Running on System/161 2.x, we always use the processor
|
||||
* on-chip timer for hardclock and we don't need ltimer as
|
||||
* hardclock.
|
||||
*
|
||||
* Ideally there should be code here that will use an ltimer
|
||||
* for hardclock if nothing else is available; e.g. if we
|
||||
* wanted to make OS/161 2.x run on System/161 1.x. However,
|
||||
* that requires a good bit more infrastructure for handling
|
||||
* timers than we have and it doesn't seem worthwhile.
|
||||
*
|
||||
* It would also require some hacking, because all CPUs need
|
||||
* to receive timer interrupts. (Exercise: how would you make
|
||||
* sure all CPUs receive exactly one timer interrupt? Remember
|
||||
* that LAMEbus uses level-triggered interrupts, so the
|
||||
* hardware interrupt line will cause repeated interrupts if
|
||||
* it's not reset on the device; but if it's reset on the
|
||||
* device before all CPUs manage to see it, those CPUs won't
|
||||
* be interrupted at all.)
|
||||
*
|
||||
* Note that the beep and rtclock devices *do* attach to
|
||||
* ltimer.
|
||||
*/
|
||||
(void)ltimerno;
|
||||
lt->lt_hardclock = 0;
|
||||
|
||||
/*
|
||||
* We do, however, use ltimer for the timer clock, since the
|
||||
* on-chip timer can't do that.
|
||||
*/
|
||||
if (!havetimerclock) {
|
||||
havetimerclock = true;
|
||||
lt->lt_timerclock = 1;
|
||||
|
||||
/* Wire it to go off once every second. */
|
||||
bus_write_register(lt->lt_bus, lt->lt_buspos, LT_REG_ROE, 1);
|
||||
bus_write_register(lt->lt_bus, lt->lt_buspos, LT_REG_COUNT,
|
||||
LT_GRANULARITY);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt handler.
|
||||
*/
|
||||
void
|
||||
ltimer_irq(void *vlt)
|
||||
{
|
||||
struct ltimer_softc *lt = vlt;
|
||||
uint32_t val;
|
||||
|
||||
val = bus_read_register(lt->lt_bus, lt->lt_buspos, LT_REG_IRQ);
|
||||
if (val) {
|
||||
/*
|
||||
* Only call hardclock if we're responsible for hardclock.
|
||||
* (Any additional timer devices are unused.)
|
||||
*/
|
||||
if (lt->lt_hardclock) {
|
||||
hardclock();
|
||||
}
|
||||
/*
|
||||
* Likewise for timerclock.
|
||||
*/
|
||||
if (lt->lt_timerclock) {
|
||||
timerclock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The timer device will beep if you write to the beep register. It
|
||||
* doesn't matter what value you write. This function is called if
|
||||
* the beep device is attached to this timer.
|
||||
*/
|
||||
void
|
||||
ltimer_beep(void *vlt)
|
||||
{
|
||||
struct ltimer_softc *lt = vlt;
|
||||
|
||||
bus_write_register(lt->lt_bus, lt->lt_buspos, LT_REG_SPKR, 440);
|
||||
}
|
||||
|
||||
/*
|
||||
* The timer device also has a realtime clock on it.
|
||||
* This function gets called if the rtclock device is attached
|
||||
* to this timer.
|
||||
*/
|
||||
void
|
||||
ltimer_gettime(void *vlt, struct timespec *ts)
|
||||
{
|
||||
struct ltimer_softc *lt = vlt;
|
||||
uint32_t secs1, secs2;
|
||||
int spl;
|
||||
|
||||
/*
|
||||
* Read the seconds twice, on either side of the nanoseconds.
|
||||
* If nsecs is small, use the *later* value of seconds, in case
|
||||
* the nanoseconds turned over between the time we got the earlier
|
||||
* value and the time we got nsecs.
|
||||
*
|
||||
* Note that the clock in the ltimer device is accurate down
|
||||
* to a single processor cycle, so this might actually matter
|
||||
* now and then.
|
||||
*
|
||||
* Do it with interrupts off on the current processor to avoid
|
||||
* getting garbage if we get an interrupt among the register
|
||||
* reads.
|
||||
*/
|
||||
|
||||
spl = splhigh();
|
||||
|
||||
secs1 = bus_read_register(lt->lt_bus, lt->lt_buspos,
|
||||
LT_REG_SEC);
|
||||
ts->tv_nsec = bus_read_register(lt->lt_bus, lt->lt_buspos,
|
||||
LT_REG_NSEC);
|
||||
secs2 = bus_read_register(lt->lt_bus, lt->lt_buspos,
|
||||
LT_REG_SEC);
|
||||
|
||||
splx(spl);
|
||||
|
||||
if (ts->tv_nsec < 5000000) {
|
||||
ts->tv_sec = secs2;
|
||||
}
|
||||
else {
|
||||
ts->tv_sec = secs1;
|
||||
}
|
||||
}
|
56
kern/dev/lamebus/ltimer.h
Normal file
56
kern/dev/lamebus/ltimer.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_LTIMER_H_
|
||||
#define _LAMEBUS_LTIMER_H_
|
||||
|
||||
struct timespec;
|
||||
|
||||
/*
|
||||
* Hardware device data for LAMEbus timer device
|
||||
*/
|
||||
struct ltimer_softc {
|
||||
/* Initialized by config function */
|
||||
int lt_hardclock; /* true if we should call hardclock() */
|
||||
int lt_timerclock; /* true if we should call timerclock() */
|
||||
|
||||
/* Initialized by lower-level attach routine */
|
||||
void *lt_bus; /* bus we're on */
|
||||
uint32_t lt_buspos; /* position (slot) on that bus */
|
||||
};
|
||||
|
||||
/* Functions called by lower-level drivers */
|
||||
void ltimer_irq(/*struct ltimer_softc*/ void *lt); // interrupt handler
|
||||
|
||||
/* Functions called by higher-level devices */
|
||||
void ltimer_beep(/*struct ltimer_softc*/ void *devdata); // for beep device
|
||||
void ltimer_gettime(/*struct ltimer_softc*/ void *devdata,
|
||||
struct timespec *ts); // for rtclock
|
||||
|
||||
#endif /* _LAMEBUS_LTIMER_H_ */
|
70
kern/dev/lamebus/ltimer_att.c
Normal file
70
kern/dev/lamebus/ltimer_att.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Routine for probing/attaching ltimer to LAMEbus.
|
||||
*/
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/ltimer.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
|
||||
struct ltimer_softc *
|
||||
attach_ltimer_to_lamebus(int ltimerno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct ltimer_softc *lt;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_TIMER,
|
||||
LOW_VERSION, NULL);
|
||||
if (slot < 0) {
|
||||
/* No ltimer (or no additional ltimer) found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lt = kmalloc(sizeof(struct ltimer_softc));
|
||||
if (lt==NULL) {
|
||||
/* out of memory */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)ltimerno; // unused
|
||||
|
||||
/* Record what bus it's on */
|
||||
lt->lt_bus = sc;
|
||||
lt->lt_buspos = slot;
|
||||
|
||||
/* Mark the slot in use and hook that slot's interrupt */
|
||||
lamebus_mark(sc, slot);
|
||||
lamebus_attach_interrupt(sc, slot, lt, ltimer_irq);
|
||||
|
||||
return lt;
|
||||
}
|
116
kern/dev/lamebus/ltrace.c
Normal file
116
kern/dev/lamebus/ltrace.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <lib.h>
|
||||
#include <platform/bus.h>
|
||||
#include <lamebus/ltrace.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Registers (offsets within slot) */
|
||||
#define LTRACE_REG_TRON 0 /* trace on */
|
||||
#define LTRACE_REG_TROFF 4 /* trace off */
|
||||
#define LTRACE_REG_DEBUG 8 /* debug code */
|
||||
#define LTRACE_REG_DUMP 12 /* dump the system */
|
||||
#define LTRACE_REG_STOP 16 /* stop for the debugger */
|
||||
#define LTRACE_REG_PROFEN 20 /* turn profiling on/off */
|
||||
#define LTRACE_REG_PROFCL 24 /* clear the profile */
|
||||
|
||||
static struct ltrace_softc *the_trace;
|
||||
|
||||
void
|
||||
ltrace_on(uint32_t code)
|
||||
{
|
||||
if (the_trace != NULL) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_TRON, code);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ltrace_off(uint32_t code)
|
||||
{
|
||||
if (the_trace != NULL) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_TROFF, code);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ltrace_debug(uint32_t code)
|
||||
{
|
||||
if (the_trace != NULL) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_DEBUG, code);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ltrace_dump(uint32_t code)
|
||||
{
|
||||
if (the_trace != NULL) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_DUMP, code);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ltrace_stop(uint32_t code)
|
||||
{
|
||||
if (the_trace != NULL && the_trace->lt_canstop) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_STOP, code);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ltrace_setprof(uint32_t onoff)
|
||||
{
|
||||
if (the_trace != NULL && the_trace->lt_canprof) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_PROFEN, onoff);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ltrace_eraseprof(void)
|
||||
{
|
||||
if (the_trace != NULL && the_trace->lt_canprof) {
|
||||
bus_write_register(the_trace->lt_busdata, the_trace->lt_buspos,
|
||||
LTRACE_REG_PROFCL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
config_ltrace(struct ltrace_softc *sc, int ltraceno)
|
||||
{
|
||||
(void)ltraceno;
|
||||
the_trace = sc;
|
||||
return 0;
|
||||
}
|
90
kern/dev/lamebus/ltrace.h
Normal file
90
kern/dev/lamebus/ltrace.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAMEBUS_LTRACE_H_
|
||||
#define _LAMEBUS_LTRACE_H_
|
||||
|
||||
struct ltrace_softc {
|
||||
/* Initialized by lower-level attachment function */
|
||||
void *lt_busdata;
|
||||
uint32_t lt_buspos;
|
||||
bool lt_canstop;
|
||||
bool lt_canprof;
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions provided for debug hacking:
|
||||
* ltrace_on: turns on the trace161 tracing flag CODE.
|
||||
* ltrace_off: turns off the trace161 tracing flag CODE.
|
||||
* ltrace_debug: causes sys161/trace161 to print a message with CODE.
|
||||
* ltrace_dump: causes trace161 to do a complete state dump, tagged CODE.
|
||||
* ltrace_stop: causes sys161/trace161 to drop to the debugger.
|
||||
* ltrace_setprof: turn on and off trace161 profile collection.
|
||||
* ltrace_eraseprof: discard trace161 profile collected so far.
|
||||
*
|
||||
* The flags for ltrace_on/off are the characters used to control
|
||||
* tracing on the trace161 command line. See the System/161 manual for
|
||||
* more information.
|
||||
*
|
||||
* ltrace_debug is for printing simple indications that a certain
|
||||
* piece of code has been reached, like one might use kprintf, except
|
||||
* that it is less invasive than kprintf. Think of it as setting the
|
||||
* value of a readout on the system's front panel. (In real life,
|
||||
* since computers don't have front panels with blinking lights any
|
||||
* more, people often use the speaker or the top left corner of the
|
||||
* screen for this purpose.)
|
||||
*
|
||||
* ltrace_dump dumps the entire system state and is primarily intended
|
||||
* for regression testing of System/161. It might or might not prove
|
||||
* useful for debugging as well.
|
||||
*
|
||||
* Calling ltrace_stop behaves similarly to hardwiring a breakpoint
|
||||
* instruction in your code, except that debuggers have trouble
|
||||
* stepping past hardwired breakpoints. Currently the value of the
|
||||
* code is ignored.
|
||||
*
|
||||
* ltrace_setprof can be used to dynamically turn profiling on and
|
||||
* off, if trace161 is collecting a profile. (Otherwise it does
|
||||
* nothing.) This can be used to e.g. profile only code that executes
|
||||
* while holding a given lock.
|
||||
*
|
||||
* ltrace_eraseprof can be used to clear the accumulated profile
|
||||
* data, if trace161 is collecting a profile. (Otherwise it does
|
||||
* nothing.) This can be used to e.g. exclude bootup actions from your
|
||||
* profile.
|
||||
*/
|
||||
void ltrace_on(uint32_t code);
|
||||
void ltrace_off(uint32_t code);
|
||||
void ltrace_debug(uint32_t code);
|
||||
void ltrace_dump(uint32_t code);
|
||||
void ltrace_stop(uint32_t code);
|
||||
void ltrace_setprof(uint32_t onoff);
|
||||
void ltrace_eraseprof(void);
|
||||
|
||||
#endif /* _LAMEBUS_LTRACE_H_ */
|
69
kern/dev/lamebus/ltrace_att.c
Normal file
69
kern/dev/lamebus/ltrace_att.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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 <types.h>
|
||||
#include <lib.h>
|
||||
#include <lamebus/lamebus.h>
|
||||
#include <lamebus/ltrace.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
/* Lowest revision we support */
|
||||
#define LOW_VERSION 1
|
||||
/* Revision that supports ltrace_stop() */
|
||||
#define STOP_VERSION 2
|
||||
/* Revision that supports ltrace_prof() */
|
||||
#define PROF_VERSION 3
|
||||
|
||||
struct ltrace_softc *
|
||||
attach_ltrace_to_lamebus(int ltraceno, struct lamebus_softc *sc)
|
||||
{
|
||||
struct ltrace_softc *lt;
|
||||
uint32_t drl;
|
||||
int slot = lamebus_probe(sc, LB_VENDOR_CS161, LBCS161_TRACE,
|
||||
LOW_VERSION, &drl);
|
||||
if (slot < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lt = kmalloc(sizeof(struct ltrace_softc));
|
||||
if (lt==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)ltraceno; // unused
|
||||
|
||||
lt->lt_busdata = sc;
|
||||
lt->lt_buspos = slot;
|
||||
lt->lt_canstop = drl >= STOP_VERSION;
|
||||
lt->lt_canprof = drl >= PROF_VERSION;
|
||||
|
||||
lamebus_mark(sc, slot);
|
||||
|
||||
return lt;
|
||||
}
|
57
kern/dev/lamebus/random_lrandom.c
Normal file
57
kern/dev/lamebus/random_lrandom.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Attachment code for having the generic random device use the LAMEbus
|
||||
* random device.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <generic/random.h>
|
||||
#include <lamebus/lrandom.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
struct random_softc *
|
||||
attach_random_to_lrandom(int randomno, struct lrandom_softc *ls)
|
||||
{
|
||||
struct random_softc *rs = kmalloc(sizeof(struct random_softc));
|
||||
if (rs==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)randomno; // unused
|
||||
|
||||
rs->rs_devdata = ls;
|
||||
rs->rs_random = lrandom_random;
|
||||
rs->rs_randmax = lrandom_randmax;
|
||||
rs->rs_read = lrandom_read;
|
||||
|
||||
return rs;
|
||||
}
|
66
kern/dev/lamebus/rtclock_ltimer.c
Normal file
66
kern/dev/lamebus/rtclock_ltimer.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||
* The President and Fellows of Harvard College.
|
||||
*
|
||||
* 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. 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 UNIVERSITY 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 UNIVERSITY 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code for attaching the (generic) rtclock device to the LAMEbus ltimer.
|
||||
*
|
||||
* rtclock is a generic clock interface that gets its clock service from
|
||||
* an actual hardware clock of some kind. (Theoretically it could also
|
||||
* get its clock service from a clock maintained in software, as is the
|
||||
* case on most systems. However, no such driver has been written yet.)
|
||||
*
|
||||
* ltimer can provide this clock service.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <lib.h>
|
||||
#include <generic/rtclock.h>
|
||||
#include <lamebus/ltimer.h>
|
||||
#include "autoconf.h"
|
||||
|
||||
struct rtclock_softc *
|
||||
attach_rtclock_to_ltimer(int rtclockno, struct ltimer_softc *ls)
|
||||
{
|
||||
/*
|
||||
* No need to probe; ltimer always has a clock.
|
||||
* Just allocate the rtclock, set our fields, and return it.
|
||||
*/
|
||||
struct rtclock_softc *rtc = kmalloc(sizeof(struct rtclock_softc));
|
||||
if (rtc==NULL) {
|
||||
/* Out of memory */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)rtclockno; // unused
|
||||
|
||||
rtc->rtc_devdata = ls;
|
||||
rtc->rtc_gettime = ltimer_gettime;
|
||||
|
||||
return rtc;
|
||||
}
|
Reference in New Issue
Block a user