Now getting these from arch/sun3/sun3

This commit is contained in:
gwr 1997-01-18 21:57:49 +00:00
parent 8749290f0a
commit 5cf8aa219a
6 changed files with 0 additions and 2272 deletions

View File

@ -1,377 +0,0 @@
/* $NetBSD: conf.c,v 1.1.1.1 1997/01/14 20:57:08 gwr Exp $ */
/*-
* Copyright (c) 1994 Adam Glass, Gordon W. Ross
* Copyright (c) 1991, 1993
* The Regents of the University of California. 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
*
* @(#)conf.c 8.2 (Berkeley) 11/14/93
*/
#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 "cd.h"
bdev_decl(cd);
cdev_decl(cd);
#include "ccd.h"
bdev_decl(ccd);
cdev_decl(ccd);
#include "rd.h"
bdev_decl(rd);
/* no cdev for rd */
#include "sd.h"
bdev_decl(sd);
cdev_decl(sd);
#include "st.h"
bdev_decl(st);
cdev_decl(st);
/* swap device (required) */
bdev_decl(sw);
cdev_decl(sw);
#include "vnd.h"
bdev_decl(vnd);
cdev_decl(vnd);
#include "xd.h"
bdev_decl(xd);
cdev_decl(xd);
#define NXT 0 /* XXX */
bdev_decl(xt);
cdev_decl(xt);
#include "xy.h"
bdev_decl(xy);
cdev_decl(xy);
struct bdevsw bdevsw[] =
{
bdev_notdef(), /* 0 */
bdev_notdef(), /* 1: tapemaster tape */
bdev_notdef(), /* 2 */
bdev_disk_init(NXY,xy), /* 3: SMD disk on Xylogics 450/451 */
bdev_swap_init(1,sw), /* 4: swap pseudo-device */
bdev_disk_init(NVND,vnd), /* 5: vnode disk driver */
bdev_notdef(), /* 6 */
bdev_disk_init(NSD,sd), /* 7: SCSI disk */
bdev_tape_init(NXT,xt), /* 8: Xylogics tape */
bdev_disk_init(NCCD,ccd), /* 9: concatenated disk driver */
bdev_disk_init(NXD,xd), /* 10: SMD disk on Xylogics 7053 */
bdev_tape_init(NST,st), /* 11: SCSI tape */
bdev_notdef(), /* 12: Sun ns? */
bdev_disk_init(NRD,rd), /* 13: RAM disk - for install tape */
bdev_notdef(), /* 14: Sun ft? */
bdev_notdef(), /* 15: Sun hd? */
bdev_notdef(), /* 16: Sun fd? */
bdev_notdef(), /* 17: Sun vd_unused */
bdev_disk_init(NCD,cd), /* 18: SCSI CD-ROM */
bdev_notdef(), /* 19: Sun vd_unused */
bdev_notdef(), /* 20: Sun vd_unused */
bdev_notdef(), /* 21: Sun vd_unused */
bdev_notdef(), /* 22: Sun IPI disks... */
bdev_notdef(), /* 23: Sun IPI disks... */
};
int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
/*
* Devices that have only CHR nodes are declared below.
*/
cdev_decl(cn);
cdev_decl(ctty);
#define mmread mmrw
#define mmwrite mmrw
cdev_decl(mm);
#include "zstty.h"
cdev_decl(zs);
#include "kbd.h"
cdev_decl(kbd);
cdev_decl(kd);
#include "ms.h"
cdev_decl(ms);
#include "pty.h"
#define ptstty ptytty
#define ptsioctl ptyioctl
cdev_decl(pts);
#define ptctty ptytty
#define ptcioctl ptyioctl
cdev_decl(ptc);
/* frame-buffer devices */
#define fbpoll seltrue
cdev_decl(fb);
#include "bwtwo.h"
#define bw2poll seltrue
cdev_decl(bw2);
#include "cgtwo.h"
#define cg2poll seltrue
cdev_decl(cg2);
#include "cgfour.h"
#define cg4poll seltrue
cdev_decl(cg4);
cdev_decl(log);
cdev_decl(fd);
#include "bpfilter.h"
cdev_decl(bpf);
#include "tun.h"
cdev_decl(tun);
dev_decl(filedesc,open);
struct cdevsw cdevsw[] =
{
cdev_cn_init(1,cn), /* 0: virtual console */
cdev_tty_init(NKBD,kd), /* 1: Sun keyboard/display */
cdev_ctty_init(1,ctty), /* 2: controlling terminal */
cdev_mm_init(1,mm), /* 3: /dev/{null,mem,kmem,...} */
cdev_notdef(), /* 4: was PROM console */
cdev_notdef(), /* 5: tapemaster tape */
cdev_notdef(), /* 6: systech/versatec */
cdev_swap_init(1,sw), /* 7: /dev/drum {swap pseudo-device) */
cdev_notdef(), /* 8: Archive QIC-11 tape */
cdev_disk_init(NXY,xy), /* 9: SMD disk on Xylogics 450/451 */
cdev_notdef(), /* 10: systech multi-terminal board */
cdev_notdef(), /* 11: DES encryption chip */
cdev_tty_init(NZSTTY,zs), /* 12: Zilog 8350 serial port */
cdev_mouse_init(NMS,ms), /* 13: Sun mouse */
cdev_notdef(), /* 14: cgone */
cdev_notdef(), /* 15: /dev/winXXX */
cdev_log_init(1,log), /* 16: /dev/klog */
cdev_disk_init(NSD,sd), /* 17: SCSI disk */
cdev_tape_init(NST,st), /* 18: SCSI tape */
cdev_disk_init(NVND,vnd), /* 19: vnode disk driver */
cdev_tty_init(NPTY,pts), /* 20: pseudo-tty slave */
cdev_ptc_init(NPTY,ptc), /* 21: pseudo-tty master */
cdev_fb_init(1,fb), /* 22: /dev/fb indirect driver */
cdev_fd_init(1,filedesc), /* 23: file descriptor pseudo-device */
cdev_bpftun_init(NTUN,tun), /* 24: network tunnel */
cdev_notdef(), /* 25: sun pi? */
cdev_notdef(), /* 26: bwone */
cdev_fb_init(NBWTWO,bw2), /* 27: bwtwo */
cdev_notdef(), /* 28: Systech VPC-2200 versatec/centronics */
cdev_mouse_init(NKBD,kbd), /* 29: Sun keyboard */
cdev_tape_init(NXT,xt), /* 30: Xylogics tape */
cdev_fb_init(NCGTWO,cg2), /* 31: cgtwo */
cdev_notdef(), /* 32: /dev/gpone */
cdev_disk_init(NCCD,ccd), /* 33: concatenated disk driver */
cdev_notdef(), /* 34: floating point accelerator */
cdev_notdef(), /* 35 */
cdev_bpftun_init(NBPFILTER,bpf),/* 36: Berkeley packet filter */
cdev_notdef(), /* 37 */
cdev_notdef(), /* 38 */
cdev_fb_init(NCGFOUR,cg4), /* 39: cgfour */
cdev_notdef(), /* 40: (sni) */
cdev_notdef(), /* 41: (sun dump) */
cdev_disk_init(NXD,xd), /* 42: SMD disk on Xylogics 7053 */
cdev_notdef(), /* 43: (sun hrc) */
cdev_notdef(), /* 44: (mcp) */
cdev_notdef(), /* 45: (sun ifd) */
cdev_notdef(), /* 46: (dcp) */
cdev_notdef(), /* 47: (dna) */
cdev_notdef(), /* 48: (tbi) */
cdev_notdef(), /* 49: (chat) */
cdev_notdef(), /* 50: (chut) */
cdev_notdef(), /* 51: (chut) */
cdev_notdef(), /* 52: RAM disk - for install tape */
cdev_notdef(), /* 53: (hd - N/A) */
cdev_notdef(), /* 54: (fd - N/A) */
cdev_notdef(), /* 55: cgthree */
cdev_notdef(), /* 56: (pp) */
cdev_notdef(), /* 57: (vd) Loadable Module control */
cdev_disk_init(NCD,cd), /* 58: SCSI CD-ROM */
cdev_notdef(), /* 59: (vd) Loadable Module stub */
cdev_notdef(), /* 60: || || || || */
cdev_notdef(), /* 61: || || || || */
cdev_notdef(), /* 62: (taac) */
cdev_notdef(), /* 63: (tcp/tli) */
cdev_notdef(), /* 64: cgeight */
cdev_notdef(), /* 65: old IPI */
cdev_notdef(), /* 66: (mcp) parallel printer */
cdev_notdef(), /* 67: cgsix */
cdev_notdef(), /* 68: cgnine */
cdev_notdef(), /* 69: /dev/audio */
cdev_notdef(), /* 70: open prom */
cdev_notdef(), /* 71: (sg?) */
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
int mem_no = 3; /* 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(4, 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) == 12);
}
static int chrtoblktbl[] = {
/* XXXX This needs to be dynamic for LKMs. */
/*VCHR*/ /*VBLK*/
/* 0 */ NODEV,
/* 1 */ NODEV,
/* 2 */ NODEV,
/* 3 */ NODEV,
/* 4 */ NODEV,
/* 5 */ 1,
/* 6 */ NODEV,
/* 7 */ NODEV,
/* 8 */ NODEV,
/* 9 */ 3,
/* 10 */ NODEV,
/* 11 */ NODEV,
/* 12 */ NODEV,
/* 13 */ NODEV,
/* 14 */ NODEV,
/* 15 */ NODEV,
/* 16 */ NODEV,
/* 17 */ 7,
/* 18 */ 11,
/* 19 */ 5,
/* 20 */ NODEV,
/* 21 */ NODEV,
/* 22 */ NODEV,
/* 23 */ NODEV,
/* 24 */ NODEV,
/* 25 */ NODEV,
/* 26 */ NODEV,
/* 27 */ NODEV,
/* 28 */ NODEV,
/* 29 */ NODEV,
/* 30 */ 8,
/* 31 */ NODEV,
/* 32 */ NODEV,
/* 33 */ 9,
/* 34 */ NODEV,
/* 35 */ NODEV,
/* 36 */ NODEV,
/* 37 */ NODEV,
/* 38 */ NODEV,
/* 39 */ NODEV,
/* 40 */ NODEV,
/* 41 */ NODEV,
/* 42 */ NODEV,
/* 43 */ 10,
/* 44 */ NODEV,
/* 45 */ NODEV,
/* 46 */ NODEV,
/* 47 */ NODEV,
/* 48 */ NODEV,
/* 49 */ NODEV,
/* 50 */ NODEV,
/* 51 */ NODEV,
/* 52 */ 13,
/* 53 */ NODEV,
/* 54 */ NODEV,
/* 55 */ NODEV,
/* 56 */ NODEV,
/* 57 */ NODEV,
/* 58 */ 18,
/* 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 */ NODEV,
};
/*
* Convert a character device number to a block device number.
*/
int
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

@ -1,475 +0,0 @@
/* $NetBSD: disksubr.c,v 1.1.1.1 1997/01/14 20:57:08 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
* Copyright (c) 1994 Theo de Raadt
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
* 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
*
* Credits:
* This file was based mostly on the i386/disksubr.c file:
* @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* The functions: disklabel_sun_to_bsd, disklabel_bsd_to_sun
* were originally taken from arch/sparc/scsi/sun_disklabel.c
* (which was written by Theo de Raadt) and then substantially
* rewritten by Gordon W. Ross.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/device.h>
#include <sys/disklabel.h>
#include <sys/disk.h>
#include <sys/dkbad.h>
#include <machine/sun_disklabel.h>
/* XXX encoding of disk minor numbers, should be elsewhere... */
#define dkpart(dev) (minor(dev) & 7)
#define b_cylin b_resid
#if LABELSECTOR != 0
#error "Default value of LABELSECTOR no longer zero?"
#endif
static char * disklabel_sun_to_bsd(char *, struct disklabel *);
static int disklabel_bsd_to_sun(struct disklabel *, char *);
/*
* Attempt to read a disk label from a device
* using the indicated stategy routine.
* The label must be partly set up before this:
* secpercyl, secsize and anything required for a block i/o read
* operation in the driver's strategy/start routines
* must be filled in before calling us.
*
* Return buffer for use in signalling errors if requested.
*
* Returns null on success and an error string on failure.
*/
char *
readdisklabel(dev, strat, lp, clp)
dev_t dev;
void (*strat) __P((struct buf *));
struct disklabel *lp;
struct cpu_disklabel *clp;
{
struct buf *bp;
struct disklabel *dlp;
struct sun_disklabel *slp;
int error;
/* minimal requirements for archtypal disk label */
if (lp->d_secperunit == 0)
lp->d_secperunit = 0x1fffffff;
lp->d_npartitions = 1;
if (lp->d_partitions[0].p_size == 0)
lp->d_partitions[0].p_size = 0x1fffffff;
lp->d_partitions[0].p_offset = 0;
/* obtain buffer to probe drive with */
bp = geteblk((int)lp->d_secsize);
/* next, dig out disk label */
bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
bp->b_cylin = 0;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
/* if successful, locate disk label within block and validate */
error = biowait(bp);
if (!error) {
/* Save the whole block in case it has info we need. */
bcopy(bp->b_un.b_addr, clp->cd_block, sizeof(clp->cd_block));
}
bp->b_flags = B_INVAL | B_AGE | B_READ;
brelse(bp);
if (error)
return("disk label read error");
/* Check for a Sun disk label (for PROM compatibility). */
slp = (struct sun_disklabel *) clp->cd_block;
if (slp->sl_magic == SUN_DKMAGIC) {
return(disklabel_sun_to_bsd(clp->cd_block, lp));
}
/* Check for a NetBSD disk label (PROM can not boot it). */
dlp = (struct disklabel *) (clp->cd_block + LABELOFFSET);
if (dlp->d_magic == DISKMAGIC) {
if (dkcksum(dlp))
return("NetBSD disk label corrupted");
*lp = *dlp; /* struct assignment */
return(NULL);
}
bzero(clp->cd_block, sizeof(clp->cd_block));
return("no disk label");
}
/*
* Check new disk label for sensibility
* before setting it.
*/
int
setdisklabel(olp, nlp, openmask, clp)
struct disklabel *olp, *nlp;
u_long openmask;
struct cpu_disklabel *clp;
{
struct partition *opp, *npp;
int i;
/* sanity clause */
if ((nlp->d_secpercyl == 0) || (nlp->d_secsize == 0) ||
(nlp->d_secsize % DEV_BSIZE) != 0)
return(EINVAL);
/* special case to allow disklabel to be invalidated */
if (nlp->d_magic == 0xffffffff) {
*olp = *nlp;
return (0);
}
if (nlp->d_magic != DISKMAGIC ||
nlp->d_magic2 != DISKMAGIC ||
dkcksum(nlp) != 0)
return (EINVAL);
while (openmask != 0) {
i = ffs(openmask) - 1;
openmask &= ~(1 << i);
if (nlp->d_npartitions <= i)
return (EBUSY);
opp = &olp->d_partitions[i];
npp = &nlp->d_partitions[i];
if (npp->p_offset != opp->p_offset ||
npp->p_size < opp->p_size)
return (EBUSY);
}
/* We did not modify the new label, so the checksum is OK. */
*olp = *nlp;
return (0);
}
/*
* Write disk label back to device after modification.
* Current label is already in clp->cd_block[]
*/
int
writedisklabel(dev, strat, lp, clp)
dev_t dev;
void (*strat) __P((struct buf *));
struct disklabel *lp;
struct cpu_disklabel *clp;
{
struct buf *bp;
int error;
error = disklabel_bsd_to_sun(lp, clp->cd_block);
if (error)
return(error);
#if 0 /* XXX - Allow writing NetBSD disk labels? */
{
struct disklabel *dlp;
dlp = (struct disklabel *)(clp->cd_block + LABELOFFSET);
*dlp = *lp; /* struct assignment */
}
#endif
/* Get a buffer and copy the new label into it. */
bp = geteblk((int)lp->d_secsize);
bcopy(clp->cd_block, bp->b_un.b_addr, sizeof(clp->cd_block));
/* Write out the updated label. */
bp->b_dev = dev;
bp->b_blkno = LABELSECTOR;
bp->b_cylin = 0;
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_WRITE;
(*strat)(bp);
error = biowait(bp);
brelse(bp);
return (error);
}
/*
* Determine the size of the transfer, and make sure it is
* within the boundaries of the partition. Adjust transfer
* if needed, and signal errors or early completion.
*/
int
bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
{
struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
int maxsz = p->p_size;
int sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
/* overwriting disk label ? */
/* XXX should also protect bootstrap in first 8K */
/* XXX PR#2598: labelsect is always sector zero. */
if (((bp->b_blkno + p->p_offset) <= LABELSECTOR) &&
((bp->b_flags & B_READ) == 0) && (wlabel == 0))
{
bp->b_error = EROFS;
goto bad;
}
/* beyond partition? */
if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
/* if exactly at end of disk, return an EOF */
if (bp->b_blkno == maxsz) {
bp->b_resid = bp->b_bcount;
return(0);
}
/* or truncate if part of it fits */
sz = maxsz - bp->b_blkno;
if (sz <= 0) {
bp->b_error = EINVAL;
goto bad;
}
bp->b_bcount = sz << DEV_BSHIFT;
}
/* calculate cylinder for disksort to order transfers with */
bp->b_cylin = (bp->b_blkno + p->p_offset) / lp->d_secpercyl;
return(1);
bad:
bp->b_flags |= B_ERROR;
return(-1);
}
/*
* This function appears to be called by each disk driver.
* Aparently this is to give this MD code a chance to do
* additional "device registration" types of work. (?)
* For example, the sparc port uses this to record the
* device node for the PROM-specified boot device.
*/
void
dk_establish(dk, dev)
struct disk *dk;
struct device *dev;
{
}
/************************************************************************
*
* The rest of this was taken from arch/sparc/scsi/sun_disklabel.c
* and then substantially rewritten by Gordon W. Ross
*
************************************************************************/
/* What partition types to assume for Sun disklabels: */
static u_char
sun_fstypes[8] = {
FS_BSDFFS, /* a */
FS_SWAP, /* b */
FS_OTHER, /* c - whole disk */
FS_BSDFFS, /* d */
FS_BSDFFS, /* e */
FS_BSDFFS, /* f */
FS_BSDFFS, /* g */
FS_BSDFFS, /* h */
};
/*
* Given a SunOS disk label, set lp to a BSD disk label.
* Returns NULL on success, else an error string.
*
* The BSD label is cleared out before this is called.
*/
static char *
disklabel_sun_to_bsd(cp, lp)
char *cp;
struct disklabel *lp;
{
struct sun_disklabel *sl;
struct partition *npp;
struct sun_dkpart *spp;
int i, secpercyl;
u_short cksum, *sp1, *sp2;
sl = (struct sun_disklabel *)cp;
/* Verify the XOR check. */
sp1 = (u_short *)sl;
sp2 = (u_short *)(sl + 1);
cksum = 0;
while (sp1 < sp2)
cksum ^= *sp1++;
if (cksum != 0)
return("SunOS disk label, bad checksum");
/* Format conversion. */
lp->d_magic = DISKMAGIC;
lp->d_magic2 = DISKMAGIC;
memcpy(lp->d_packname, sl->sl_text, sizeof(lp->d_packname));
lp->d_secsize = 512;
lp->d_nsectors = sl->sl_nsectors;
lp->d_ntracks = sl->sl_ntracks;
lp->d_ncylinders = sl->sl_ncylinders;
secpercyl = sl->sl_nsectors * sl->sl_ntracks;
lp->d_secpercyl = secpercyl;
lp->d_secperunit = secpercyl * sl->sl_ncylinders;
lp->d_sparespercyl = sl->sl_sparespercyl;
lp->d_acylinders = sl->sl_acylinders;
lp->d_rpm = sl->sl_rpm;
lp->d_interleave = sl->sl_interleave;
lp->d_npartitions = 8;
/* These are as defined in <ufs/ffs/fs.h> */
lp->d_bbsize = 8192; /* XXX */
lp->d_sbsize = 8192; /* XXX */
for (i = 0; i < 8; i++) {
spp = &sl->sl_part[i];
npp = &lp->d_partitions[i];
npp->p_offset = spp->sdkp_cyloffset * secpercyl;
npp->p_size = spp->sdkp_nsectors;
if (npp->p_size == 0)
npp->p_fstype = FS_UNUSED;
else {
/* Partition has non-zero size. Set type, etc. */
npp->p_fstype = sun_fstypes[i];
/*
* The sun label does not store the FFS fields,
* so just set them with default values here.
* XXX: This keeps newfs from trying to rewrite
* XXX: the disk label in the most common case.
* XXX: (Should remove that code from newfs...)
*/
if (npp->p_fstype == FS_BSDFFS) {
npp->p_fsize = 1024;
npp->p_frag = 8;
npp->p_cpg = 16;
}
}
}
lp->d_checksum = 0;
lp->d_checksum = dkcksum(lp);
return(NULL);
}
/*
* Given a BSD disk label, update the Sun disklabel
* pointed to by cp with the new info. Note that the
* Sun disklabel may have other info we need to keep.
* Returns zero or error code.
*/
static int
disklabel_bsd_to_sun(lp, cp)
struct disklabel *lp;
char *cp;
{
struct sun_disklabel *sl;
struct partition *npp;
struct sun_dkpart *spp;
int i, secpercyl;
u_short cksum, *sp1, *sp2;
if (lp->d_secsize != 512)
return (EINVAL);
sl = (struct sun_disklabel *)cp;
/* Format conversion. */
memcpy(sl->sl_text, lp->d_packname, sizeof(lp->d_packname));
sl->sl_rpm = lp->d_rpm;
sl->sl_pcyl = lp->d_ncylinders + lp->d_acylinders; /* XXX */
sl->sl_sparespercyl = lp->d_sparespercyl;
sl->sl_interleave = lp->d_interleave;
sl->sl_ncylinders = lp->d_ncylinders;
sl->sl_acylinders = lp->d_acylinders;
sl->sl_ntracks = lp->d_ntracks;
sl->sl_nsectors = lp->d_nsectors;
secpercyl = sl->sl_nsectors * sl->sl_ntracks;
for (i = 0; i < 8; i++) {
spp = &sl->sl_part[i];
npp = &lp->d_partitions[i];
if (npp->p_offset % secpercyl)
return (EINVAL);
spp->sdkp_cyloffset = npp->p_offset / secpercyl;
spp->sdkp_nsectors = npp->p_size;
}
sl->sl_magic = SUN_DKMAGIC;
/* Correct the XOR check. */
sp1 = (u_short *)sl;
sp2 = (u_short *)(sl + 1);
sl->sl_cksum = cksum = 0;
while (sp1 < sp2)
cksum ^= *sp1++;
sl->sl_cksum = cksum;
return(0);
}
#if 0
/*
* Search the bad sector table looking for the specified sector.
* Return index if found.
* Return -1 if not found.
*/
int
isbad(bt, cyl, trk, sec)
register struct dkbad *bt;
{
register int i;
register long blk, bblk;
blk = ((long)cyl << 16) + (trk << 8) + sec;
for (i = 0; i < 126; i++) {
bblk = ((long)bt->bt_bad[i].bt_cyl << 16) +
bt->bt_bad[i].bt_trksec;
if (blk == bblk)
return (i);
if (blk < bblk || bblk < 0)
break;
}
return (-1);
}
#endif

View File

@ -1,303 +0,0 @@
/* $NetBSD: isr.c,v 1.1.1.1 1997/01/14 20:57:09 gwr Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Adam Glass and Gordon W. Ross.
*
* 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 the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION 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.
*/
/*
* This handles multiple attach of autovectored interrupts,
* and the handy software interrupt request register.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/vmmeter.h>
#include <net/netisr.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/mon.h>
#include <machine/obio.h>
#include "machdep.h"
#include "vector.h"
extern int intrcnt[]; /* statistics */
#define NUM_LEVELS 8
struct isr {
struct isr *isr_next;
isr_func_t isr_intr;
void *isr_arg;
int isr_ipl;
};
void set_vector_entry __P((int, void *));
void * get_vector_entry __P((int));
/*
* These are called from locore. The "struct clockframe" arg
* is really just the normal H/W interrupt frame format.
* (kern_clock really wants it to be named that...)
*/
void isr_autovec __P((struct clockframe));
void isr_vectored __P((struct clockframe));
void
isr_add_custom(level, handler)
int level;
void *handler;
{
set_vector_entry(AUTOVEC_BASE + level, handler);
}
/*
* netisr junk...
* XXX - This really belongs in some common file,
* i.e. src/sys/net/netisr.c
* Also, should use an array of chars instead of
* a bitmask to avoid atomicity locking issues.
*/
#include "ether.h" /* for NETHER */
#include "ppp.h"
/*
* Declarations for the netisr functions...
* They are in the header files, but that's not
* really a good reason to drag all those in.
*/
void arpintr __P((void));
void ipintr __P((void));
void nsintr __P((void));
void clnlintr __P((void));
void ccittintr __P((void));
void pppintr __P((void));
void netintr()
{
int n, s;
s = splhigh();
n = netisr;
netisr = 0;
splx(s);
#if NETHER > 0
if (n & (1 << NETISR_ARP))
arpintr();
#endif
#ifdef INET
if (n & (1 << NETISR_IP))
ipintr();
#endif
#ifdef NS
if (n & (1 << NETISR_NS))
nsintr();
#endif
#ifdef ISO
if (n & (1 << NETISR_ISO))
clnlintr();
#endif
#ifdef CCITT
if (n & (1 << NETISR_CCITT)) {
ccittintr();
}
#endif
#if NPPP > 0
if (n & (1 << NETISR_PPP)) {
pppintr();
}
#endif
}
static struct isr *isr_autovec_list[NUM_LEVELS];
/*
* This is called by the assembly routines
* for handling auto-vectored interupts.
*/
void isr_autovec(cf)
struct clockframe cf;
{
struct isr *isr;
register int n, ipl, vec;
vec = (cf.cf_vo & 0xFFF) >> 2;
if ((vec < AUTOVEC_BASE) || (vec >= (AUTOVEC_BASE+8)))
panic("isr_autovec: bad vec");
ipl = vec - 0x18;
n = intrcnt[ipl];
intrcnt[ipl] = n+1;
cnt.v_intr++;
isr = isr_autovec_list[ipl];
if (isr == NULL) {
if (n == 0)
printf("isr_autovec: ipl %d unexpected\n", ipl);
return;
}
/* Give all the handlers a chance. */
n = 0;
while (isr) {
n |= isr->isr_intr(isr->isr_arg);
isr = isr->isr_next;
}
if (!n)
printf("isr_autovec: ipl %d not claimed\n", ipl);
}
/*
* Establish an interrupt handler.
* Called by driver attach functions.
*/
void isr_add_autovect(handler, arg, level)
isr_func_t handler;
void *arg;
int level;
{
struct isr *new_isr;
if ((level < 0) || (level >= NUM_LEVELS))
panic("isr_add: bad level=%d", level);
new_isr = (struct isr *)
malloc(sizeof(struct isr), M_DEVBUF, M_NOWAIT);
if (!new_isr)
panic("isr_add: malloc failed");
new_isr->isr_intr = handler;
new_isr->isr_arg = arg;
new_isr->isr_ipl = level;
new_isr->isr_next = isr_autovec_list[level];
isr_autovec_list[level] = new_isr;
}
struct vector_handler {
isr_func_t func;
void *arg;
};
static struct vector_handler isr_vector_handlers[192];
/*
* This is called by the assembly glue
* for handling vectored interupts.
*/
void
isr_vectored(cf)
struct clockframe cf;
{
struct vector_handler *vh;
register int ipl, vec;
vec = (cf.cf_vo & 0xFFF) >> 2;
ipl = getsr();
ipl = (ipl >> 8) & 7;
intrcnt[ipl]++;
cnt.v_intr++;
if (vec < 64 || vec >= 256) {
printf("isr_vectored: vector=0x%x (invalid)\n", vec);
return;
}
vh = &isr_vector_handlers[vec - 64];
if (vh->func == NULL) {
printf("isr_vectored: vector=0x%x (nul func)\n", vec);
set_vector_entry(vec, (void *)badtrap);
return;
}
/* OK, call the isr function. */
if (vh->func(vh->arg) == 0)
printf("isr_vectored: vector=0x%x (not claimed)\n", vec);
}
/*
* Establish an interrupt handler.
* Called by driver attach functions.
*/
extern void _isr_vectored __P((void));
void
isr_add_vectored(func, arg, level, vec)
isr_func_t func;
void *arg;
int level, vec;
{
struct vector_handler *vh;
if (vec < 64 || vec >= 256) {
printf("isr_add_vectored: vect=0x%x (invalid)\n", vec);
return;
}
vh = &isr_vector_handlers[vec - 64];
if (vh->func) {
printf("isr_add_vectored: vect=0x%x (in use)\n", vec);
return;
}
vh->func = func;
vh->arg = arg;
set_vector_entry(vec, (void *)_isr_vectored);
}
/*
* XXX - could just kill these...
*/
void
set_vector_entry(entry, handler)
int entry;
void *handler;
{
if ((entry <0) || (entry >= NVECTORS))
panic("set_vector_entry: setting vector too high or low\n");
vector_table[entry] = handler;
}
void *
get_vector_entry(entry)
int entry;
{
if ((entry <0) || (entry >= NVECTORS))
panic("get_vector_entry: setting vector too high or low\n");
return ((void *) vector_table[entry]);
}

View File

@ -1,70 +0,0 @@
/* $NetBSD: kgdb_proto.h,v 1.1.1.1 1997/01/14 20:57:09 gwr Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratories.
*
* 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
*
* @(#)kgdb_proto.h 8.1 (Berkeley) 6/10/93
*/
/*
* Message types.
*/
#define KGDB_MEM_R 0x01
#define KGDB_MEM_W 0x02
#define KGDB_REG_R 0x03
#define KGDB_REG_W 0x04
#define KGDB_CONT 0x05
#define KGDB_STEP 0x06
#define KGDB_KILL 0x07
#define KGDB_SIGNAL 0x08
#define KGDB_EXEC 0x09
#define KGDB_HALT 0x0a
#define KGDB_BOOT 0x0b
#define KGDB_CMD(x) ((x) & 0x0f)
/*
* Message flags.
*/
#define KGDB_ACK 0x80
#define KGDB_DELTA 0x40
#define KGDB_MORE 0x20
#define KGDB_SEQ 0x10

View File

@ -1,621 +0,0 @@
/* $NetBSD: kgdb_stub.c,v 1.1.1.1 1997/01/14 20:57:09 gwr Exp $ */
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratories.
*
* 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
*
* @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
*/
/*
* "Stub" to allow remote cpu to debug over a serial line using gdb.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <machine/control.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/psl.h>
#include <machine/pte.h>
#include <machine/reg.h>
#include <machine/trap.h>
#include <sun3/sun3/kgdb_proto.h>
#include <machine/db_machdep.h>
#include <machine/remote-sl.h>
#ifndef KGDBDEV
#define KGDBDEV -1
#endif
#ifndef KGDBRATE
#define KGDBRATE 19200
#endif
int kgdb_dev = KGDBDEV; /* remote debugging device (-1 if none) */
int kgdb_rate = KGDBRATE; /* remote debugging baud rate */
int kgdb_active = 0; /* remote debugging active if != 0 */
int kgdb_debug_init = 0; /* != 0 waits for remote at system init */
int kgdb_debug_panic = 0; /* != 0 waits for remote on panic */
static void kgdb_send __P((u_int, u_char *, int));
static int kgdb_recv __P((u_char *, int *));
static int computeSignal __P((int));
int kgdb_trap __P((int, struct trapframe *));
int kgdb_acc __P((caddr_t, int));
static int (*kgdb_getc) __P((void *));
static void (*kgdb_putc) __P((void *, int));
static void *kgdb_ioarg;
#define GETC() ((*kgdb_getc)(kgdb_ioarg))
#define PUTC(c) ((*kgdb_putc)(kgdb_ioarg, c))
#define PUTESC(c) do { \
if (c == FRAME_END) { \
PUTC(FRAME_ESCAPE); \
c = TRANS_FRAME_END; \
} else if (c == FRAME_ESCAPE) { \
PUTC(FRAME_ESCAPE); \
c = TRANS_FRAME_ESCAPE; \
} else if (c == FRAME_START) { \
PUTC(FRAME_ESCAPE); \
c = TRANS_FRAME_START; \
} \
PUTC(c); \
} while (0)
/*
* This is called by the approprite tty driver.
* In our case, by dev/zs_kgdb.c:zs_kgdb_init()
*/
void
kgdb_attach(getfn, putfn, ioarg)
int (*getfn) __P((void *));
void (*putfn) __P((void *, int));
void *ioarg;
{
kgdb_getc = getfn;
kgdb_putc = putfn;
kgdb_ioarg = ioarg;
}
/*
* Send a message. The host gets one chance to read it.
*/
static void
kgdb_send(type, bp, len)
register u_int type;
register u_char *bp;
register int len;
{
register u_char csum;
register u_char *ep = bp + len;
PUTC(FRAME_START);
PUTESC(type);
csum = type;
while (bp < ep) {
type = *bp++;
csum += type;
PUTESC(type);
}
csum = -csum;
PUTESC(csum);
PUTC(FRAME_END);
}
static int
kgdb_recv(bp, lenp)
u_char *bp;
int *lenp;
{
register u_char c, csum;
register int escape, len;
register int type;
restart:
csum = len = escape = 0;
type = -1;
while (1) {
c = GETC();
switch (c) {
case FRAME_ESCAPE:
escape = 1;
continue;
case TRANS_FRAME_ESCAPE:
if (escape)
c = FRAME_ESCAPE;
break;
case TRANS_FRAME_END:
if (escape)
c = FRAME_END;
break;
case TRANS_FRAME_START:
if (escape)
c = FRAME_START;
break;
case FRAME_START:
goto restart;
case FRAME_END:
if (type < 0 || --len < 0) {
csum = len = escape = 0;
type = -1;
continue;
}
if (csum != 0)
return (0);
*lenp = len;
return (type);
}
csum += c;
if (type < 0) {
type = c;
escape = 0;
continue;
}
if (++len > SL_RPCSIZE) {
while (GETC() != FRAME_END)
continue;
return (0);
}
*bp++ = c;
escape = 0;
}
}
/*
* Translate a trap number into a unix compatible signal value.
* (gdb only understands unix signal numbers).
*/
static int
computeSignal(type)
int type;
{
int sigval;
switch (type) {
case T_BUSERR:
sigval = SIGBUS;
break;
case T_ADDRERR:
sigval = SIGBUS;
break;
case T_ILLINST:
sigval = SIGILL;
break;
case T_ZERODIV:
sigval = SIGFPE;
break;
case T_CHKINST:
sigval = SIGFPE;
break;
case T_TRAPVINST:
sigval = SIGFPE;
break;
case T_PRIVINST:
sigval = SIGILL;
break;
case T_TRACE:
sigval = SIGTRAP;
break;
case T_MMUFLT:
sigval = SIGSEGV;
break;
case T_SSIR:
sigval = SIGSEGV;
break;
case T_FMTERR:
sigval = SIGILL;
break;
case T_FPERR:
sigval = SIGFPE;
break;
case T_COPERR:
sigval = SIGFPE;
break;
case T_ASTFLT:
sigval = SIGINT;
break;
case T_TRAP15:
sigval = SIGTRAP;
break;
default:
sigval = SIGEMT;
break;
}
return (sigval);
}
/*
* Trap into kgdb to wait for debugger to connect,
* noting on the console why nothing else is going on.
*/
void
kgdb_connect(verbose)
int verbose;
{
if (kgdb_dev < 0 || kgdb_getc == NULL)
return;
fb_unblank();
if (verbose)
printf("kgdb waiting...");
Debugger(); /* XXX: trap into kgdb */
if (verbose)
printf("connected.\n");
}
/*
* Decide what to do on panic.
* (This is called by panic, like Debugger())
*/
void
kgdb_panic()
{
if (kgdb_dev >= 0 && kgdb_getc != NULL &&
kgdb_active == 0 && kgdb_debug_panic)
{
/* XXX: Just call Debugger() instead? */
kgdb_connect(1);
}
}
/*
* Definitions exported from gdb.
*/
#define NUM_REGS 18
#define REGISTER_BYTES (NUM_REGS * 4)
#define REGISTER_BYTE(n) ((n) * 4)
#define GDB_SR 16
#define GDB_PC 17
/*
* This little routine exists simply so that bcopy() can be debugged.
*/
static void
kgdb_copy(vsrc, vdst, len)
void *vsrc, *vdst;
register int len;
{
register char *src = vsrc;
register char *dst = vdst;
while (--len >= 0)
*dst++ = *src++;
}
/* ditto for bzero */
static void
kgdb_zero(vptr, len)
void *vptr;
register int len;
{
register char *ptr = vptr;
while (--len >= 0)
*ptr++ = (char) 0;
}
/*
* Translate the values stored in the kernel regs struct to the format
* understood by gdb.
*
* There is a short pad word between SP (A7) and SR which keeps the
* kernel stack long word aligned (note that this is in addition to
* the stack adjust short that we treat as the upper half of a longword
* SR). We must skip this when copying into and out of gdb.
*/
static void
regs_to_gdb(tf, gdb_regs)
struct trapframe *tf;
u_long *gdb_regs;
{
kgdb_copy(tf->tf_regs, gdb_regs, 16*4);
gdb_regs[GDB_SR] = tf->tf_sr;
gdb_regs[GDB_PC] = tf->tf_pc;
}
/*
* Reverse the above.
*/
static void
gdb_to_regs(tf, gdb_regs)
struct trapframe *tf;
u_long *gdb_regs;
{
kgdb_copy(gdb_regs, tf->tf_regs, 16*4);
tf->tf_sr = gdb_regs[GDB_SR];
tf->tf_pc = gdb_regs[GDB_PC];
}
static u_long reg_cache[NUM_REGS];
static u_char inbuffer[SL_RPCSIZE];
static u_char outbuffer[SL_RPCSIZE];
/*
* This function does all command procesing for interfacing to
* a remote gdb.
*/
int
kgdb_trap(type, tf)
int type;
struct trapframe *tf;
{
register u_long len;
caddr_t addr;
register u_char *cp;
register u_char out, in;
register int outlen;
int inlen;
u_long gdb_regs[NUM_REGS];
if (kgdb_dev < 0 || kgdb_getc == NULL) {
/* not debugging */
return (0);
}
if (kgdb_active == 0) {
if (type != T_BREAKPOINT) {
/* No debugger active -- let trap handle this. */
return (0);
}
/*
* If the packet that woke us up isn't an exec packet,
* ignore it since there is no active debugger. Also,
* we check that it's not an ack to be sure that the
* remote side doesn't send back a response after the
* local gdb has exited. Otherwise, the local host
* could trap into gdb if it's running a gdb kernel too.
*/
in = GETC();
/*
* If we came in asynchronously through the serial line,
* the framing character is eaten by the receive interrupt,
* but if we come in through a synchronous trap (i.e., via
* kgdb_connect()), we will see the extra character.
*/
if (in == FRAME_START)
in = GETC();
/*
* Check that this is a debugger exec message. If so,
* slurp up the entire message then ack it, and fall
* through to the recv loop.
*/
if (KGDB_CMD(in) != KGDB_EXEC || (in & KGDB_ACK) != 0)
return (0);
while (GETC() != FRAME_END)
continue;
/*
* Do the printf *before* we ack the message. This way
* we won't drop any inbound characters while we're
* doing the polling printf.
*/
printf("kgdb started from device %x\n", kgdb_dev);
kgdb_send(in | KGDB_ACK, (u_char *)0, 0);
kgdb_active = 1;
}
/*
* Stick frame regs into our reg cache then tell remote host
* that an exception has occured.
*/
regs_to_gdb(tf, gdb_regs);
if (type != T_BREAKPOINT) {
/*
* XXX - Which is right? The code or the comment? -gwr
* Only send an asynchronous SIGNAL message when we hit
* a breakpoint. Otherwise, we will drop the incoming
* packet while we output this one (and on entry the other
* side isn't interested in the SIGNAL type -- if it is,
* it will have used a signal packet.)
*/
outbuffer[0] = computeSignal(type);
kgdb_send(KGDB_SIGNAL, outbuffer, 1);
}
for (;;) {
in = kgdb_recv(inbuffer, &inlen);
if (in == 0 || (in & KGDB_ACK))
/* Ignore inbound acks and error conditions. */
continue;
out = in | KGDB_ACK;
switch (KGDB_CMD(in)) {
case KGDB_SIGNAL:
/*
* if this command came from a running gdb,
* answer it -- the other guy has no way of
* knowing if we're in or out of this loop
* when he issues a "remote-signal". (Note
* that without the length check, we could
* loop here forever if the output line is
* looped back or the remote host is echoing.)
*/
if (inlen == 0) {
outbuffer[0] = computeSignal(type);
kgdb_send(KGDB_SIGNAL, outbuffer, 1);
}
continue;
case KGDB_REG_R:
case KGDB_REG_R | KGDB_DELTA:
cp = outbuffer;
outlen = 0;
for (len = inbuffer[0]; len < NUM_REGS; ++len) {
if (reg_cache[len] != gdb_regs[len] ||
(in & KGDB_DELTA) == 0) {
if (outlen + 5 > SL_MAXDATA) {
out |= KGDB_MORE;
break;
}
cp[outlen] = len;
kgdb_copy(&gdb_regs[len],
&cp[outlen + 1], 4);
reg_cache[len] = gdb_regs[len];
outlen += 5;
}
}
break;
case KGDB_REG_W:
case KGDB_REG_W | KGDB_DELTA:
cp = inbuffer;
for (len = 0; len < inlen; len += 5) {
register int j = cp[len];
kgdb_copy(&cp[len + 1],
&gdb_regs[j], 4);
reg_cache[j] = gdb_regs[j];
}
gdb_to_regs(tf, gdb_regs);
outlen = 0;
break;
case KGDB_MEM_R:
len = inbuffer[0];
kgdb_copy(&inbuffer[1], &addr, 4);
if (len > SL_MAXDATA) {
outlen = 1;
outbuffer[0] = E2BIG;
} else if (!kgdb_acc(addr, len)) {
outlen = 1;
outbuffer[0] = EFAULT;
} else {
outlen = len + 1;
outbuffer[0] = 0;
db_read_bytes((vm_offset_t)addr, (size_t)len,
(char *)&outbuffer[1]);
}
break;
case KGDB_MEM_W:
len = inlen - 4;
kgdb_copy(inbuffer, &addr, 4);
outlen = 1;
if (!kgdb_acc(addr, len))
outbuffer[0] = EFAULT;
else {
outbuffer[0] = 0;
db_write_bytes((vm_offset_t)addr, (size_t)len,
(char *)&inbuffer[4]);
}
break;
case KGDB_KILL:
kgdb_active = 0;
printf("kgdb detached\n");
/* FALLTHROUGH */
case KGDB_CONT:
kgdb_send(out, 0, 0);
tf->tf_sr &=~ PSL_T;
goto out;
case KGDB_STEP:
kgdb_send(out, 0, 0);
tf->tf_sr |= PSL_T;
goto out;
case KGDB_HALT:
kgdb_send(out, 0, 0);
sun3_mon_halt();
/* NOTREACHED */
case KGDB_BOOT:
kgdb_send(out, 0, 0);
sun3_mon_reboot("");
/* NOTREACHED */
case KGDB_EXEC:
default:
/* Unknown command. Ack with a null message. */
outlen = 0;
break;
}
/* Send the reply */
kgdb_send(out, outbuffer, outlen);
}
out:
return (1);
}
/*
* XXX: Determine if the memory at addr..(addr+len) is valid.
* XXX: Should we just use the PTE bits? Why not?
* XXX: Better yet, setup a fault handler?
*/
kgdb_acc(addr, len)
caddr_t addr;
int len;
{
vm_offset_t va;
int pgoff;
mmu_short_pte_t pte;
va = (vm_offset_t) addr;
pgoff = va & PGOFSET;
va -= pgoff;
len += pgoff;
do {
pte = get_pte(va);
if (MMU_VALID_DT(pte) == 0)
return (0);
va += NBPG;
len -= NBPG;
} while (len > 0);
return (1);
}

View File

@ -1,426 +0,0 @@
/* $NetBSD: vm_machdep.c,v 1.1.1.1 1997/01/14 20:57:09 gwr Exp $ */
/*
* Copyright (c) 1994, 1995 Gordon W. Ross
* Copyright (c) 1993 Adam Glass
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1982, 1986, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department.
*
* 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 the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
*
* from: Utah $Hdr: vm_machdep.c 1.21 91/04/06$
* from: @(#)vm_machdep.c 8.6 (Berkeley) 1/12/94
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/vnode.h>
#include <sys/user.h>
#include <sys/core.h>
#include <sys/exec.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
/* #include <vm/vm_map.h> */
#include <machine/cpu.h>
#include <machine/reg.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include "machdep.h"
extern int fpu_type;
extern void proc_do_uret __P((void));
extern void proc_trampoline __P((void));
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the kernel stack and pcb, making the child
* ready to run, and marking it so that it can return differently
* than the parent. Returns 1 in the child process, 0 in the parent.
*/
void
cpu_fork(p1, p2)
register struct proc *p1, *p2;
{
register struct pcb *p1pcb = &p1->p_addr->u_pcb;
register struct pcb *p2pcb = &p2->p_addr->u_pcb;
register struct trapframe *p2tf;
register struct switchframe *p2sf;
/*
* Before copying the PCB from the current process,
* make sure it is up-to-date. (p1 == curproc)
*/
if (p1 == curproc)
savectx(p1pcb);
/* copy over the machdep part of struct proc */
p2->p_md.md_flags = p1->p_md.md_flags;
/* Copy pcb from proc p1 to p2. */
bcopy(p1pcb, p2pcb, sizeof(*p2pcb));
/* Child can start with low IPL (XXX - right?) */
p2pcb->pcb_ps = PSL_LOWIPL;
/*
* Our cpu_switch MUST always call PMAP_ACTIVATE on a
* process switch so there is no need to do it here.
* (Our PMAP_ACTIVATE call allocates an MMU context.)
*/
/*
* Create the child's kernel stack, from scratch.
* Pick a stack pointer, leaving room for a trapframe;
* copy trapframe from parent so return to user mode
* will be to right address, with correct registers.
* Leave one word unused at the end of the kernel stack
* so the system stack pointer stays within the page.
*/
p2tf = (struct trapframe *)((char*)p2pcb + USPACE-4) - 1;
p2->p_md.md_regs = (int *)p2tf;
bcopy(p1->p_md.md_regs, p2tf, sizeof(*p2tf));
/*
* Create a "switch frame" such that when cpu_switch returns,
* this process will be in proc_do_uret() going to user mode.
*/
p2sf = (struct switchframe *)p2tf - 1;
p2sf->sf_pc = (u_int)proc_do_uret;
p2pcb->pcb_regs[11] = (int)p2sf; /* SSP */
/*
* This will "push a call" to an arbitrary kernel function
* onto the stack of p2, very much like signal delivery.
* When p2 runs, it will find itself in child_return().
*/
cpu_set_kpc(p2, child_return);
}
/*
* cpu_set_kpc:
*
* Arrange for in-kernel execution of a process to continue in the
* named function, as if that function were called with one argument,
* the current process's process pointer.
*
* Note that it's assumed that when the named process returns,
* rei() should be invoked, to return to user mode. That is
* accomplished by having cpu_fork set the initial frame with a
* return address pointing to proc_do_uret() which does the rte.
*
* The design allows this function to be implemented as a general
* "kernel sendsig" utility, that can "push" a call to a kernel
* function onto any other process kernel stack, in a way very
* similar to how signal delivery works on a user stack. When
* the named process is switched to, it will call the function
* we "pushed" and then proc_trampoline will pop the args that
* were pushed here and return to where it would have returned
* before we "pushed" this call.
*/
void
cpu_set_kpc(proc, func)
struct proc *proc;
void (*func)(struct proc *);
{
struct pcb *pcbp;
struct ksigframe {
struct switchframe sf;
void (*func)(struct proc *);
void *proc;
} *ksfp;
pcbp = &proc->p_addr->u_pcb;
/* Push a ksig frame onto the kernel stack. */
ksfp = (struct ksigframe *)pcbp->pcb_regs[11] - 1;
pcbp->pcb_regs[11] = (int)ksfp;
/* Now fill it in for proc_trampoline. */
ksfp->sf.sf_pc = (u_int)proc_trampoline;
ksfp->func = func;
ksfp->proc = proc;
}
/*
* cpu_exit is called as the last action during exit.
* We release the address space and machine-dependent resources,
* including the memory for the user structure and kernel stack.
* Once finished, we call switch_exit, which switches to a temporary
* pcb and stack and never returns. We block memory allocation
* until switch_exit has made things safe again.
*/
void
cpu_exit(p)
struct proc *p;
{
vmspace_free(p->p_vmspace);
(void) splimp();
cnt.v_swtch++;
switch_exit(p);
/* NOTREACHED */
}
/*
* Do any additional state-saving necessary before swapout.
*/
void
cpu_swapout(p)
register struct proc *p;
{
/*
* This will have real work to do when we implement the
* context-switch optimization of not switching FPU state
* until the new process actually uses FPU instructions.
*/
}
/*
* Do any additional state-restoration after swapin.
*/
void
cpu_swapin(p)
register struct proc *p;
{
/*
* XXX - Just for debugging... (later).
*/
}
/*
* Dump the machine specific segment at the start of a core dump.
* This means the CPU and FPU registers. The format used here is
* the same one ptrace uses, so gdb can be machine independent.
*
* XXX - Generate Sun format core dumps for Sun executables?
*/
struct md_core {
struct reg intreg;
struct fpreg freg;
};
int
cpu_coredump(p, vp, cred, chdr)
struct proc *p;
struct vnode *vp;
struct ucred *cred;
struct core *chdr;
{
struct md_core md_core;
struct coreseg cseg;
int error;
/* XXX: Make sure savectx() was done? */
CORE_SETMAGIC(*chdr, COREMAGIC, MID_M68K, 0);
chdr->c_hdrsize = ALIGN(sizeof(*chdr));
chdr->c_seghdrsize = ALIGN(sizeof(cseg));
chdr->c_cpusize = sizeof(md_core);
/* Save integer registers. */
error = process_read_regs(p, &md_core.intreg);
if (error)
return error;
/* Save floating point registers. */
error = process_read_fpregs(p, &md_core.freg);
if (error)
return error;
CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_M68K, CORE_CPU);
cseg.c_addr = 0;
cseg.c_size = chdr->c_cpusize;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
(off_t)chdr->c_hdrsize, UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)0, p);
if (error)
return error;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
(off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)0, p);
if (error)
return error;
chdr->c_nseg++;
return (0);
}
/*
* Move pages from one kernel virtual address to another.
* Both addresses are assumed to reside in the kernel map,
* and size must be a multiple of CLSIZE.
*/
void
pagemove(from, to, size)
register caddr_t from, to;
size_t size;
{
register vm_offset_t pa;
#ifdef DIAGNOSTIC
if (size & CLOFSET || (int)from & CLOFSET || (int)to & CLOFSET)
panic("pagemove 1");
#endif
while (size > 0) {
pa = pmap_extract(pmap_kernel(), (vm_offset_t)from);
#ifdef DIAGNOSTIC
if (pa == 0)
panic("pagemove 2");
#endif
/* this does the cache flush work itself */
pmap_remove(pmap_kernel(),
(vm_offset_t)from, (vm_offset_t)from + NBPG);
pmap_enter(pmap_kernel(),
(vm_offset_t)to, pa, VM_PROT_READ|VM_PROT_WRITE, 1);
from += NBPG;
to += NBPG;
size -= NBPG;
}
}
/*
* Map an IO request into kernel virtual address space.
* Requests fall into one of five catagories:
*
* B_PHYS|B_UAREA: User u-area swap.
* Address is relative to start of u-area (p_addr).
* B_PHYS|B_PAGET: User page table swap.
* Address is a kernel VA in usrpt (Usrptmap).
* B_PHYS|B_DIRTY: Dirty page push.
* Address is a VA in proc2's address space.
* B_PHYS|B_PGIN: Kernel pagein of user pages.
* Address is VA in user's address space.
* B_PHYS: User "raw" IO request.
* Address is VA in user's address space.
*
* All requests are (re)mapped into kernel VA space via the kernel_map
*
* This routine has user context and can sleep
* (called only by physio).
*
* XXX we allocate KVA space by using kmem_alloc_wait which we know
* allocates space without backing physical memory. This implementation
* is a total crock, the multiple mappings of these physical pages should
* be reflected in the higher-level VM structures to avoid problems.
*/
void
vmapbuf(bp, sz)
register struct buf *bp;
vm_size_t sz;
{
register vm_offset_t addr, kva, pa;
register vm_size_t size, off;
register int npf;
struct proc *p;
register struct vm_map *map;
if ((bp->b_flags & B_PHYS) == 0)
panic("vmapbuf");
p = bp->b_proc;
map = &p->p_vmspace->vm_map;
bp->b_saveaddr = bp->b_data;
addr = (vm_offset_t)bp->b_saveaddr;
off = addr & PGOFSET;
addr = trunc_page(addr);
size = round_page(bp->b_bcount + off);
kva = kmem_alloc_wait(kernel_map, size);
bp->b_data = (caddr_t)(kva + off);
npf = btoc(size);
while (npf--) {
pa = pmap_extract(vm_map_pmap(map), (vm_offset_t)addr);
pa = trunc_page(pa); /* page type in low bits? */
if (pa == 0)
panic("vmapbuf: null page frame");
/* XXX: flush write-back on old mappings? */
/* XXX: cache_flush_page((vm_offset_t)addr); */
pmap_enter(pmap_kernel(), kva,
pa | PMAP_NC,
VM_PROT_READ|VM_PROT_WRITE, 1);
addr += NBPG;
kva += NBPG;
}
}
/*
* Free the io mappings associated with this I/O operation.
* The mappings in the I/O map (phys_map) were non-cached,
* so there are no write-back modifications to flush.
* Also note, kmem_free_wakeup will remove the mappings.
*
* This routine has user context and can sleep
* (called only by physio).
*/
void
vunmapbuf(bp, sz)
register struct buf *bp;
vm_size_t sz;
{
register vm_offset_t kva, pgva;
register vm_size_t size, off;
if ((bp->b_flags & B_PHYS) == 0)
panic("vunmapbuf");
kva = (vm_offset_t)bp->b_data;
off = kva & PGOFSET;
pgva = trunc_page(kva);
size = round_page(bp->b_bcount + off);
/* XXX: Actually remove mappings, which does cache flush. */
pmap_remove(pmap_kernel(), pgva, pgva + size);
/*
* Now remove the map entry, which may also call
* pmap_remove but that will do nothing since we
* already removed the actual mappings.
*/
kmem_free_wakeup(kernel_map, pgva, size);
bp->b_data = bp->b_saveaddr;
bp->b_saveaddr = NULL;
}