Populate dnard/dnard.

This commit is contained in:
matt 2001-05-09 15:58:07 +00:00
parent 0cd5b27a79
commit 77666e6c72
14 changed files with 13304 additions and 0 deletions

View File

@ -0,0 +1,334 @@
/* $NetBSD: autoconf.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe for
* the NetBSD project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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.
*
* RiscBSD kernel project
*
* autoconf.c
*
* Autoconfiguration functions
*
* Created : 08/10/94
*/
#include "opt_md.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/termios.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <dev/ofw/openfirm.h>
#include <dev/isa/isavar.h>
#include <dev/ofisa/ofisavar.h>
#include <dev/ic/comvar.h>
#include <dnard/dnard/sequoia.h>
extern void startrtclock __P((void));
extern int vga_ofbus_cnattach(int, bus_space_tag_t, bus_space_tag_t);
extern char *boot_file;
extern char *boot_kernel;
struct device *booted_device;
int booted_partition;
extern dev_t dumpdev;
void dumpconf __P((void));
void isa_intr_init __P((void));
/*
* Set up the root device from the boot args
*/
void
cpu_rootconf()
{
#ifndef MEMORY_DISK_IS_ROOT
printf("boot device: %s\n",
booted_device != NULL ? booted_device->dv_xname : "<unknown>");
#endif
setroot(booted_device, booted_partition);
}
/*
* void cpu_configure()
*
* Configure all the root devices
* The root devices are expected to configure their own children
*/
void
cpu_configure()
{
int node;
struct ofbus_attach_args aa;
/*
* Configure all the roots.
*/
sequoiaInit();
startrtclock();
/*
* Since the ICU is not standard on the ARM we don't know
* if we have one until we find a bridge.
* Since various PCI interrupts could be routed via the ICU
* (for PCI devices in the bridge) we need to set up the ICU
* now so that these interrupts can be established correctly
* i.e. This is a hack.
*/
#if 0
#include "isa.h"
#if NISA > 0 && !defined(SHARK)
isa_intr_init();
#endif
#endif
/*
* Walk the OFW device tree and configure found devices.
*/
if (!(node = OF_peer(0)))
panic("No OFW root");
aa.oba_busname = "ofw";
aa.oba_phandle = node;
if (!config_rootfound("ofbus", &aa))
panic("ofw root ofbus not configured");
/* Debugging information */
#ifndef TERSE
printf("ipl_bio=%08x ipl_net=%08x ipl_tty=%08x ipl_imp=%08x\n",
irqmasks[IPL_BIO], irqmasks[IPL_NET], irqmasks[IPL_TTY],
irqmasks[IPL_IMP]);
printf("ipl_audio=%08x ipl_imp=%08x ipl_high=%08x ipl_serial=%08x\n",
irqmasks[IPL_AUDIO], irqmasks[IPL_CLOCK], irqmasks[IPL_HIGH],
irqmasks[IPL_SERIAL]);
#endif
/* Time to start taking interrupts so lets open the flood gates .... */
(void)spl0();
}
void
device_register(struct device *dev, void *aux)
{
static struct device *parent;
#if NSD > 0 || NCD > 0
static struct device *scsipidev;
#endif
static char *boot_component;
struct ofbus_attach_args *oba;
const char *cd_name = dev->dv_cfdata->cf_driver->cd_name;
char name[64];
int i;
if (boot_component == NULL) {
char *cp;
boot_component = boot_file;
if (boot_component == NULL)
return;
cp = strrchr(boot_component, ':');
if (cp != NULL) {
*cp++ = '\0';
if (cp[0] == '\\')
cp++;
boot_kernel = cp;
}
}
if (booted_device != NULL
|| boot_component == NULL
|| boot_component[0] == '\0')
return;
if (!strcmp(cd_name, "ofbus") || !strcmp(cd_name, "ofisa")) {
oba = aux;
} else if (parent == NULL) {
return;
} else if (parent == dev->dv_parent
&& !strcmp(parent->dv_cfdata->cf_driver->cd_name, "ofisa")) {
struct ofisa_attach_args *aa = aux;
oba = &aa->oba;
#if NWD > 0 || NSD > 0 || NCD > 0
} else if (parent == dev->dv_parent
&& !strcmp(parent->dv_cfdata->cf_driver->cd_name, "wdc")) {
#if NSD > 0 || NCD > 0
if (!strcmp(cd_name, "atapibus")) {
scsipidev = dev;
return;
}
#endif
#if NWD > 0
if (!strcmp(cd_name, "wd")) {
struct ata_atapi_attach *aa = aux;
char *cp = strchr(boot_component, '@');
if (cp != NULL
&& aa->aa_drv_data->drive == strtoul(cp+1, NULL, 16)
&& aa->aa_channel == 0) {
booted_device = dev;
return;
}
}
return;
#endif /* NWD > 0 */
#if NSD > 0 || NCD > 0
} else if (scsipidev == dev->dv_parent
&& (!strcmp(cd_name, "sd") || !strcmp(cd_name, "cd"))) {
struct scsipibus_attach_args *sa = aux;
char *cp = strchr(boot_component, '@');
if (cp != NULL
&& sa->sa_sc_link->type == BUS_ATAPI
&& sa->sa_sc_link->scsipi_atapi.channel == 0
&& sa->sa_sc_link->scsipi_atapi.drive == strtoul(cp+1, NULL, 16)) {
booted_device = dev;
}
return;
#endif /* NSD > 0 || NCD > 0 */
#endif /* NWD > 0 || NSD > 0 || NCD > 0 */
} else {
return;
}
(void) of_packagename(oba->oba_phandle, name, sizeof name);
i = strlen(name);
if (!strncmp(name, &boot_component[1], i)
&& (boot_component[i+1] == '/' || boot_component[i+1] == '\0')) {
boot_component += i + 1;
if (boot_component[0] == '/') {
parent = dev;
} else {
booted_device = dev;
}
}
}
#include "ofb.h"
#include "vga_ofbus.h"
#include "com.h"
#if (NCOM > 0)
#ifndef CONSPEED
#define CONSPEED 9600
#endif
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
#endif
int comcnmode = CONMODE;
#endif /* (NCOM > 0) */
void
cninit(void)
{
int chosen, stdin, stdout, node;
char type[16], name[16];
chosen = OF_finddevice("/chosen");
if (chosen == 0)
goto nocons;
if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout))
!= sizeof(stdout))
goto nocons;
node = OF_instance_to_package(stdout);
bzero(type, sizeof(type));
if (OF_getprop(node, "device_type", type, sizeof(type)) == -1)
goto nocons;
if (strcmp(type, "display") == 0) {
#if NOFB > 0
if (!ofb_cnattach())
goto dokbd;
#endif
#if NVGA_OFBUS > 0
if (!vga_ofbus_cnattach(node, &isa_io_bs_tag, &isa_mem_bs_tag))
goto dokbd;
#endif
return;
dokbd:
/*
* We must determine which keyboard type we have.
*/
if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin))
!= sizeof(stdin)) {
printf("WARNING: no `stdin' property in /chosen\n");
return;
}
node = OF_instance_to_package(stdin);
bzero(name, sizeof(name));
OF_getprop(node, "name", name, sizeof(name));
if (strcmp(name, "keyboard") != 0) {
printf("WARNING: stdin is not a keyboard: %s\n", name);
return;
}
#if (NPCKBC > 0)
pckbc_cnattach(&isa_io_bs_tag, IO_KBD, KBCMDP, PCKBC_KBD_SLOT);
#endif
return;
}
#if NCOM > 0
if (strcmp(type, "serial") == 0) {
int regs[3];
int freq;
if (OF_getprop(node, "reg", regs, sizeof(regs)) != sizeof(regs))
goto nocom;
if (OF_getprop(node, "clock-frequency", &freq, sizeof(freq))
!= sizeof(freq))
goto nocom;
if (!comcnattach(&isa_io_bs_tag, regs[1], CONSPEED, freq,
comcnmode))
return;
nocom:
panic("can't init serial console (hanlde=%#x)", node);
return;
}
#endif
nocons:
return;
}

417
sys/arch/dnard/dnard/conf.c Normal file
View File

@ -0,0 +1,417 @@
/* $NetBSD: conf.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Mark Brinicombe
* for the NetBSD Project.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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.
*
* RiscBSD kernel project
*
* conf.c
*
* Character and Block Device configuration
* Console configuration
*
* Defines the structures cdevsw and constab
*
* Created : 17/09/94
*/
#include "opt_footbridge.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/conf.h>
#include <sys/vnode.h>
#include <machine/conf.h>
#include "wd.h"
#include "md.h"
#include "sd.h"
#include "st.h"
#include "cd.h"
#include "vnd.h"
#include "ccd.h"
#include "raid.h"
/* Block devices */
struct bdevsw bdevsw[] = {
bdev_lkm_dummy(), /* 0: */
bdev_swap_init(1, sw), /* 1: swap pseudo-device */
bdev_lkm_dummy(), /* 2: */
bdev_lkm_dummy(), /* 3: */
bdev_lkm_dummy(), /* 4: */
bdev_lkm_dummy(), /* 5: */
bdev_lkm_dummy(), /* 6: */
bdev_lkm_dummy(), /* 7: */
bdev_lkm_dummy(), /* 8: */
bdev_lkm_dummy(), /* 9: */
bdev_lkm_dummy(), /* 10: */
bdev_lkm_dummy(), /* 11: */
bdev_lkm_dummy(), /* 12: */
bdev_lkm_dummy(), /* 13: */
bdev_lkm_dummy(), /* 14: */
bdev_lkm_dummy(), /* 15: */
bdev_disk_init(NWD, wd), /* 16: Internal IDE disk */
bdev_lkm_dummy(), /* 17: */
bdev_disk_init(NMD, md), /* 18: memory disk */
bdev_disk_init(NVND,vnd), /* 19: vnode disk driver */
bdev_lkm_dummy(), /* 20: */
bdev_disk_init(NCCD,ccd), /* 21: concatenated disk driver */
bdev_lkm_dummy(), /* 22: */
bdev_lkm_dummy(), /* 23: */
bdev_disk_init(NSD,sd), /* 24: SCSI disk */
bdev_tape_init(NST,st), /* 25: SCSI tape (??) */
bdev_disk_init(NCD,cd), /* 26: SCSI cdrom */
bdev_lkm_dummy(), /* 27: */
bdev_lkm_dummy(), /* 28: */
bdev_lkm_dummy(), /* 29: */
bdev_lkm_dummy(), /* 30: */
bdev_lkm_dummy(), /* 31: */
bdev_lkm_dummy(), /* 32: */
bdev_lkm_dummy(), /* 33: */
bdev_lkm_dummy(), /* 34: */
bdev_lkm_dummy(), /* 35: */
bdev_lkm_dummy(), /* 36: */
bdev_lkm_dummy(), /* 37: */
bdev_lkm_dummy(), /* 38: */
bdev_lkm_dummy(), /* 39: */
bdev_lkm_dummy(), /* 40: */
bdev_lkm_dummy(), /* 41: */
bdev_lkm_dummy(), /* 42: */
bdev_lkm_dummy(), /* 43: */
bdev_lkm_dummy(), /* 44: */
bdev_lkm_dummy(), /* 45: */
bdev_lkm_dummy(), /* 46: */
bdev_lkm_dummy(), /* 47: */
bdev_lkm_dummy(), /* 48: */
bdev_lkm_dummy(), /* 49: */
bdev_lkm_dummy(), /* 50: */
bdev_lkm_dummy(), /* 51: */
bdev_lkm_dummy(), /* 52: */
bdev_lkm_dummy(), /* 53: */
bdev_lkm_dummy(), /* 54: */
bdev_lkm_dummy(), /* 55: */
bdev_lkm_dummy(), /* 56: */
bdev_lkm_dummy(), /* 57: */
bdev_lkm_dummy(), /* 58: */
bdev_lkm_dummy(), /* 59: */
bdev_lkm_dummy(), /* 60: */
bdev_lkm_dummy(), /* 61: */
bdev_lkm_dummy(), /* 62: */
bdev_lkm_dummy(), /* 63: */
bdev_lkm_dummy(), /* 64: */
bdev_lkm_dummy(), /* 65: */
bdev_lkm_dummy(), /* 66: */
bdev_lkm_dummy(), /* 67: */
bdev_lkm_dummy(), /* 68: */
bdev_lkm_dummy(), /* 69: */
bdev_lkm_dummy(), /* 70: */
bdev_disk_init(NRAID,raid), /* 71: RAIDframe disk driver */
bdev_lkm_dummy(), /* 72: */
};
int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
#include "i4b.h"
#include "i4bctl.h"
#include "i4btrc.h"
#include "i4brbch.h"
#include "i4btel.h"
cdev_decl(i4b);
cdev_decl(i4bctl);
cdev_decl(i4btrc);
cdev_decl(i4brbch);
cdev_decl(i4btel);
#include "pty.h"
#define ptstty ptytty
#define ptsioctl ptyioctl
#define ptctty ptytty
#define ptcioctl ptyioctl
#include "com.h"
#include "lpt.h"
#include "bpfilter.h"
#include "tun.h"
#include "audio.h"
#include "midi.h"
#include "sequencer.h"
#include "ipfilter.h"
#include "rnd.h"
#include "profiler.h"
#include "ofcons.h"
#include "ofrom.h"
#include "ofrtc.h" /* XXX not used for anything?! */
#include "scr.h"
#include "joy.h"
#include "vcoda.h" /* coda file system */
#include "wsdisplay.h"
#include "wskbd.h"
#include "wsmouse.h"
#include "wsmux.h"
#include "scsibus.h"
#include "openfirm.h"
/* Character devices */
struct cdevsw cdevsw[] = {
cdev_mm_init(1, mm), /* 0: /dev/{null,mem,kmem,...} */
cdev_swap_init(1, sw), /* 1: /dev/drum (swap pseudo-device) */
cdev_cn_init(1, cn), /* 2: virtual console */
cdev_ctty_init(1,ctty), /* 3: controlling terminal */
cdev_tty_init(NOFCONS,ofcons_), /* 4: Openfirmware console */
cdev_log_init(1,log), /* 5: /dev/klog */
cdev_ptc_init(NPTY,ptc), /* 6: pseudo-tty master */
cdev_tty_init(NPTY,pts), /* 7: pseudo-tty slave */
cdev_lpt_init(NLPT,lpt), /* 8: parallel printer */
cdev_lkm_dummy(), /* 9: qms driver */
cdev_lkm_dummy(), /* 10: simple beep device */
cdev_lkm_dummy(), /* 11: kbd device */
cdev_tty_init(NCOM,com), /* 12: serial port */
cdev_lkm_dummy(), /* 13: */
cdev_lkm_dummy(), /* 14: */
cdev_lkm_dummy(), /* 15: */
cdev_disk_init(NWD, wd), /* 16: ST506/ESDI/IDE disk */
cdev_lkm_dummy(), /* 17: floppy diskette */
cdev_disk_init(NMD, md), /* 18: memory disk driver */
cdev_disk_init(NVND,vnd), /* 19: vnode disk driver */
cdev_lkm_dummy(), /* 20: */
cdev_disk_init(NCCD,ccd), /* 21: concatenated disk driver */
cdev_lkm_dummy(), /* 22: */
cdev_lkm_dummy(), /* 23: */
cdev_disk_init(NSD,sd), /* 24: SCSI disk */
cdev_tape_init(NST,st), /* 25: SCSI tape */
cdev_disk_init(NCD,cd), /* 26: SCSI CD-ROM */
cdev_lkm_dummy(), /* 27: SCSI autochanger */
cdev_lkm_dummy(), /* 28: SCSI unknown */
cdev_lkm_dummy(), /* 29: SCSI scanner */
cdev_lkm_dummy(), /* 30: */
cdev_lkm_dummy(), /* 31: */
cdev_bpftun_init(NBPFILTER,bpf),/* 32: Berkeley packet filter */
cdev_bpftun_init(NTUN,tun), /* 33: network tunnel */
cdev_fd_init(1,filedesc), /* 34: file descriptor pseudo-device */
cdev_lkm_init(NLKM,lkm), /* 35: loadable module driver */
cdev_audio_init(NAUDIO,audio), /* 36: generic audio I/O */
cdev_lkm_dummy(), /* 37: vidcconsole device */
cdev_lkm_dummy(), /* 38: removed cpu device */
cdev_lkm_dummy(), /* 39: reserved */
cdev_lkm_dummy(), /* 40: PS2 mouse driver */
cdev_lkm_dummy(), /* 41: reserved */
cdev_lkm_dummy(), /* 42: IIC bus driver */
cdev_lkm_dummy(), /* 43: RTC driver */
cdev_lkm_dummy(), /* 44: reserved */
cdev_lkm_dummy(), /* 45: reserved */
cdev_ipf_init(NIPFILTER,ipl), /* 46: ip-filter device */
cdev_lkm_dummy(), /* 47: reserved */
cdev_lkm_dummy(), /* 48: reserved */
cdev_mm_init(NOFROM, ofrom), /* 49: ofrom */
cdev_tty_init(NSCR,scr), /* 50: Smart card reader */
cdev_notdef(), /* 51: reserved */
cdev_rnd_init(NRND,rnd), /* 52: random source pseudo-device */
cdev_prof_init(NPROFILER, prof), /* 53: fiq Profiler*/
cdev_lkm_dummy(), /* 54: FOOTBRIDGE console */
cdev_lkm_dummy(), /* 55: Reserved for bypass device */
cdev_joy_init(NJOY,joy), /* 56: ISA joystick */
cdev_midi_init(NMIDI,midi), /* 57: MIDI I/O */
cdev_midi_init(NSEQUENCER,sequencer), /* 58: sequencer I/O */
cdev_vc_nb_init(NVCODA,vc_nb_), /* 59: coda file system psdev */
cdev_wsdisplay_init(NWSDISPLAY, wsdisplay), /* 60: frame buffers, etc. */
cdev_mouse_init(NWSKBD, wskbd), /* 61: keyboards */
cdev_mouse_init(NWSMOUSE, wsmouse), /* 62: mice */
cdev_lkm_dummy(), /* 63: reserved */
cdev_lkm_dummy(), /* 64: USB controller */
cdev_lkm_dummy(), /* 65: USB generic HID */
cdev_lkm_dummy(), /* 66: USB printer */
cdev_lkm_dummy(), /* 67: reserved */
cdev_lkm_dummy(), /* 68: reserved */
cdev_lkm_dummy(), /* 69: reserved */
cdev_scsibus_init(NSCSIBUS,scsibus), /* 70: SCSI bus */
cdev_disk_init(NRAID,raid), /* 71: RAIDframe disk driver */
cdev_lkm_dummy(), /* 72: USB generic driver */
cdev_mouse_init(NWSMUX,wsmux), /* 73: ws multiplexor */
cdev_lkm_dummy(), /* 74: USB tty */
cdev_lkm_dummy(), /* 75: Diamond Rio 500 */
cdev_lkm_dummy(), /* USB scanner */
cdev_openfirm_init(NOPENFIRM,openfirm),/* 77: openfirmware */
cdev_lkm_dummy(), /* 78: i4b main device */
cdev_lkm_dummy(), /* 79: i4b control device */
cdev_lkm_dummy(), /* 80: i4b raw b-channel access */
cdev_lkm_dummy(), /* 81: i4b trace device */
cdev_lkm_dummy(), /* 82: i4b phone device */
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
int mem_no = 0; /* major device number of memory special file */
/*
* Swapdev is a fake device implemented
* in sw.c used only internally to get to swstrategy.
* It cannot be provided to the users, because the
* swstrategy routine munches the b_dev and b_blkno entries
* before calling the appropriate driver. This would horribly
* confuse, e.g. the hashing routines. Instead, /dev/drum is
* provided as a character (raw) device.
*/
dev_t swapdev = makedev(1, 0);
/*
* Returns true if dev is /dev/mem or /dev/kmem.
*/
int
iskmemdev(dev)
dev_t dev;
{
return (major(dev) == mem_no && minor(dev) < 2);
}
/*
* Returns true if dev is /dev/zero.
*/
int
iszerodev(dev)
dev_t dev;
{
return (major(dev) == mem_no && minor(dev) == 3);
}
static int chrtoblktbl[] = {
/* XXXX This needs to be dynamic for LKMs. */
/*VCHR*/ /*VBLK*/
/* 0 */ NODEV,
/* 1 */ 1,
/* 2 */ NODEV,
/* 3 */ NODEV,
/* 4 */ NODEV,
/* 5 */ NODEV,
/* 6 */ NODEV,
/* 7 */ NODEV,
/* 8 */ NODEV,
/* 9 */ NODEV,
/* 10 */ NODEV,
/* 11 */ NODEV,
/* 12 */ NODEV,
/* 13 */ NODEV,
/* 14 */ NODEV,
/* 15 */ NODEV,
/* 16 */ 16,
/* 17 */ 17,
/* 18 */ 18,
/* 19 */ 19,
/* 20 */ NODEV,
/* 21 */ 21,
/* 22 */ NODEV,
/* 23 */ NODEV,
/* 24 */ 24,
/* 25 */ 25,
/* 26 */ 26,
/* 27 */ NODEV,
/* 28 */ NODEV,
/* 29 */ NODEV,
/* 30 */ NODEV,
/* 31 */ NODEV,
/* 32 */ NODEV,
/* 33 */ NODEV,
/* 34 */ NODEV,
/* 35 */ NODEV,
/* 36 */ NODEV,
/* 37 */ NODEV,
/* 38 */ NODEV,
/* 39 */ NODEV,
/* 40 */ NODEV,
/* 41 */ NODEV,
/* 42 */ NODEV,
/* 43 */ NODEV,
/* 44 */ NODEV,
/* 45 */ NODEV,
/* 46 */ NODEV,
/* 47 */ NODEV,
/* 48 */ NODEV,
/* 49 */ NODEV,
/* 50 */ NODEV,
/* 51 */ NODEV,
/* 52 */ NODEV,
/* 53 */ NODEV,
/* 54 */ NODEV,
/* 55 */ NODEV,
/* 56 */ NODEV,
/* 57 */ NODEV,
/* 58 */ NODEV,
/* 59 */ NODEV,
/* 60 */ NODEV,
/* 61 */ NODEV,
/* 62 */ NODEV,
/* 63 */ NODEV,
/* 64 */ NODEV,
/* 65 */ NODEV,
/* 66 */ NODEV,
/* 67 */ NODEV,
/* 68 */ NODEV,
/* 69 */ NODEV,
/* 70 */ NODEV,
/* 71 */ 71,
/* 72 */ NODEV,
/* 73 */ NODEV,
/* 74 */ NODEV,
/* 75 */ NODEV,
/* 76 */ NODEV,
/* 77 */ NODEV,
/* 78 */ NODEV,
/* 79 */ NODEV,
/* 80 */ NODEV,
/* 81 */ NODEV,
/* 82 */ NODEV,
};
/*
* Convert a character device number to a block device number.
*/
dev_t
chrtoblk(dev)
dev_t dev;
{
int blkmaj;
if (major(dev) >= nchrdev)
return (NODEV);
blkmaj = chrtoblktbl[major(dev)];
if (blkmaj == NODEV)
return (NODEV);
return (makedev(blkmaj, minor(dev)));
}

View File

@ -0,0 +1,74 @@
/* $NetBSD: db_ofw_machdep.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright (c) 1996 Mark Brinicombe
*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/systm.h>
#include <machine/db_machdep.h>
#include <ddb/db_access.h>
#include <ddb/db_sym.h>
#include <ddb/db_output.h>
#include <dev/ofw/openfirm.h>
void
db_of_boot_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
char *modif;
{
OF_boot("");
}
void
db_of_enter_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
char *modif;
{
OF_enter();
}
void
db_of_exit_cmd(addr, have_addr, count, modif)
db_expr_t addr;
int have_addr;
db_expr_t count;
char *modif;
{
OF_exit();
}

View File

@ -0,0 +1,364 @@
/* $NetBSD: dnard_machdep.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
* Kernel setup for the SHARK Configuration
*/
#include "opt_ddb.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/buf.h>
#include <sys/exec.h>
#include <uvm/uvm_extern.h>
#include <dev/cons.h>
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#include <ddb/db_extern.h>
#include <machine/frame.h>
#include <machine/cpu.h>
#include <machine/irqhandler.h>
#include <machine/pio.h>
#include <machine/pte.h>
#include <machine/undefined.h>
#include "opt_ipkdb.h"
#include <dev/ofw/openfirm.h>
#include <machine/ofw.h>
#include <machine/isa_machdep.h>
#include <dev/isa/isavar.h>
#include <dev/ofisa/ofisavar.h>
#include <dnard/dnard/sequoia.h>
#include "wd.h"
#include "cd.h"
#include "sd.h"
#if NWD > 0 || NSD > 0 || NCD > 0
#include <dev/ata/atavar.h>
#endif
#if NSD > 0 || NCD > 0
#include <dev/scsipi/scsi_all.h>
#include <dev/scsipi/scsipi_all.h>
#include <dev/scsipi/scsipiconf.h>
#endif
/*
* Imported variables
*/
extern pv_addr_t irqstack;
extern pv_addr_t undstack;
extern pv_addr_t abtstack;
extern pv_addr_t kernelstack;
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
/*
* Imported routines
*/
extern void parse_mi_bootargs __P((char *args));
extern void data_abort_handler __P((trapframe_t *frame));
extern void prefetch_abort_handler __P((trapframe_t *frame));
extern void undefinedinstruction_bounce __P((trapframe_t *frame));
extern void consinit __P((void));
#ifdef DDB
extern void db_machine_init __P((void));
#endif
int ofbus_match __P((struct device *, struct cfdata *, void *));
void ofbus_attach __P((struct device *, struct device *, void *));
/*
* Exported variables
*/
char *boot_args = NULL;
char *boot_file = NULL;
char *boot_kernel = NULL;
#ifndef PMAP_STATIC_L1S
int max_processes = 64; /* Default number */
#endif /* !PMAP_STATIC_L1S */
int ofw_handleticks = 0; /* set to TRUE by cpu_initclocks */
/*
* For faster cache cleaning we need two 16K banks of virtual address
* space that NOTHING else will access and then we alternate the cache
* cleaning between the two banks.
* The cache cleaning code requires requires 2 banks aligned
* on total size boundry so the banks can be alternated by
* xorring the size bit (assumes the bank size is a power of 2)
*/
extern unsigned int sa110_cache_clean_addr;
extern unsigned int sa110_cache_clean_size;
struct cfattach ofbus_root_ca = {
sizeof(struct device), ofbus_match, ofbus_attach
};
/*
* Exported routines
*/
/* Move to header file? */
extern void cpu_reboot __P((int, char *));
extern vaddr_t initarm __P((ofw_handle_t));
/* Local routines */
static void process_kernel_args __P((void));
/**************************************************************/
/*
* void cpu_reboot(int howto, char *bootstr)
*
* Reboots the system, in evsent of:
* - reboot system call
* - panic
*/
void
cpu_reboot(howto, bootstr)
int howto;
char *bootstr;
{
/* Just call OFW common routine. */
ofw_boot(howto, bootstr);
OF_boot("not reached -- stupid compiler");
}
/*
* vaddr_t initarm(ofw_handle_t handle)
*
* Initial entry point on startup for a GENERIC OFW
* system. Called with MMU on, running in the OFW
* client environment.
*
* Major tasks are:
* - read the bootargs out of OFW;
* - take over memory management from OFW;
* - set-up the stacks
* - set-up the exception handlers
*
* Return the new stackptr (va) for the SVC frame.
*
*/
vaddr_t
initarm(ofw_handle)
ofw_handle_t ofw_handle;
{
vaddr_t pclean;
vaddr_t isa_io_physaddr, isa_mem_physaddr;
vaddr_t isa_io_virtaddr, isa_mem_virtaddr;
vaddr_t isadmaphysbufs;
fiqhandler_t fiqhandler;
extern void shark_fiq __P((void));
extern void shark_fiq_end __P((void));
/* Don't want to get hit with interrupts 'til we're ready. */
(void)disable_interrupts(I32_bit | F32_bit);
set_cpufuncs();
/* XXX - set these somewhere else? -JJK */
boothowto = 0;
/* Init the OFW interface. */
/* MUST do this before invoking any OFW client services! */
ofw_init(ofw_handle);
/* Configure ISA stuff: must be done before consinit */
ofw_configisa(&isa_io_physaddr, &isa_mem_physaddr);
/* Map-in ISA I/O and memory space. */
/* XXX - this should be done in the isa-bus attach routine! -JJK */
isa_mem_virtaddr = ofw_map(isa_mem_physaddr, NBPD, 0);
isa_io_virtaddr = ofw_map(isa_io_physaddr, NBPD, 0);
/* Set-up the ISA system: must be done before consinit */
isa_init(isa_io_virtaddr, isa_mem_virtaddr);
/* Initialize the console (which will call into OFW). */
/* This will allow us to see panic messages and other printf output. */
consinit();
/* Get boot info and process it. */
ofw_getbootinfo(&boot_file, &boot_args);
process_kernel_args();
ofw_configisadma(&isadmaphysbufs);
isa_dma_init();
/* allocate a cache clean space */
if ((pclean = ofw_getcleaninfo()) != -1) {
sa110_cache_clean_addr = ofw_map(pclean, 0x4000 * 2,
PT_B | PT_C);
sa110_cache_clean_size = 0x4000;
}
/* Configure memory. */
ofw_configmem();
/*
* Set-up stacks.
* The kernel stack for SVC mode will be updated on return
* from this routine.
*/
set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + NBPG);
set_stackptr(PSR_UND32_MODE, undstack.pv_va + NBPG);
set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + NBPG);
/* Set-up exception handlers. */
/*
* Take control of selected vectors from OFW.
* We take: undefined, swi, pre-fetch abort, data abort, addrexc,
* irq, fiq
* OFW retains: reset
*/
{
int our_vecnums[] = {1, 2, 3, 4, 5, 6, 7};
unsigned int *vectors = (unsigned int *)0;
extern unsigned int page0[];
int i;
for (i = 0; i < (sizeof(our_vecnums) / sizeof(int)); i++) {
int vecnum = our_vecnums[i];
/* Copy both the instruction and the data word
* for the vector.
* The latter is needed to support branching
* arbitrarily far.
*/
vectors[vecnum] = page0[vecnum];
vectors[vecnum + 8] = page0[vecnum + 8];
}
/* Sync the first 16 words of memory */
cpu_cache_syncI_rng(0, 64);
}
data_abort_handler_address = (u_int)data_abort_handler;
prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
undefined_handler_address =
(u_int)undefinedinstruction_bounce; /* why is this needed? -JJK */
/* Initialise the undefined instruction handlers. */
undefined_init();
/* Now for the SHARK-specific part of the FIQ set-up */
fiqhandler.fh_func = shark_fiq;
fiqhandler.fh_size = (char *)shark_fiq_end - (char *)shark_fiq;
fiqhandler.fh_mask = 0x01; /* XXX ??? */
fiqhandler.fh_r8 = isa_io_virtaddr;
fiqhandler.fh_r9 = 0; /* no routine right now */
fiqhandler.fh_r10 = 0; /* no arg right now */
fiqhandler.fh_r11 = 0; /* scratch */
fiqhandler.fh_r12 = 0; /* scratch */
fiqhandler.fh_r13 = 0; /* must set a stack when r9 is set! */
if (fiq_claim(&fiqhandler))
panic("Cannot claim FIQ vector.\n");
#ifdef DDB
printf("ddb: ");
db_machine_init();
{
struct exec *kernexec = (struct exec *)KERNEL_BASE;
extern int end;
extern char *esym;
ddb_init(kernexec->a_syms, &end, esym);
}
if (boothowto & RB_KDB)
Debugger();
#endif
/* Return the new stackbase. */
return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
}
/*
* Set various globals based on contents of boot_args
*
* Note that this routine must NOT trash boot_args, as
* it is scanned by later routines.
*/
static void
process_kernel_args(void)
{
#ifdef RB_QUIET
int bool;
#endif
#if defined(RB_QUIET) && defined(BOOT_QUIETLY)
boothowto |= RB_QUIET;
#endif
/* Process all the generic ARM boot options */
parse_mi_bootargs(boot_args);
#ifdef RB_QUIET
if (get_bootconf_option(args, "noquiet", BOOTOPT_TYPE_BOOLEAN, &bool)) {
if (!bool)
boothowto |= RB_QUIET;
else
boothowto &= ~RB_QUIET;
}
if (get_bootconf_option(args, "quiet", BOOTOPT_TYPE_BOOLEAN, &bool)) {
if (bool)
boothowto |= RB_QUIET;
else
boothowto &= ~RB_QUIET;
}
#endif
/* Check for ofwgencfg-specific args here. */
}

151
sys/arch/dnard/dnard/fiq.S Normal file
View File

@ -0,0 +1,151 @@
/* $NetBSD: fiq.S,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
* fiq.S
*
* Low level fiq handlers
*
* Created : 19/05/97
*/
#include <machine/asm.h>
#include <machine/cpu.h>
#include <dnard/dnard/fiq.h>
#include <dnard/dnard/sequoia.h>
sp .req r13
lr .req r14
pc .req r15
.text
/* this variable is used to detect when it is necessary to unwedge the
sequoia SMI/PMI edge detect logic. *sigh* */
Lfiqs_happened:
.word _C_LABEL(fiqs_happened)
Lsequoia_index_cache:
.word _C_LABEL(sequoia_index_cache)
.data
.global _C_LABEL(fiqs_happened)
_C_LABEL(fiqs_happened):
.word 0
.text
.global _C_LABEL(shark_fiq)
.global _C_LABEL(shark_fiq_end)
/*
* r8 - VAM_IO_DATA = address of IO space in virtual memory
* r9 - C routine to call (0 => no routine)
* r10 - argument (0 => pass PMI reason register)
* r11 - scratch
* r12 - scratch
* r13 - stack for C routine call
*/
_C_LABEL(shark_fiq):
/* clear the FIQ immediately */
/* do the FIQ/SMI clear here to avoid synchronization problems!
both the chip enable (caused by the ISA register read) and
the sequoia bit clear must be done. do it in that order so
the sequoia port accesses will clear the chip enable caused
by accessing FIQ_CLEAR_IOPORT
*/
/* set up to read/write the power management status register */
ldr r11, Lsequoia_index_cache
ldr r12, [r11]
/* see if the index is properly set. unfortunately, the common
case will probably be that the FIQ handler (e.g. smartcard)
talks to the sequoia, so the index will need to be set. */
cmp r12, #PMC_PMSR_REG
movne r12, #PMC_PMSR_REG
#ifdef STRH
strneh r12, [r8, #SEQUOIA_INDEX]
#else
.word 0x11c8c2b4
#endif
strne r12, [r11]
/* set SMIACT by changing the power management mode to sleep */
mov r12, #PMMD_SLEEP
#ifdef STRH
strh r12, [r8, #SEQUOIA_DATA]
#else
.word 0xe1c8c2b6
#endif
/* get the PMI reason register, if desired */
cmp r10, #0
#ifdef LDRH
ldreqh r10, [r8, #SEQUOIA_DATA]
#else
.word 0x01d8a2b6 /* ldrh r10, [r8, #0x26] */
#endif
/* simultaneously clear the PMI reason bits and clear SMIACT */
mov r12, #PMMD_ON
orr r12, r12, #PMSR_M_PMISRC
#ifdef STRH
strh r12, [r8, #SEQUOIA_DATA]
#else
.word 0xe1c8c2b6
#endif
ldr r12, Lfiqs_happened
ldr r11, [r12]
add r11, r11, #1
str r11, [r12]
cmp r9, #0
subeqs pc, lr, #4 /* no routine => return from trap */
/* assume that the C routine follows the ARM procedure call standard.
save only user registers and let the C code save the rest.
r0-r3, r12, r14 clobbered. other regs should be restored
by C code.
*/
stmfd sp!, {r0-r3, lr} /* save user registers */
mov r0, r10 /* pass the PMI reason register */
mov lr, pc /* call C routine */
mov pc, r9
ldmfd sp!, {r0-r3, lr} /* restore user registers */
subs pc, lr, #4 /* return from trap */
_C_LABEL(shark_fiq_end):
/* End of fiq.S */

View File

@ -0,0 +1,52 @@
/* $NetBSD: fiq.h,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
* fiq.h
*
* Low level fiq handlers
*
* Created : 20/05/97
*/
#ifndef _FIQ_H_
#include <dev/isa/isareg.h>
/* FIQ_CLEAR_IOPORT can be anywhere, as long as it is harmless.
IO_TIMER2 seems pretty harmless on SHARK. */
#define FIQ_CLEAR_IOPORT IO_TIMER2
#endif /* _FIQ_H_ */

200
sys/arch/dnard/dnard/hat.c Normal file
View File

@ -0,0 +1,200 @@
/* $NetBSD: hat.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
* hat.c
*
* implementation of high-availability timer on SHARK
*
* Created : 19/05/97
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <machine/cpu.h>
#include <machine/irqhandler.h>
#include <machine/pio.h>
#include <machine/cpufunc.h>
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <dnard/isa/timerreg.h>
#include <dnard/dnard/fiq.h>
#include <dnard/dnard/sequoia.h>
extern int fiq_getregs __P((fiqhandler_t *));
extern int fiq_setregs __P((fiqhandler_t *));
static int hatOn = 0;
/* interface to high-availability timer */
static void hatClkCount(int count);
static void hatEnableSWTCH();
static void (*hatWedgeFn)(int);
int hatClkOff(void)
{
fiqhandler_t fiqhandler;
u_int16_t seqReg;
if (!hatOn) return -1;
hatOn = 0;
hatWedgeFn = NULL;
/* disable the SWTCH pin */
sequoiaRead(PMC_PMCMCR2_REG, &seqReg);
sequoiaWrite(PMC_PMCMCR2_REG, seqReg | (PMCMCR2_M_SWTCHEN));
/* turn off timer 2 */
outb(ATSR_REG1_REG,
inb(ATSR_REG1_REG) & ~((REG1_M_TMR2EN) | (REG1_M_SPKREN)));
fiq_getregs(&fiqhandler);
/* get rid of the C routine and stack */
fiqhandler.fh_r9 = 0;
fiqhandler.fh_r13 = 0;
fiq_setregs(&fiqhandler);
isa_dmathaw(&isa_chipset_tag); /* XXX */
return 0;
}
int hatClkOn(int count, void (*hatFn)(int), int arg,
unsigned char *stack, void (*wedgeFn)(int))
{
fiqhandler_t fiqhandler;
u_int16_t seqReg;
if (hatOn) return -1;
hatWedgeFn = wedgeFn;
isa_dmafreeze(&isa_chipset_tag); /* XXX */
fiq_getregs(&fiqhandler);
/* set the C routine and stack */
fiqhandler.fh_r9 = (u_int)hatFn;
fiqhandler.fh_r10 = (u_int)arg;
fiqhandler.fh_r13 = (u_int)stack;
fiq_setregs(&fiqhandler);
/* no debounce on SWTCH */
sequoiaRead(PMC_DBCR_REG, &seqReg);
sequoiaWrite(PMC_DBCR_REG, seqReg | DBCR_M_DBDIS0);
hatEnableSWTCH(); /* enable the SWTCH -> PMI logic */
/* turn on timer 2 */
outb(ATSR_REG1_REG,
inb(ATSR_REG1_REG) | (REG1_M_TMR2EN) | (REG1_M_SPKREN));
/* start timer 2 running */
hatClkCount(count);
/* enable the SWTCH pin */
sequoiaRead(PMC_PMCMCR2_REG, &seqReg);
sequoiaWrite(PMC_PMCMCR2_REG, seqReg | (PMCMCR2_M_SWTCHEN));
hatOn = 1;
return 0;
}
int hatClkAdjust(int count)
{
if (!hatOn) return -1;
hatClkCount(count);
hatEnableSWTCH();
return 0;
}
static void
hatEnableSWTCH()
{
u_int16_t seqReg;
/* SWTCH input causes PMI, not automatic switch to standby mode! */
/* clearing bit 9 is bad news. seems to enable PMI from secondary
activity timeout! */
/* first setting, then clearing this bit seems to unwedge the edge
detect logic in the sequoia */
sequoiaRead(PMC_PMIMCR_REG, &seqReg);
sequoiaWrite(PMC_PMIMCR_REG, seqReg | (PMIMCR_M_IMSKSWSTBY));
sequoiaWrite(PMC_PMIMCR_REG, seqReg & ~(PMIMCR_M_IMSKSWSTBY));
}
void hatUnwedge()
{
static int lastFiqsHappened = -1;
extern int fiqs_happened;
if (!hatOn) return;
if (lastFiqsHappened == fiqs_happened) {
hatEnableSWTCH();
if (hatWedgeFn) (*hatWedgeFn)(fiqs_happened);
} else {
lastFiqsHappened = fiqs_happened;
}
}
static void hatClkCount(int count)
{
u_int savedints;
savedints = disable_interrupts(I32_bit);
outb(TIMER_MODE, TIMER_SEL2|TIMER_RATEGEN|TIMER_16BIT);
outb(TIMER_CNTR2, count % 256);
outb(TIMER_CNTR2, count / 256);
restore_interrupts(savedints);
}

View File

@ -0,0 +1,91 @@
/* $NetBSD: hat.h,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
* hat.h
*
* interface to high-availability timer on SHARK
*
* Created : 19/05/97
*/
/* interface to high-availability timer.
DO NOT CALL ANY OF THESE FUNCTIONS FROM CODE CALLED BY THE FIQ!
(e.g. hatFn)
*/
/* hatClkOff(): turn off HAT clock.
returns: 0 => success -1 => error
*/
int hatClkOff(void);
/* hatClkOn(): turn on HAT clock.
count = count for ISA TIMER 2, which generates HAT clock
hatFn = function to be called on every HAT FIQ.
arg = argument to pass to hatFn.
if (arg == 0)
then the FIQ handler will pass the contents of
sequoia register 001H, including the PMI source bits
otherwise the FIQ handler will not load the register and
will pass arg directly
stack = stack for hatFn
wedgeFn = function called when the HAT wedges and needs to be restarted.
the argument is the total number of FIQs received by the system.
(wraps at 32-bits).
returns: 0 => success -1 => error
*/
int hatClkOn(int count, void (*hatFn)(int), int arg,
unsigned char *stack, void (*wedgeFn)(int));
/* hatClkAdjust: adjusts the speed of the HAT.
count = new count for ISA TIMER 2
returns: 0 => success -1 => error
*/
int hatClkAdjust(int count);
/* hatUnwedge: call this function periodically (slower than the frequency
of the HAT) to unwedge the HAT, if necessary.
*/
void hatUnwedge();
/* HAT_MIN_FREQ: should be a power of 2. Call hatUnwedge() no more
often than HAT_MIN_FREQ. HMF should be a power of 2.
*/
#define HAT_MIN_FREQ 64

View File

@ -0,0 +1,363 @@
/* $NetBSD: ns87307.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
**++
**
** FACILITY:
**
** ns87307 SuperIO chip configuration functions.
**
** ABSTRACT:
**
** This file contains routines to configure the National Semiconductor
** PC87307VUL SuperIO chip.
**
** AUTHORS:
**
** John Court, Digital Equipment Corporation.
**
** CREATION DATE:
**
** 16/4/1997
**
**--
*/
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <dev/isa/isavar.h>
#include <dnard/dnard/ns87307reg.h>
/*
**++
** FUNCTION NAME:
**
** i87307KbdConfig
**
** FUNCTIONAL DESCRIPTION:
**
** This function configures the Keyboard controller logical
** device on the ns87307 SuperIO hardware. It sets up the addresses
** of the data and command ports and configures the irq number and
** triggering for the device. It then activates the device.
**
** FORMAL PARAMETERS:
**
** iot
** kbdBase
** irqNum
**
** IMPLICIT INPUTS:
**
** None.
**
** IMPLICIT OUTPUTS:
**
** None.
**
** function value or completion codes
**
** TRUE configuration of the kdb device was successful.
** FALSE configuration of the kdb device failed.
**
** SIDE EFFECTS:
**
** None.
**--
*/
int
i87307KbdConfig(bus_space_tag_t iot,
u_int kbdBase,
u_int irqNum )
{
u_int configured = FALSE;
bus_space_handle_t ioh;
if (!(bus_space_map( iot, CONNSIOADDR, NSIO_NPORTS, 0 , &ioh )))
{
NSIO_SELECT_DEV( iot, ioh, NSIO_DEV_KBC );
NSIO_DEACTIVATE_DEV( iot, ioh );
NSIO_CONFIG_IRQ( iot, ioh, irqNum, NSIO_IRQ_LEVEL | NSIO_IRQ_HIGH );
NSIO_CONFIG_KBCDATA( iot, ioh, kbdBase );
NSIO_CONFIG_KBCCMD(iot, ioh, kbdBase+4);
NSIO_WRITE_REG( iot, ioh, NSIO_KBC_CFG, 0x80 );
NSIO_ACTIVATE_DEV( iot, ioh );
NSIO_CONFIG_KBCDEBUG( iot, ioh );
/* unmap the space so can probe later
*/
bus_space_unmap( iot, ioh, NSIO_NPORTS );
configured = TRUE;
}
return (configured);
} /* End i87307KbdConfig() */
/*
**++
** FUNCTION NAME:
**
** i87307MouseConfig
**
** FUNCTIONAL DESCRIPTION:
**
** This function configures the Mouse logical device on the ns87307
** SuperIO chip. It sets up only the interrupt parameters since the
** mouse shares the device ports with the Keyboard. It also activates
** the device.
**
** FORMAL PARAMETERS:
**
** iot
** irqNum
**
** IMPLICIT INPUTS:
**
** None.
**
** IMPLICIT OUTPUTS:
**
** None.
**
** function value or completion codes
**
** TRUE configuration of the kdb device was successful.
** FALSE configuration of the kdb device failed.
**
** SIDE EFFECTS:
**
** None.
**--
*/
int
i87307MouseConfig(bus_space_tag_t iot,
u_int irqNum )
{
u_int configured;
bus_space_handle_t ioh;
configured = FALSE; /* be a pessimist */
if (!(bus_space_map( iot, CONNSIOADDR, NSIO_NPORTS, 0 , &ioh )))
{
/* Now do the mouse logical device IRQ settup.
*/
NSIO_SELECT_DEV( iot, ioh, NSIO_DEV_MOUSE );
NSIO_DEACTIVATE_DEV( iot, ioh );
NSIO_CONFIG_IRQ( iot, ioh, irqNum, NSIO_IRQ_LEVEL | NSIO_IRQ_HIGH);
NSIO_ACTIVATE_DEV( iot, ioh );
NSIO_CONFIG_DEBUG( iot, ioh );
/* unmap the space so can probe later
*/
bus_space_unmap( iot, ioh, NSIO_NPORTS );
configured = TRUE;
}
return (configured);
} /* End i87307MouseConfig() */
/*
**++
** FUNCTION NAME:
**
** i87307PrinterConfig
**
** FUNCTIONAL DESCRIPTION:
**
** This function configures the Parrel logical device on the ns87307
** SuperIO chip.
** the device.
**
** FORMAL PARAMETERS:
**
** iot
** irqNum
**
** IMPLICIT INPUTS:
**
** None.
**
** IMPLICIT OUTPUTS:
**
** None.
**
** function value or completion codes
**
** TRUE configuration of the kdb device was successful.
** FALSE configuration of the kdb device failed.
**
** SIDE EFFECTS:
**
** None.
**--
*/
int
i87307PrinterConfig(bus_space_tag_t iot,
u_int irqNum )
{
u_int configured = FALSE;
bus_space_handle_t ioh;
u_char value;
if (!(bus_space_map( iot, CONNSIOADDR, NSIO_NPORTS, 0 , &ioh )))
{
/* select the printer */
NSIO_SELECT_DEV( iot, ioh, NSIO_DEV_LPT );
NSIO_DEACTIVATE_DEV( iot, ioh );
value = NSIO_LPT_TRISTATE_DISABLE |
NSIO_LPT_CLOCK_DISABLE |
NSIO_LPT_REPORT_SPP |
NSIO_LPT_REG403_DISABLE |
NSIO_LPT_SPP_EXTENDED;
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_REG0, value);
/* set the type of interupt */
value = NSIO_IRQ_HIGH |
NSIO_IRQ_LEVEL;
NSIO_CONFIG_IRQ( iot, ioh, irqNum,value);
/* activate the device */
NSIO_ACTIVATE_DEV( iot, ioh );
/* unmap the space so can probe later */
bus_space_unmap( iot, ioh, NSIO_NPORTS );
configured = TRUE;
}
return (configured);
} /* End i87307PrinterConfig() */
/*
**++
** FUNCTION NAME:
**
** nsioConfigPrint
**
** FUNCTIONAL DESCRIPTION:
**
** This function prints out the irq, iobase etc, for the
** currently selected logical device. It is intended to
** be used for debugging only.
**
** FORMAL PARAMETERS:
**
** sc pointer to the nsio's softc structure
**
** IMPLICIT INPUTS:
**
** None.
**
** IMPLICIT OUTPUTS:
**
** None.
**
** function value or completion codes
**
** None
**
** SIDE EFFECTS:
**
** None.
**
**--
*/
//#ifdef DDB
void nsioConfigPrint(bus_space_tag_t nsioIot,
bus_space_handle_t nsioIoh )
{
u_char dev;
u_char activate;
u_char iorange;
u_char iobaseh;
u_char iobasel;
u_char irq;
u_char irqType;
u_char dma1;
u_char dma2;
u_char reg0;
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_LOGDEV, dev );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_ACTIVATE, activate );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_IORNGCHK, iorange );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_IOBASEH, iobaseh );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_IOBASEL, iobasel );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_IRQ, irq );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_IRQTYPE, irqType );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_DMA1, dma1 );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_DMA2, dma2 );
NSIO_READ_REG( nsioIot, nsioIoh, NSIO_CFG_REG0, reg0 );
printf("nsio config for logical device %d\n", dev );
printf("activate: %x\n",activate);
printf("iorange: %x\n",iorange);
printf("iobase: %x\n",(iobaseh << 8) | iobasel);
printf("irq: %x\n",irq);
printf("irqtype: %x\n",irqType);
printf("dma1: %x\n",dma1);
printf("dma2: %x\n",dma2) ;
printf("reg0: %x\n",reg0);
}
//#endif

View File

@ -0,0 +1,395 @@
/* $NetBSD: ns87307reg.h,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
**++
**
** FACILITY:
**
** ns87307.h
**
** ABSTRACT:
**
**
**
** AUTHORS:
**
** Patrick Crilly Digital Equipment Corporation.
**
** CREATION DATE:
**
** 25-February-1997
**
**--
*/
#ifndef _NS87307REG_H
#define _NS87307REG_H
/*
** Define TRUE/FALSE if not already defined. It
** annoys me that C doesn't do this in a standard
** header.
*/
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/*
** Macro for debugging
*/
#define NSIODEBUG
#ifdef NSIODEBUG
#define nsioDebug(x) printf x
#else
#define nsioDebug(x)
#endif
/*
** Base address of chip. Used to configure console
** devices.
*/
#ifndef CONNSIOADDR
#define CONNSIOADDR 0x15c
#endif
/*
** Base Register Offsets
*/
#define NSIO_OFFSET_INDEX 0x00 /* Index register */
#define NSIO_OFFSET_DATA 0x01 /* Data register */
/*
** Number of io ports
*/
#define NSIO_NPORTS 2 /* Number of io ports */
/*
** Card Configuration Registers
*/
#define NSIO_CFG_LOGDEV 0x07 /* Select logical device */
#define NSIO_CFG_SID 0x20 /* Chip SID register */
/*
** Logical Device Configuration Registers
*/
#define NSIO_CFG_ACTIVATE 0x30 /* activate register */
#define NSIO_CFG_IORNGCHK 0x31 /* I/O range check register */
#define NSIO_CFG_IOBASEH 0x60 /* IO port base bits 15-8 */
#define NSIO_CFG_IOBASEL 0x61 /* IO port base bits 7-0 */
#define NSIO_CFG_IRQ 0x70 /* Interrupt Request Level */
#define NSIO_CFG_IRQTYPE 0x71 /* Interrupt Request Type */
#define NSIO_CFG_DMA1 0x74 /* DMA channel for DMA 0 */
#define NSIO_CFG_DMA2 0x75 /* DMA channel for DMA 1 */
#define NSIO_CFG_REG0 0xF0 /* First configuration register */
/*
** KBC Configuration Registers
*/
#define NSIO_KBC_DATAH 0x60 /* kbc data address bits 15-8 */
#define NSIO_KBC_DATAL 0x61 /* kbc data address bits 7-0 */
#define NSIO_KBC_CMDH 0x62 /* kbc cmd address bits 15-8 */
#define NSIO_KBC_CMDL 0x63 /* kbc cmd address bits 7-0 */
#define NSIO_KBC_CFG 0xF0 /* kbc Super I/O cfg register */
/*
** Chip SID defines
*/
#define NSIO_CHIP_ID_MASK 0xFC /* Mask to obtain chip id */
#define NSIO_CHIP_ID 0xC0 /* ns87307 chip id */
/*
** Interrupt Type Masks
*/
#define NSIO_IRQ_LEVEL 0x01 /* Trigger, level = 1 edge = 0 */
#define NSIO_IRQ_HIGH 0x02 /* Int level, high = 1 low = 0 */
#define NSIO_IRQ_LOW 0x00
/*
** IO Range check bit masks
*/
#define NSIO_RNGCHK_ENABLE 0x02 /* Enable IO range checking */
#define NSIO_RNGCHK_USE55 0x01 /* Set to read 0x55 */
/*
** Logical Devices
*/
#define NSIO_DEV_KBC 0 /* keyboard controller */
#define NSIO_DEV_MOUSE 1 /* mouse controller */
#define NSIO_DEV_RTC 2 /* real-time clock */
#define NSIO_DEV_FDC 3 /* floppy disk controller */
#define NSIO_DEV_LPT 4 /* parallel port */
#define NSIO_DEV_USI 5 /* USI = UART + inafred */
#define NSIO_DEV_UART 6 /* UART */
#define NSIO_DEV_GPIO 7 /* gerneral purpose I/O */
#define NSIO_DEV_PWR 8 /* power management */
/*
** PARREL PORT CONFIGURATION
*/
#define NSIO_LPT_TRISTATE_DISABLE (0 << 0) /* tri-state when inactive */
#define NSIO_LPT_TRISTATE_ENABLE (1 << 0) /* tri-state when inactive */
#define NSIO_LPT_CLOCK_DISABLE (0 << 1) /* report ecp mode */
#define NSIO_LPT_CLOCK_ENABLE (1 (( 1) /* ecp/epp timeout function when active */
/* bit 2 reserved */
#define NSIO_LPT_REPORT_ECP (0 << 3) /* report ecp mode */
#define NSIO_LPT_REPORT_SPP (1 << 3) /* report spp mode */
#define NSIO_LPT_REG403_DISABLE (0 << 4) /* dont respond to reg 403 */
#define NSIO_LPT_REG403_ENABLE (1 << 4) /* respond to reg 403 */
#define NSIO_LPT_SPP_NORMAL (0x0<< 5)
#define NSIO_LPT_SPP_EXTENDED (0x1<< 5)
#define NSIO_LPT_EPP_V_1_7 (0x2<< 5)
#define NSIO_LPT_EPP_V_1_9 (0x3<< 5)
#define NSIO_LPT_ECP_NO_EPP (0x4<< 5)
/* bit7-5 0x5 reserved */
/* bit7-5 0x6 reserved */
#define NSIO_LPT_ECP_AND_EPP4 (0x7<< 5)
/*
** As there are two devices which can be used for serial
** communication, set up defines so it's easy to configure
** the logical devices used for serial communication.
*/
#define NSIO_DEV_COM0 NSIO_DEV_UART
#define NSIO_DEV_COM1 NSIO_DEV_USI
/*---------------------------------------------------------------------------*/
/* Macros used to configure logical devices */
/*---------------------------------------------------------------------------*/
/*
** NSIO_READ_REG
**
** Read a configuration register. Use the currently
** selected logical device.
**
** sc pointer to nsio devices softc
** reg index of register to read
** value value read from register
*/
#define NSIO_READ_REG( iot, ioh, reg, value ) \
{ \
bus_space_write_1(iot, ioh, NSIO_OFFSET_INDEX, reg ); \
value = bus_space_read_1( iot, ioh, NSIO_OFFSET_DATA ); \
}
/*
** NSIO_WRITE_REG
**
** Write to a configuration register. Use the currently
** selected logical device.
**
** sc pointer to nsio devices softc
** reg index of register to read
** value value read from register
*/
#define NSIO_WRITE_REG( iot, ioh, reg, value ) \
{ \
bus_space_write_1(iot, ioh, NSIO_OFFSET_INDEX, reg ); \
bus_space_write_1( iot, ioh, NSIO_OFFSET_DATA, value ); \
}
/*
** NSIO_SELECT_DEV
**
** Select logDev as the current the logical device
**
** sc pointer to nsio devices softc
** reg index of register to read
** logDev logical device to select
*/
#define NSIO_SELECT_DEV( iot, ioh, logDev ) \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_LOGDEV, logDev )
/*
** NSIO_CONFIG_IRQ
**
** Set the irq number and triggering for the currently
** selected logical device. If irqNum is unknown
** the number won't be set and the device will be left
** with it's default value.
**
** sc pointer to nsio devices softc
** irqNum irq number to set
** irqType trigger flags e.g. edge/level, high/low
*/
#define NSIO_CONFIG_IRQ( iot, ioh, irqNum, irqType ) \
{ \
if ( irqNum != IRQUNK ) \
{ \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_IRQ, irqNum ); \
} \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_IRQTYPE, irqType ); \
}
/*
** NSIO_CONFIG_KBCCMD
**
** Set the io base for the currently selected logical device.
**
** sc pointer to nsio devices softc
** ioBase address to set io base to
*/
#define NSIO_CONFIG_IOBASE( iot, ioh, ioBase ) \
{ \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_IOBASEH, \
(unsigned char)(((ioBase) >> 8) & 0xff) ); \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_IOBASEL, \
(unsigned char)(((ioBase) & 0xff ) ); \
}
/*
** NSIO_CONFIG_KBCDATA
**
** Set the data base for the keyboard. The keyboard
** controller must be the currently selected logical device.
**
** sc pointer to nsio devices softc
** dataBase address to set data base to
*/
#define NSIO_CONFIG_KBCDATA( iot, ioh, dataBase ) \
{ \
NSIO_WRITE_REG( iot, ioh, NSIO_KBC_DATAH, \
(unsigned char)(((dataBase) >> 8) & 0xff) ); \
NSIO_WRITE_REG( iot, ioh, NSIO_KBC_DATAL, \
(unsigned char)((dataBase) & 0xff ) ); \
}
/*
** NSIO_CONFIG_KBCCMD
**
** Set the command base for the keyboard. The keyboard
** controller must be the currently selected logical device.
**
** sc pointer to nsio devices softc
** cmdBase address to set command base to
*/
#define NSIO_CONFIG_KBCCMD( iot, ioh, cmdBase ) \
{ \
NSIO_WRITE_REG( iot, ioh, NSIO_KBC_CMDH, \
(unsigned char)(((cmdBase) >> 8) & 0xff) ); \
NSIO_WRITE_REG( iot, ioh, NSIO_KBC_CMDL, \
(unsigned char)((cmdBase) & 0xff ) ); \
}
/*
** NSIO_ACTIVATE_DEV
**
** Activate the currently selected logical device.
**
** sc pointer to nsio devices softc
*/
#define NSIO_ACTIVATE_DEV( iot, ioh ) \
{ \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_ACTIVATE, (0x01) ); \
}
/*
** NSIO_DEACTIVATE_DEV
**
** Deactivate the currently selected logical device.
**
** sc pointer to nsio devices softc
*/
#define NSIO_DEACTIVATE_DEV( iot, ioh ) \
{ \
NSIO_WRITE_REG( iot, ioh, NSIO_CFG_ACTIVATE, (0x00) ); \
}
/*
** NSIO_CONFIG_DEBUG
**
** Print out configuration information for the device
**
** sc pointer to nsio devices softc
*/
#ifdef DDB
#define NSIO_CONFIG_DEBUG( iot, ioh ) \
{ \
/* nsioConfigPrint( iot, ioh ); */ \
}
#else
#define NSIO_CONFIG_DEBUG( iot, ioh )
#endif
/*
** NSIO_CONFIG_KBCDEBUG
**
** Print out configuration information for the keyboard device
**
** sc pointer to nsio devices softc
*/
#ifdef DDB
#define NSIO_CONFIG_KBCDEBUG( iot, ioh ) \
{ \
u_char cmdL; \
u_char cmdH; \
/* nsioConfigPrint( iot, ioh ); */ \
NSIO_READ_REG( iot, ioh, NSIO_KBC_CMDH, cmdH ); \
NSIO_READ_REG( iot, ioh, NSIO_KBC_CMDH, cmdL ); \
printf("kbc command: %x\n", (((u_short)(cmdH)) << 8)| cmdL ); \
}
#else
#define NSIO_CONFIG_KBCDEBUG( iot, ioh )
#endif
/* Functions to help configure the ns87307 logical devices.
*/
int i87307KbdConfig __P((bus_space_tag_t iot,
u_int comBase,
u_int irqNum ));
int i87307MouseConfig __P((bus_space_tag_t iot,
u_int irqNum ));
void nsioConfigPrint(bus_space_tag_t nsioIot, bus_space_handle_t nsioIoh );
#endif /* _NS87307REG_H */

View File

@ -0,0 +1,719 @@
/* $NetBSD: profile.c,v 1.1 2001/05/09 15:58:07 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
* The fiq based profiler.
*/
#include "profiler.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/time.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/ioctl.h>
#include <sys/map.h>
#include <sys/conf.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/uio.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <dnard/dnard/hat.h>
#include <machine/profileio.h>
#include <dev/ic/i8253reg.h>
#define PROFILER_DEBUG 1
#define countPerTick 500 /* TIMER_FREQ/10000 10 kHz timer */
/* Processor Status Defines */
#define STATUS_MODE_MASK 0x1f
#define USER_MODE 0x10
#define FIQ_MODE 0x11
#define IRQ_MODE 0x12
#define SVC_MODE 0x13
#define ABORT_MODE 0x17
#define UNDEF_MODE 0x1b
#define SYS_MODE 0x1f
/* software controller
*/
struct profiler_sc
{
int state;
#define PROF_OPEN 0x01
#define PROF_PROFILING 0x02
} prof_sc;
/*
* GLOBAL DATA
*/
/* I need my own stack space for the hat */
#define HATSTACKSIZE 1024 /* size of stack used during a FIQ */
static unsigned char hatStack[HATSTACKSIZE]; /* actual stack used
* during a FIQ
*/
/* Pointer to the list of hash tables.
* A backup table is created for every table malloced, this
* is used so that we don't miss samples while copying the
* data out. Thus the actual number of tables in the array is twice
* what nhashTables says.
*/
struct profHashTable *profTable;
struct profHashTable *phashTables[2];
int nhashTables;
/*
* FORWARD DECLARATIONS
*/
static void profFiq(int x);
static void profHatWedge(int nFIQs);
void profStop(void);
void profStart(struct profStartInfo *);
static void profEnter(struct profHashTable * , unsigned int);
void displayTable(struct profHashTable * );
void
profilerattach(n)
int n;
{
/* reset the profiler state */
prof_sc.state = 0;
}
/*
* Open the profiling devicee.
* Returns
* ENXIO for illegal minor device
* ie. if the minor device number is not 0.
* EBUSY if file is open by another process.
* EROFS if attempt to open in write mode.
*/
int
profopen(dev, flag, mode, p)
dev_t dev;
int flag;
int mode;
struct proc *p;
{
/* check that the minor number is correct. */
if (minor(dev) >= NPROFILER)
{
return ENXIO;
}
/* check that the device is not already open. */
if (prof_sc.state && PROF_OPEN)
{
return EBUSY;
}
/* check that the flag is set to read only. */
if (!(flag && FWRITE))
{
return EROFS;
}
/* flag the device as open. */
prof_sc.state |= PROF_OPEN;
nhashTables = 0;
phashTables[0] = phashTables[1] = NULL;
return 0;
}
/*
* Close the descriptor.
*
*/
int
profclose(dev, flag, mode, p)
dev_t dev;
int flag;
int mode;
struct proc *p;
{
/* clear the state, and stop profiling if
* it is happening.
*/
profStop();
prof_sc.state &= ~PROF_OPEN;
return 0;
}
int
profread(dev, uio, flags)
dev_t dev;
struct uio *uio;
int flags;
{
int error;
int real, backup;
/* must be profiling to read */
if (!(prof_sc.state & PROF_PROFILING))
{
error = EINVAL;
}
else
{
if (uio->uio_resid != sizeof(struct profHashHeader) +
profTable->hdr.tableSize * sizeof(struct profHashEntry))
{
printf("profile read size is incorrect!");
error = EINVAL;
}
else
{
/* first work out which table is currently being used.
*/
if (profTable == phashTables[0])
{
real = 0;
backup = 1;
}
else
{
if (profTable == phashTables[1])
{
real = 1;
backup = 0;
}
else
{
panic("profiler lost buffer\n");
}
}
/* now initialise the backup copy before switching over.
*/
memset(phashTables[backup]->entries, 0,
profTable->hdr.tableSize * sizeof(struct profHashEntry));
/* now initialise the header */
phashTables[backup]->hdr.tableSize = phashTables[real]->hdr.tableSize;
phashTables[backup]->hdr.entries = phashTables[backup]->hdr.last
= phashTables[real]->hdr.entries;
phashTables[backup]->hdr.samples = 0;
phashTables[backup]->hdr.missed = 0;
phashTables[backup]->hdr.fiqs = 0;
phashTables[backup]->hdr.pid = phashTables[real]->hdr.pid;
phashTables[backup]->hdr.mode = phashTables[real]->hdr.mode;
/* ok now swap over.
* I don't worry about locking the fiq while I change
* this, at this point it won't matter which table the
* fiq reads.
*/
profTable = phashTables[backup];
/* don't want to send the pointer,
* make assumption that table follows the header.
*/
if ( (error = uiomove(phashTables[real],
sizeof(struct profHashHeader), uio))
!= 0)
{
printf("uiomove failed error is %d\n", error);
}
else
{
if ( (error = uiomove(phashTables[real]->entries,
phashTables[real]->hdr.tableSize *
sizeof(struct profHashEntry), uio))
!= 0)
{
printf("uiomove failed error is %d\n", error);
}
}
}
}
return error;
}
/*
* PROFIOSTART Start Profiling
* PROFIOSTOP Stop Profiling
*/
static int profcount = 0;
static int ints = 0;
int
profioctl(dev, cmd, data, flag, p)
dev_t dev;
u_long cmd;
caddr_t data;
int flag;
struct proc *p;
{
int error = 0;
struct profStartInfo *info = (struct profStartInfo *) data;
switch (cmd)
{
case PROFIOSTART :
profStart(info);
break;
case PROFIOSTOP :
profStop();
break;
default :
error = EINVAL;
break;
}
return error;
}
/* start profiling, returning status information in the
* profStartInfo structure.
*
* presumes pid is running, does no checks here.
*/
void
profStart(struct profStartInfo *info)
{
unsigned int savedInts;
char *buffer;
/* can't already be sampling */
if ( prof_sc.state & PROF_PROFILING )
{
info->status = ALREADY_SAMPLING;
return ;
}
/* sanity check that the table sizes are logical */
if (info->entries > info->tableSize)
{
info->status = BAD_TABLE_SIZE;
return ;
}
/* now sanity check that we are sampling either the
* kernel or a pid or both.
*/
if ( !(info->mode & SAMPLE_MODE_MASK) )
{
info->status = ILLEGAL_COMMAND;
return ;
}
/* alloc two hash tables. */
buffer = malloc(sizeof(struct profHashTable) +
info->tableSize * sizeof(struct profHashEntry),
M_DEVBUF, M_NOWAIT);
if ( (buffer == NULL) )
{
info->status = NO_MEMORY;
return;
}
phashTables[0] = (struct profHashTable *) buffer;
phashTables[0]->entries = (struct profHashEntry *)
( buffer + sizeof(struct profHashTable));
buffer = malloc(sizeof(struct profHashTable) +
info->tableSize * sizeof(struct profHashEntry),
M_DEVBUF, M_NOWAIT);
if ( (buffer == NULL) )
{
free(phashTables[0], M_DEVBUF);
info->status = NO_MEMORY;
return;
}
phashTables[1] = (struct profHashTable *) buffer;
phashTables[1]->entries = (struct profHashEntry *)
( buffer + sizeof(struct profHashTable));
memset(phashTables[0]->entries, 0,
info->tableSize * sizeof(struct profHashEntry));
memset(phashTables[1]->entries, 0,
info->tableSize * sizeof(struct profHashEntry));
/* now initialise the header */
profTable = phashTables[0];
profTable->hdr.tableSize = info->tableSize;
profTable->hdr.entries = profTable->hdr.last = info->entries;
profTable->hdr.samples = 0;
profTable->hdr.missed = 0;
profTable->hdr.fiqs = 0;
profTable->hdr.pid = info->pid;
profTable->hdr.mode = info->mode;
/* now let the pigeons loose. */
savedInts = disable_interrupts(I32_bit | F32_bit);
prof_sc.state |= PROF_PROFILING;
hatClkOn(countPerTick,
profFiq,
(int)&prof_sc,
hatStack + HATSTACKSIZE - sizeof(unsigned),
profHatWedge);
restore_interrupts(savedInts);
}
void
profStop(void)
{
unsigned int savedInts;
int spl;
savedInts = disable_interrupts(I32_bit | F32_bit);
hatClkOff();
restore_interrupts(savedInts);
spl = splbio();
/* only free the buffer's if we were profiling,
* who cares if we were not, won't alert any one.
*/
if (prof_sc.state & PROF_PROFILING)
{
/* now free both buffers. */
free(phashTables[0], M_DEVBUF);
free(phashTables[1], M_DEVBUF);
}
phashTables[0] = phashTables[1] = NULL;
prof_sc.state &= ~PROF_PROFILING;
splx(spl);
}
/*
**++
** FUNCTIONAL DESCRIPTION:
**
** profFiq
**
** This is what the HAT clock calls. This call drives
** the timeout queues, which in turn drive the state machines
**
** Be very carefully when calling a timeout as the function
** that is called may in turn do timeout/untimeout calls
** before returning
**
** FORMAL PARAMETERS:
**
** int x - not used
**
** IMPLICIT INPUTS:
**
** nill
**
** IMPLICIT OUTPUTS:
**
** nill
**
** FUNCTION VALUE:
**
** nill
**
** SIDE EFFECTS:
**
** a timeout may be called if it is due
**--
*/
static void
profFiq(int x)
{
int i;
int *ip; /* the fiq stack pointer */
unsigned int spsr, stacklr; /* the link register, off the stack. */
/* get the link register and see where we came from.
* We do this by getting the stack pointer using,
* an inline assembler instruction and then going 9
* words up to get the return address from the fiq.
*
* NOTE: the stack will change if more local variables
* are added so beware of modifications to this
* function.
* the fiq.S handler puts the following on the stack
* stmfd sp!, {r0-r3, lr}
* then this function does
* mov ip, sp
* stmfd sp!, {r4, fp, ip, lr, pc}
* or some variant of this.
*
* instead of using sp we can use ip, the saved stack pointer
* and be done with the chance of sp changing around on us.
*
* so by the time we get here we have a stack that looks like.
* (see pg 4-23, ARM programming Techniques doco for description
* on stm instructions.)
* lr-fiq (we want this one).
* r3-fiq
* r2-fiq
* r1-fiq
* ip--> r0-fiq
* pc-prof
* lr-prof
* ip-prof
* fp-prof
* sp--> r4-prof
* the sp by the time we get to it will point to r4 at the
* bottom of the stack. So we go 9 up to get the lr we want.
* or even better we have ip pointing to r0 and we can go 4 up
* to get the saved link register.
*
* We are safer this way because fiq.S is coded assembler, we are
* at the mercy of the assembler for our stack.
*
*/
asm("mov %0, ip" : "=r" (ip) : );
stacklr = *(ip+4);
/* get the spsr register
*/
asm("mrs %0, spsr" : "=r" (spsr) : );
/* now check whether we want this sample.
* NB. We place kernel and user level samples in the
* same table.
*/
if ( (profTable->hdr.mode & SAMPLE_PROC) &&
((spsr & STATUS_MODE_MASK) == USER_MODE) )
{
if ( curproc->p_pid == profTable->hdr.pid )
{
profEnter(profTable, stacklr-4);
}
}
if ( profTable->hdr.mode & SAMPLE_KERN )
{
if ( ((spsr & STATUS_MODE_MASK) == SVC_MODE)/* ||
((spsr & STATUS_MODE_MASK) == IRQ_MODE)*/ )
{
/* Note: the link register will be two instructions,
* ahead of the "blamed" instruction. This is actually
* a most likely case and might not actually highlight the
* exact cause of problems, some post processing intelligence
* will be required to make use of this data.
*/
profEnter(profTable, stacklr-4);
}
}
/* increment the samples counter */
profTable->hdr.fiqs++;
}
/*
**++
** FUNCTIONAL DESCRIPTION:
**
** profHatWedge
**
** Called if the HAT timer becomes clogged/wedged. Not
** used by this driver, we let upper layers recover
** from this condition
**
** FORMAL PARAMETERS:
**
** int nFIQs - not used
**
** IMPLICIT INPUTS:
**
** nill
**
** IMPLICIT OUTPUTS:
**
** nill
**
** FUNCTION VALUE:
**
** nill
**
** SIDE EFFECTS:
**
** nill
**--
*/
static void
profHatWedge(int nFIQs)
{
#ifdef PROFILER_DEBUG
printf("profHatWedge: nFIQ = %d\n",nFIQs);
#endif
}
/* Enter the data in the table.
*
* To reduce the time taken to find samples with time
* an eviction algorithm is implemented.
* When a new entry in the overflow area is required
* the first entry in the hash table is copied there
* and the new entry placed as the hash table entry. The
* displaced entry will then be the first entry accessed in
* the table.
*/
static void
profEnter(struct profHashTable *table, unsigned int lr)
{
unsigned int entries, hashShift, index, count;
struct profHashEntry *sample;
struct profHashEntry *first;
struct profHashEntry *prev;
struct profHashEntry tmpEntry;
int tmpIndex;
/* work out how many bits
* are required to hash the given size.
*/
entries = table->hdr.entries - 1;
hashShift = 0;
do
{
entries = entries << 1;
hashShift ++;
} while (!(entries & 0x80000000));
/* enter the pc in the table. */
/* remove redundant bits.
* and save the count offset bits
*/
lr = lr >> REDUNDANT_BITS;
count = lr & COUNT_BIT_MASK;
lr = lr >> COUNT_BITS;
/* this is easier than working out how
* many bits to or, based on the hashShift.
* maybe it would be better to work out at
* the start and save time during the fiq.
*/
index = (lr << hashShift) >> hashShift;
first = sample = &table->entries[index];
/* now loop until we either find the entry
* or the next free space.
*/
while ( (sample->pc != lr) && (table->hdr.last < table->hdr.tableSize) )
{
if (sample->pc == 0)
{
/* go ahead and stick it in */
sample->pc = lr;
}
else
{
if (sample->next != 0)
{
/* move along and continue */
prev = sample;
sample = &table->entries[sample->next];
}
else
{
/* create a new entry if available */
if (table->hdr.last < table->hdr.tableSize)
{
sample = &table->entries[table->hdr.last];
/* copy the first sample into the new
* field.
*/
memcpy(sample, first, sizeof(struct profHashEntry));
/* now update the new entry in the first position.
*/
first->pc = lr;
first->next = table->hdr.last;
first->counts[0] = 0;
first->counts[1] = 0;
first->counts[2] = 0;
first->counts[3] = 0;
table->hdr.last++;
/* update the sample pointer so that we
* can insert the count.
*/
sample = first;
}
}
}
}
/* check if we need to do an eviction. */
if (sample != first)
{
/* copy the sample out of the table. */
memcpy(&tmpEntry, sample, sizeof(struct profHashEntry));
/* remove the sample from the chain. */
tmpIndex = prev->next;
prev->next = sample->next;
/* now insert it at the beginning. */
memcpy(sample, first, sizeof(struct profHashEntry));
memcpy(first, &tmpEntry, sizeof(struct profHashEntry));
/* now make the new first entry point to the old
* first entry.
*/
first->next = tmpIndex;
}
/* must now check the lr
* to see if the table is full.
*/
if (sample->pc == lr)
{
/* update the count */
sample->counts[count]++;
table->hdr.samples++;
}
else
{
table->hdr.missed++;
}
}
void
displayTable(struct profHashTable *table)
{
int i;
struct profHashEntry *sample;
char buff[100] = ".............................................\n";
for (i=0; i < table->hdr.tableSize; i++)
{
sample = &table->entries[i];
if ((i * table->hdr.tableSize) >= table->hdr.entries)
{
printf("%s", buff);
buff[0] = '\0';
}
printf("i = %d, pc = 0x%x, next = %d, counts %d %d %d %d\n",
i, sample->pc, sample->next, sample->counts[0],
sample->counts[1], sample->counts[2], sample->counts[3]);
}
return;
}

4239
sys/arch/dnard/dnard/scr.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,775 @@
/* $NetBSD: sequoia.c,v 1.1 2001/05/09 15:58:08 matt Exp $ */
/*
* Copyright 1997
* Digital Equipment Corporation. All rights reserved.
*
* This software is furnished under license and may be used and
* copied only in accordance with the following terms and conditions.
* Subject to these conditions, you may download, copy, install,
* use, modify and distribute this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce
* and retain this copyright notice and list of conditions as
* they appear in the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Digital Equipment Corporation. Neither the "Digital Equipment
* Corporation" name nor any trademark or logo of Digital Equipment
* Corporation may be used to endorse or promote products derived
* from this software without the prior written permission of
* Digital Equipment Corporation.
*
* 3) This software is provided "AS-IS" and any express or implied
* warranties, including but not limited to, any implied warranties
* of merchantability, fitness for a particular purpose, or
* non-infringement are disclaimed. In no event shall DIGITAL be
* liable for any damages whatsoever, and in particular, DIGITAL
* shall not be liable for special, indirect, consequential, or
* incidental damages or damages for lost profits, loss of
* revenue or loss of use, whether such damages arise in contract,
* negligence, tort, under statute, in equity, at law or otherwise,
* even if advised of the possibility of such damage.
*/
/*
**
** INCLUDE FILES
**
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/callout.h>
#include <sys/syslog.h>
#include <sys/types.h>
#include <machine/bus.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <dev/isa/isareg.h>
#include <machine/isa_machdep.h>
#include <machine/cpufunc.h>
#include <dnard/dnard/sequoia.h>
#include <dnard/dnard/fiq.h>
/*
**
** MACROS
**
*/
#define SET(t, f) (t) |= (f)
#define CLR(t, f) (t) &= ~(f)
#define ISSET(t, f) ((t) & (f))
#define ISCLR(t, f) ( ((t) & (f)) == 0)
/* define regisers on sequoia used by pins */
#define SEQUOIA_1GPIO PMC_GPCR_REG /* reg 0x007 gpio 0-3 */
#define SEQUOIA_2GPIO SEQ2_OGPIOCR_REG /* reg 0x304 gpio 4.8 */
/* define pins on sequoia that talk to smart card reader */
#define SCR_DETECT_DIR GPIOCR2_M_GPIOBDIR0
#define SCR_DETECT GPIOCR2_M_GPIOBDATA0
#define SCR_POWER_DIR GPCR_M_GPIODIR0
#define SCR_POWER GPCR_M_GPIODATA0
#define SCR_RESET_DIR GPCR_M_GPIODIR1
#define SCR_RESET GPCR_M_GPIODATA1
#define SCR_CLOCK_DIR OGPIOCR_M_GPIODIR6
#define SCR_CLOCK OGPIOCR_M_GPIODATA6
#define SCR_DATA_IN_DIR GPCR_M_GPIODIR2
#define SCR_DATA_IN GPCR_M_GPIODATA2
#define SCR_DATA_OUT_DIR OGPIOCR_M_GPIODIR5
#define SCR_DATA_OUT OGPIOCR_M_GPIODATA5
#define SCR_BUGA_DIR OGPIOCR_M_GPIODIR4
#define SCR_BUGA OGPIOCR_M_GPIODATA4
#define SCR_BUGB_DIR OGPIOCR_M_GPIODIR7
#define SCR_BUGB OGPIOCR_M_GPIODATA7
/* define pins on sequoia that talk to leds */
#define LED_BILED_YELLOW_BIT FOMPCR_M_PCON5
#define LED_BILED_GREEN_BIT FOMPCR_M_PCON6
#define LED_DEBUG_YELLOW_BIT FOMPCR_M_PCON7
#define LED_DEBUG_GREEN_BIT FOMPCR_M_PCON8
/* define biled colors */
#define LED_BILED_NONE 0
#define LED_BILED_GREEN 1
#define LED_BILED_YELLOW 2
#define LED_BILED_RED 3
#define LED_TIMEOUT HZ / 20 /* 20 times a second */
#define LED_NET_ACTIVE (1000000/HZ) * LED_TIMEOUT /* delay in us for net activity */
/*
**
** DATA
**
*/
static bus_space_handle_t sequoia_ioh;
static struct timeval ledLastActive; /* last time we get net activity */
static int ledColor; /* present color of led */
static int ledBlockCount;; /* reference count of block calles */
int sequoia_index_cache = -1; /* set to silly value so that we dont cache on init */
static struct callout led_timo_ch = CALLOUT_INITIALIZER;
/*
**
** FUNCITONAL PROTOTYPES
**
*/
static void ledSetBiled(int color);
static void ledTimeout(void * arg);
/*
**
** FUNCITONS
**
*/
void sequoiaInit(void)
{
u_int16_t seqReg;
/* map the sequoi registers */
if (bus_space_map(&isa_io_bs_tag, SEQUOIA_BASE, SEQUOIA_NPORTS, 0, &sequoia_ioh))
{
panic("SequoiaInit: io mapping failed");
}
/*
**
** setup the pins associated with the X server
**
*/
/* seems power on sets them correctly */
/*
** setup the pins associated with the led
*/
sequoiaRead(SEQR_SEQPSR1_REG,&seqReg);
SET(seqReg,SEQPSR1_M_TAGDEN); /* enable pc[4:9] */
sequoiaWrite(SEQR_SEQPSR1_REG,seqReg);
sequoiaRead(SEQR_SEQPSR3_REG,&seqReg);
CLR(seqReg,SEQPSR3_M_PC5PINEN); /* enable pc5, biled */
CLR(seqReg,SEQPSR3_M_PC6PINEN); /* enable pc6, biled */
CLR(seqReg,SEQPSR3_M_PC7PINEN); /* enable pc7, debug led yellow */
CLR(seqReg,SEQPSR3_M_PC8PINEN); /* enable pc8, debug led green */
sequoiaWrite(SEQR_SEQPSR3_REG,seqReg);
sequoiaRead (PMC_FOMPCR_REG, &seqReg);
CLR(seqReg,LED_BILED_YELLOW_BIT);
CLR(seqReg,LED_BILED_GREEN_BIT);
SET(seqReg,LED_DEBUG_YELLOW_BIT);
CLR(seqReg,LED_DEBUG_GREEN_BIT);
sequoiaWrite(PMC_FOMPCR_REG, seqReg);
/* setup the biled info */
ledColor = LED_BILED_GREEN;
ledLastActive.tv_usec = 0;
ledLastActive.tv_sec = 0;
ledBlockCount = 0;
callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL);
/*
**
** setup the pins associated with the smart card reader *
**
*/
/* sequoia 1 direction & data */
sequoiaRead(SEQUOIA_1GPIO,&seqReg);
SET(seqReg,SCR_POWER_DIR); /* output */
SET(seqReg,SCR_RESET_DIR); /* output */
CLR(seqReg,SCR_DATA_IN_DIR); /* input */
CLR(seqReg,SCR_POWER); /* 0V to card */
SET(seqReg,SCR_RESET); /* 0V to card */
sequoiaWrite(SEQUOIA_1GPIO,seqReg);
/* sequoia 2 pin enables */
sequoiaRead(SEQ2_SEQ2PSR_REG,&seqReg);
SET(seqReg,SEQ2PSR_M_DPBUSEN);
CLR(seqReg,SEQ2PSR_M_GPIOPINEN);
sequoiaWrite(SEQ2_SEQ2PSR_REG,seqReg);
/* sequoia 2 direction & data */
sequoiaRead(SEQUOIA_2GPIO,&seqReg);
SET(seqReg,SCR_BUGA_DIR); /* output */
SET(seqReg,SCR_DATA_OUT_DIR); /* output */
SET(seqReg,SCR_CLOCK_DIR); /* output */
SET(seqReg,SCR_BUGB_DIR); /* output */
CLR(seqReg,SCR_BUGA); /* 0 */
CLR(seqReg,SCR_BUGB); /* 0 */
CLR(seqReg,SCR_CLOCK); /* 0 */
sequoiaWrite(SEQUOIA_2GPIO,seqReg);
/* setup the wak0 pin to be detect */
sequoiaRead(SEQR_SEQPSR2_REG,&seqReg);
SET(seqReg,SEQPSR2_M_DIRTYPINEN);
SET(seqReg,SEQPSR2_M_GPIOB0PINEN);
sequoiaWrite(SEQR_SEQPSR2_REG,seqReg);
sequoiaRead(PMC_GPIOCR2_REG,&seqReg);
CLR(seqReg,SCR_DETECT_DIR); /* input */
sequoiaWrite(PMC_GPIOCR2_REG,seqReg);
/* don't delay when setting PC bits. this is particularly important
for using PC[4] to clear the FIQ. */
sequoiaRead(PMC_SCCR_REG, &seqReg);
sequoiaWrite(PMC_SCCR_REG, seqReg | SCCR_M_PCSTGDIS);
}
/* X console functions */
void consXTvOn(void)
{
u_int16_t savedPSR3;
u_int16_t savedFMPCR;
/*
** Switch on TV output on the Sequoia, data indicates mode,
** but we are currently hardwired to NTSC, so ignore it.
*/
sequoiaRead (SEQR_SEQPSR3_REG, &savedPSR3);
sequoiaWrite(SEQR_SEQPSR3_REG, (savedPSR3 | SEQPSR3_M_PC3PINEN));
sequoiaRead (PMC_FOMPCR_REG, &savedFMPCR);
sequoiaWrite(PMC_FOMPCR_REG, (savedFMPCR | FOMPCR_M_PCON3));
}
void consXTvOff(void)
{
u_int16_t savedPSR3;
u_int16_t savedFMPCR;
/*
** Switch off TV output on the Seqoia
*/
sequoiaRead (SEQR_SEQPSR3_REG, &savedPSR3);
sequoiaWrite(SEQR_SEQPSR3_REG, (savedPSR3 & ~SEQPSR3_M_PC3PINEN));
sequoiaRead (PMC_FOMPCR_REG, &savedFMPCR);
sequoiaWrite(PMC_FOMPCR_REG, (savedFMPCR & ~FOMPCR_M_PCON3));
}
/* smart card routines */
int scrGetDetect (void)
{
int r;
u_int16_t seqReg;
sequoiaRead(PMC_GPIOCR2_REG,&seqReg);
/* inverse logic, so invert */
if (ISSET(seqReg,SCR_DETECT))
{
r = 0;
} else
{
r = 1;
}
return r;
}
void scrSetPower (int value)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead(SEQUOIA_1GPIO,&seqReg);
if (value)
{
SET(seqReg,SCR_POWER);
} else
{
CLR(seqReg,SCR_POWER);
}
sequoiaWrite(SEQUOIA_1GPIO,seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
void scrSetClock (int value)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead(SEQUOIA_2GPIO,&seqReg);
if (value)
{
SET(seqReg,SCR_CLOCK);
} else
{
CLR(seqReg,SCR_CLOCK);
}
sequoiaWrite(SEQUOIA_2GPIO,seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
void scrSetReset (int value)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead(SEQUOIA_1GPIO,&seqReg);
if (value)
{
SET(seqReg,SCR_RESET);
} else
{
CLR(seqReg,SCR_RESET);
}
sequoiaWrite(SEQUOIA_1GPIO,seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
void scrSetDataHighZ (void)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead(SEQUOIA_2GPIO,&seqReg);
/* set data to 5V, io pin is inverse logic */
CLR(seqReg,SCR_DATA_OUT);
sequoiaWrite(SEQUOIA_2GPIO,seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
void scrSetData (int value)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead(SEQUOIA_2GPIO,&seqReg);
/* inverse logic */
if (value )
{
CLR(seqReg,SCR_DATA_OUT);
} else
{
SET(seqReg,SCR_DATA_OUT);
}
sequoiaWrite(SEQUOIA_2GPIO,seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
int scrGetData (void)
{
int r;
u_int16_t seqReg;
sequoiaRead(SEQUOIA_1GPIO,&seqReg);
if (ISSET(seqReg,SCR_DATA_IN))
{
r = 1;
} else
{
r = 0;
}
return r;
}
void ledNetActive (void)
{
ledLastActive = time;
}
void ledNetBlock (void)
{
ledBlockCount++;
}
void ledNetUnblock (void)
{
ledBlockCount--;
}
void ledPanic (void)
{
/* we are in panic, timeout wont happen, so set led */
ledSetBiled(LED_BILED_RED);
}
static void ledTimeout(void * arg)
{
int timeSpan; /* in usec */
if(time.tv_sec == ledLastActive.tv_sec)
{
timeSpan = time.tv_usec - ledLastActive.tv_usec;
}
else if (time.tv_sec - 10 < ledLastActive.tv_sec) /* stop rollover problems */
{
timeSpan = (1000000 + time.tv_usec) - ledLastActive.tv_usec;
}
else
{
timeSpan = LED_NET_ACTIVE * 2; /* ie big number */
}
/* check if we are blocked */
if(ledBlockCount)
{
if(ledColor == LED_BILED_YELLOW)
{
ledSetBiled(LED_BILED_NONE);
}
else
{
ledSetBiled(LED_BILED_YELLOW);
}
}
/* check if we have network activity */
else if (timeSpan < LED_NET_ACTIVE)
{
if(ledColor == LED_BILED_GREEN)
{
ledSetBiled(LED_BILED_NONE);
}
else
{
ledSetBiled(LED_BILED_GREEN);
}
}
/* normal operating mode */
else
{
if(ledColor != LED_BILED_GREEN)
{
ledSetBiled(LED_BILED_GREEN);
}
}
/* resubmint the timeout */
callout_reset(&led_timo_ch, LED_TIMEOUT, ledTimeout, NULL);
}
static void ledSetBiled(int color)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
ledColor = color;
sequoiaRead (PMC_FOMPCR_REG, &seqReg);
switch(color)
{
case LED_BILED_NONE:
SET(seqReg,LED_BILED_YELLOW_BIT);
SET(seqReg,LED_BILED_GREEN_BIT);
break;
case LED_BILED_YELLOW:
CLR(seqReg,LED_BILED_YELLOW_BIT);
SET(seqReg,LED_BILED_GREEN_BIT);
break;
case LED_BILED_GREEN:
SET(seqReg,LED_BILED_YELLOW_BIT);
CLR(seqReg,LED_BILED_GREEN_BIT);
break;
case LED_BILED_RED:
CLR(seqReg,LED_BILED_YELLOW_BIT);
CLR(seqReg,LED_BILED_GREEN_BIT);
break;
default:
panic("invalid color %x\n",color);
break;
}
sequoiaWrite(PMC_FOMPCR_REG, seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
int hwGetRev(void)
{
u_int16_t seqReg;
sequoiaRead(SR_POR_REG,&seqReg);
seqReg = seqReg >> POR_V_MISCCF0;
seqReg = seqReg & 0x7;
return seqReg;
}
/* routines to read/write to sequoia registers */
void sequoiaWrite(int reg,u_int16_t seqReg)
{
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
/*
On SHARK, the fiq comes from the pmi/smi. After receiving
a FIQ, the SMI must be cleared. The SMI gets cleared by
changing to sleep mode, thereby lowering PC[4]. */
// need to do the right thing with the cache if this is going to work */
if (reg == PMC_FOMPCR_REG) {
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg);
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,
seqReg | (FOMPCR_M_PCON4));
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,
PMC_SLPMPCR_REG);
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,
seqReg & ~(SLPMPCR_M_PCSLP4));
sequoia_index_cache = PMC_SLPMPCR_REG;
} else {
/* normal case: just do the write */
if(sequoia_index_cache != reg)
{
sequoia_index_cache = reg;
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg);
}
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET,seqReg);
}
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
void sequoiaRead (int reg,u_int16_t * seqReg_ptr)
{
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
if(sequoia_index_cache != reg)
{
sequoia_index_cache = reg;
bus_space_write_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_INDEX_OFFSET,reg);
}
*seqReg_ptr = bus_space_read_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
void ledSetDebug(int command)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead (PMC_FOMPCR_REG, &seqReg);
switch (command)
{
case LED_DEBUG_STATE_0:
CLR(seqReg,LED_DEBUG_YELLOW_BIT);
CLR(seqReg,LED_DEBUG_GREEN_BIT);
break;
case LED_DEBUG_STATE_1:
SET(seqReg,LED_DEBUG_YELLOW_BIT);
CLR(seqReg,LED_DEBUG_GREEN_BIT);
break;
case LED_DEBUG_STATE_2:
CLR(seqReg,LED_DEBUG_YELLOW_BIT);
SET(seqReg,LED_DEBUG_GREEN_BIT);
break;
case LED_DEBUG_STATE_3:
SET(seqReg,LED_DEBUG_YELLOW_BIT);
SET(seqReg,LED_DEBUG_GREEN_BIT);
break;
case LED_DEBUG_YELLOW_ON:
SET(seqReg,LED_DEBUG_YELLOW_BIT);
break;
case LED_DEBUG_YELLOW_OFF:
CLR(seqReg,LED_DEBUG_YELLOW_BIT);
break;
case LED_DEBUG_GREEN_ON:
SET(seqReg,LED_DEBUG_GREEN_BIT);
break;
case LED_DEBUG_GREEN_OFF:
CLR(seqReg,LED_DEBUG_GREEN_BIT);
break;
default:
panic("ledSetDebug: invalid command %d\n",command);
break;
}
sequoiaWrite(PMC_FOMPCR_REG, seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
#ifdef USEFULL_DEBUG
void sequoiaOneAccess(void)
{
u_int16_t reg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
reg = bus_space_read_2(&isa_io_bs_tag,sequoia_ioh,SEQUOIA_DATA_OFFSET);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}
#endif
int testPin=0;
void scrToggleTestPin (void)
{
u_int16_t seqReg;
#ifdef SHARK
u_int savedints;
savedints = disable_interrupts(I32_bit | F32_bit);
#endif
sequoiaRead(SEQUOIA_2GPIO,&seqReg);
if (testPin)
{
testPin = 0;
CLR(seqReg,SCR_BUGA);
}
else
{
SET(seqReg,SCR_BUGA);
testPin = 1;
}
sequoiaWrite(SEQUOIA_2GPIO,seqReg);
#ifdef SHARK
restore_interrupts(savedints);
#endif
}

File diff suppressed because it is too large Load Diff