summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/wgrisc/conf/GENERIC8
-rw-r--r--sys/arch/wgrisc/conf/files.wgrisc8
-rw-r--r--sys/arch/wgrisc/dev/flash.c593
-rw-r--r--sys/arch/wgrisc/riscbus/riscbus.c4
-rw-r--r--sys/arch/wgrisc/wgrisc/clock_dp.c65
-rw-r--r--sys/arch/wgrisc/wgrisc/conf.c16
-rw-r--r--sys/arch/wgrisc/wgrisc/machdep.c46
7 files changed, 664 insertions, 76 deletions
diff --git a/sys/arch/wgrisc/conf/GENERIC b/sys/arch/wgrisc/conf/GENERIC
index d6cf1213e2e..39fc21c1bb2 100644
--- a/sys/arch/wgrisc/conf/GENERIC
+++ b/sys/arch/wgrisc/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.3 1997/02/23 21:59:24 pefo Exp $
+# $OpenBSD: GENERIC,v 1.4 1997/08/24 12:01:12 pefo Exp $
#
# Generic configuration file for Willowglen RISC-PC 9100
#
@@ -53,7 +53,7 @@ options INET # Internet protocols
#options ISO,TPIP # OSI networking
#options EON # OSI tunneling over IP
#options CCITT,LLC,HDLC # X.25
-options IPFILTER # IP packet filter for security
+#options IPFILTER # IP packet filter for security
#options TCP_COMPAT_42 # compatibility with 4.2BSD TCP/IP
#options MULTICAST # Multicast support
@@ -85,7 +85,7 @@ com3 at riscbus?
asc0 at riscbus?
scsibus* at asc?
-flash0 at riscbus?
+fl0 at riscbus?
#
# ISA Bus.
@@ -97,7 +97,7 @@ com4 at isa? port 0x3e8 irq 4
com5 at isa? port 0x2e8 irq 3
ep0 at isa? port ? irq ? # 3C509 ethernet cards
-#ed0 at isa? port 0x280 iomem 0xd0000 irq 9 # WD/SMC, 3C503, and NE[12]000
+ed0 at isa? port 0x280 iomem 0xd0000 irq 9 # WD/SMC, 3C503, and NE[12]000
#ed1 at isa? port 0x250 iomem 0xd8000 irq 9 # ethernet cards
#ed2 at isa? port 0x300 iomem 0xcc000 irq 10 #
diff --git a/sys/arch/wgrisc/conf/files.wgrisc b/sys/arch/wgrisc/conf/files.wgrisc
index 290098834db..f7daa6d0887 100644
--- a/sys/arch/wgrisc/conf/files.wgrisc
+++ b/sys/arch/wgrisc/conf/files.wgrisc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.wgrisc,v 1.2 1997/02/23 21:59:26 pefo Exp $
+# $OpenBSD: files.wgrisc,v 1.3 1997/08/24 12:01:12 pefo Exp $
#
# maxpartitions must be first item in files.${ARCH}
#
@@ -72,9 +72,9 @@ attach asc at riscbus
file arch/wgrisc/dev/asc.c asc needs-count
# FLASH Memory device driver
-device flash
-attach flash at riscbus
-file arch/wgrisc/dev/flash.c flash needs-count
+device fl
+attach fl at riscbus
+file arch/wgrisc/dev/flash.c fl needs-count
#
# ISA
diff --git a/sys/arch/wgrisc/dev/flash.c b/sys/arch/wgrisc/dev/flash.c
index 89bbf9c7b44..1eb45bfb884 100644
--- a/sys/arch/wgrisc/dev/flash.c
+++ b/sys/arch/wgrisc/dev/flash.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: flash.c,v 1.1 1997/02/23 21:59:27 pefo Exp $ */
+/* $OpenBSD: flash.c,v 1.2 1997/08/24 12:01:13 pefo Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom
@@ -44,6 +44,7 @@
#include <sys/malloc.h>
#include <sys/fcntl.h>
#include <sys/device.h>
+#include <sys/disklabel.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/pio.h>
@@ -54,61 +55,137 @@
extern int cputype;
-void flashattach __P((struct device *, struct device *, void *));
-int flashmatch __P((struct device *, void *, void *));
+void flattach __P((struct device *, struct device *, void *));
+int flmatch __P((struct device *, void *, void *));
-struct flashtype {
+#define FLUNIT(dev) ((dev & 0xf0) >> 4)
+#define FLPART(dev) (minor(dev) & 0x0f)
+#define MAKEFLDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part)
+
+#define FLLABELDEV(dev) (MAKEFLDEV(major(dev), FLUNIT(dev), RAW_PART))
+
+
+
+/*
+ * Flash cache stuff
+ */
+
+#define MAX_BLKS 64 /* Define size of cache */
+
+#ifdef IS_THERE_A_16BIT_STORE_PROBLEM
+struct flctag {
+ u_int16_t next; /* Pointer to next on list */
+ u_int16_t offset; /* Flash memory block offset */
+ u_int16_t age; /* LSW of time last updated */
+ u_int16_t stat; /* Status */
+};
+
+struct flcache {
+ int magic;
+ u_int16_t free; /* List of free blocks */
+ u_int16_t nfree; /* Number of free blocks left */
+ u_int16_t lbusy; /* Last busy block */
+ u_int16_t stat; /* Cache status */
+ char *cache; /* Pointer to cache data area */
+
+ struct flctag flcblk[MAX_BLKS]; /* Flash cache block tags */
+};
+#else
+struct flctag {
+ u_int32_t next; /* Pointer to next on list */
+ u_int32_t offset; /* Flash memory block offset */
+ u_int32_t age; /* LSW of time last updated */
+ u_int32_t stat; /* Status */
+};
+
+struct flcache {
+ int magic;
+ u_int32_t free; /* List of free blocks */
+ u_int32_t nfree; /* Number of free blocks left */
+ u_int32_t lbusy; /* Last busy block */
+ u_int32_t stat; /* Cache status */
+ char *cache; /* Pointer to cache data area */
+
+ struct flctag flcblk[MAX_BLKS]; /* Flash cache block tags */
+};
+#endif
+
+#define FLC_MAGIC 0xf1cac3e0
+
+#define BLK_SFREE 0x0001 /* Sanity check blk on free */
+#define BLK_SBUSY 0x0002 /* Sanity check blk on busy */
+#define BLK_ONFREE 0x0010 /* Block is on free list */
+#define BLK_ONBUSY 0x0020 /* Block is on busy list */
+
+#define BLK_FIND 0 /* Serach cmd "find" */
+#define BLK_FORCE 1 /* Search cmd "must find" */
+#define BLK_LAST 2 /* Search cmd "put last" if found */
+
+/* Flash memory type descriptor */
+
+struct fltype {
char *fl_name;
int fl_size;
int fl_blksz;
u_char fl_manf;
u_char fl_type;
};
-struct flashtype flashlist[] = {
+struct fltype fllist[] = {
{ "Samsung KM29N16000", 2097152, 4096, 0xec, 0x64 },
{ NULL },
};
-struct flashsoftc {
+struct flsoftc {
struct device sc_dev;
int sc_prot;
size_t sc_size;
int sc_present;
- struct flashtype *sc_ftype;
+ int sc_opncnt;
+ struct flcache *sc_cache;
+ struct fltype *sc_ftype;
+ struct disklabel sc_label;
};
-struct cfattach flash_ca = {
- sizeof(struct flashsoftc), flashmatch, flashattach
+struct cfattach fl_ca = {
+ sizeof(struct flsoftc), flmatch, flattach
};
-struct cfdriver flash_cd = {
- NULL, "flash", DV_DISK, 0 /* Yes! We want is as root device */
+struct cfdriver fl_cd = {
+ NULL, "fl", DV_DISK, 0 /* Yes! We want is as root device */
};
+static void flgetdisklabel __P((dev_t, struct flsoftc *));
+static void flinitcache __P((struct flsoftc *));
+void flstrategy __P((struct buf *));
+
+
int
-flashmatch(parent, cf, args)
+flmatch(parent, cf, args)
struct device *parent;
void *cf;
void *args;
{
struct confargs *ca = args;
- if(!BUS_MATCHNAME(ca, "flash"))
+ if(!BUS_MATCHNAME(ca, "fl"))
return(0);
return(1);
}
void
-flashattach(parent, self, args)
+flattach(parent, self, args)
struct device *parent, *self;
void *args;
{
struct confargs *ca = args;
- struct flashsoftc *sc = (struct flashsoftc *)self;
- struct flashtype *flist;
+ struct flsoftc *sc = (struct flsoftc *)self;
+ struct fltype *flist;
int i, manf, type;
+ u_int32_t next;
+ struct flctag *blkbase;
switch(cputype) {
case WGRISC9100: /* WGRISC9100 can have 4 chips */
+ sc->sc_opncnt = 0;
sc->sc_present = 0;
sc->sc_ftype = NULL;
OUT_FL_CTRL(0, 0); /* All CS lines high */
@@ -117,7 +194,7 @@ flashattach(parent, self, args)
OUT_FL_ALE1(0, (1 << i));
manf = IN_FL_DATA;
type = IN_FL_DATA;
- flist = flashlist;
+ flist = fllist;
while(flist->fl_name != 0) {
if(flist->fl_manf == manf &&
flist->fl_type == type) {
@@ -141,7 +218,7 @@ flashattach(parent, self, args)
break;
default:
- printf("flash: Unknown cputype '%d'", cputype);
+ printf("fl: Unknown cputype '%d'", cputype);
}
if(sc->sc_ftype != NULL) {
printf(" %s, %d*%d bytes%s.", sc->sc_ftype->fl_name,
@@ -153,17 +230,165 @@ flashattach(parent, self, args)
printf("WARNING! Flash type not identified!");
}
printf("\n");
+
+ /*
+ * Now set up the sram cache. We usually have 128k sram
+ * on the board and we use up 25% or 32kb of this for the
+ * flash cache.
+ */
+
+ sc->sc_cache = (struct flcache *)(RISC_SRAM_START+16);
+ blkbase = &sc->sc_cache->flcblk[0];
+
+ if(sc->sc_cache->magic != FLC_MAGIC) {
+ printf("fl0: *WARNING* flash cache not initialized!");
+ printf(" Initializing to %d blocks.\n", MAX_BLKS-1);
+
+ flinitcache(sc);
+ }
+ else { /* Cache initialized. Make sanity check. */
+ for(i = 1; i < MAX_BLKS; i++) {
+ blkbase[i].stat &= ~(BLK_SFREE | BLK_SBUSY);
+ }
+ next = sc->sc_cache->free;
+ i = 0;
+ while(next && (next < MAX_BLKS) && (i < MAX_BLKS)) {
+ blkbase[next].stat |= BLK_SFREE;
+ next = blkbase[next].next;
+ i++;
+ }
+ i = 0;
+ next = blkbase[0].next;
+ while(next && (next < MAX_BLKS) && (i < MAX_BLKS)) {
+ blkbase[next].stat |= BLK_SBUSY;
+ next = blkbase[next].next;
+ i++;
+ }
+ for(i = 1; i < MAX_BLKS; i++) {
+ switch(blkbase[i].stat & (BLK_SBUSY|BLK_SFREE|BLK_ONFREE|BLK_ONBUSY)) {
+ case BLK_SBUSY|BLK_ONBUSY:
+ case BLK_SFREE|BLK_ONFREE:
+ break;
+
+ default:
+ printf("fl0: cache sanity err blk %d stat %x\n",
+ i, blkbase[i].stat);
+ break;
+ }
+ }
+ }
+}
+
+static void
+flinitcache(sc)
+ struct flsoftc *sc;
+{
+ int i;
+ struct flctag *blkbase;
+
+ blkbase = &sc->sc_cache->flcblk[0];
+ for(i = 1; i < MAX_BLKS; i++) {
+ blkbase[i].next = i+1;
+ blkbase[i].stat = BLK_ONFREE;
+ }
+ blkbase[MAX_BLKS-1].next = 0; /* mark end */
+ sc->sc_cache->free = 1; /* first free */
+ sc->sc_cache->nfree = MAX_BLKS-1;
+ blkbase[0].next = 0; /* no busy blocks */
+ sc->sc_cache->lbusy = 0; /* no busy blocks */
+ sc->sc_cache->stat = 0;
+ sc->sc_cache->cache = (char *)sc->sc_cache + sizeof(struct flcache);
+ sc->sc_cache->magic = FLC_MAGIC;
+}
+
+/*
+ * Return index to cached block if in cache.
+ * Also execute command.
+ */
+static int
+flblkincache(sc, offs, command)
+ struct flsoftc *sc;
+ size_t offs;
+ int command;
+{
+ u_int32_t next, prev, offset;
+ struct flctag *blkbase;
+
+ offset = offs >> DEV_BSHIFT;
+ blkbase = &sc->sc_cache->flcblk[0];
+ next = blkbase[0].next;
+ prev = 0;
+
+ while(next && (blkbase[next].offset != offset)) {
+ prev = next;
+ next = blkbase[next].next;
+ }
+ if(next && (command == BLK_LAST)) {
+ if(sc->sc_cache->lbusy != next) {
+ blkbase[prev].next = blkbase[next].next;
+ blkbase[next].next = 0;
+ blkbase[sc->sc_cache->lbusy].next = next;
+ sc->sc_cache->lbusy = next;
+ }
+ return(next); /* already last */
+ }
+ if(next || (command != BLK_FORCE))
+ return(next);
+
+ /* BLK_FORCE */
+ printf("fl0: expected offset %x not found in cache!!\n", offset);
+ next = blkbase[0].next;
+ while(next) {
+ printf("%d/%x ",next, blkbase[next].offset);
+ next = blkbase[next].next;
+ }
+ printf("\n");
+ next = sc->sc_cache->free;
+ while(next) {
+ printf("%d/%x ",next, blkbase[next].offset);
+ next = blkbase[next].next;
+ }
+ printf("\n");
+mdbpanic();
+
+ return(0);
+}
+
+/*
+ * Return block erase status.
+ */
+static int
+flblkerased(sc, blk, offs, cnt)
+ struct flsoftc *sc;
+ size_t offs;
+ size_t cnt;
+{
+ int chip;
+ u_int32_t blkadr;
+ int erased = TRUE;
+
+ chip = 1 << (offs / sc->sc_ftype->fl_size);
+ blkadr = offs % sc->sc_ftype->fl_size;
+
+ OUT_FL_CLE(FL_READ1, chip);
+ OUT_FL_ALE3(blkadr, chip);
+ WAIT_FL_RDY;
+ while(cnt--) {
+ if(IN_FL_DATA != 0xff)
+ erased = FALSE;
+ }
+ return(erased);
}
static int
-flashgetblk(sc, blk, offs, cnt)
- struct flashsoftc *sc;
+flgetblk(sc, blk, offs, cnt)
+ struct flsoftc *sc;
char *blk;
size_t offs;
size_t cnt;
{
int chip;
- int blkadr;
+ u_int32_t blkadr;
chip = 1 << (offs / sc->sc_ftype->fl_size);
blkadr = offs % sc->sc_ftype->fl_size;
@@ -178,14 +403,14 @@ flashgetblk(sc, blk, offs, cnt)
}
static int
-flashputblk(sc, blk, offs, cnt)
- struct flashsoftc *sc;
+flputblk(sc, blk, offs, cnt)
+ struct flsoftc *sc;
char *blk;
size_t offs;
size_t cnt;
{
int chip;
- int blkadr;
+ u_int32_t blkadr;
chip = 1 << (offs / sc->sc_ftype->fl_size);
blkadr = offs % sc->sc_ftype->fl_size;
@@ -206,12 +431,12 @@ flashputblk(sc, blk, offs, cnt)
}
static int
-flasheraseblk(sc, offs)
- struct flashsoftc *sc;
+fleraseblk(sc, offs)
+ struct flsoftc *sc;
size_t offs;
{
int chip;
- int blkadr;
+ u_int32_t blkadr;
chip = 1 << (offs / sc->sc_ftype->fl_size);
blkadr = offs % sc->sc_ftype->fl_size;
@@ -227,54 +452,274 @@ flasheraseblk(sc, offs)
return(0);
}
+/*
+ * Get next free block and put it last on busy list.
+ */
+static int
+flgetfree(sc, offs)
+ struct flsoftc *sc;
+ size_t offs;
+{
+ u_int32_t blkno;
+ struct flctag *blkbase;
+
+ blkbase = &sc->sc_cache->flcblk[0];
+ blkno = sc->sc_cache->free;
+ if(blkno) {
+ sc->sc_cache->free = blkbase[blkno].next;
+ sc->sc_cache->nfree--;
+ blkbase[blkno].next = 0;
+ blkbase[blkno].stat = BLK_ONBUSY;
+ blkbase[blkno].offset = offs >> DEV_BSHIFT;
+ blkbase[blkno].age = 0; /* XXX ticks! */
+ blkbase[sc->sc_cache->lbusy].next = blkno;
+ sc->sc_cache->lbusy = blkno;
+ }
+ return(blkno);
+}
+
+/*
+ * Put block from busy list on free list.
+ */
+static void
+flputfree(sc, blkno)
+ struct flsoftc *sc;
+ u_int32_t blkno;
+{
+ struct flctag *cblk, *rblk;
+
+ if(blkno) {
+ cblk = &sc->sc_cache->flcblk[0];
+ rblk = &sc->sc_cache->flcblk[blkno];
+
+ while(cblk->next && cblk->next != blkno) {
+ cblk = &sc->sc_cache->flcblk[cblk->next];
+ }
+ cblk->next = rblk->next;
+ if(sc->sc_cache->lbusy == blkno) {
+ sc->sc_cache->lbusy = cblk - &sc->sc_cache->flcblk[0];
+ }
+
+ rblk->next = sc->sc_cache->free;
+ rblk->stat = BLK_ONFREE;
+ sc->sc_cache->free = blkno;
+ sc->sc_cache->nfree++;
+ }
+}
+
+/*
+ * Push back a block (4k) to the flash. We first need to get
+ * any used pages not in cache before erasing.
+ */
+
+static int
+flpushblk(sc, offs)
+ struct flsoftc *sc;
+ size_t offs;
+{
+ int i;
+ u_int32_t blkno, offset;
+ int error = 0;
+ char *blk;
+
+printf("fl: pushing block %d to flash.\n", offs);
+ offset = offs;
+ for(i = 0; i < 8; i++) {
+ if(flblkincache(sc, offset, BLK_FIND) == 0) {
+ if((blkno = flgetfree(sc, offset)) != 0) {
+ blk = &sc->sc_cache->cache[blkno*512];
+ flgetblk(sc, blk, offset, 256);
+ flgetblk(sc, blk + 256, offset + 256, 256);
+ }
+ else {
+ error = EIO;
+ }
+ }
+ offset += DEV_BSIZE;
+ }
+ if(error == 0 && fleraseblk(sc, offs))
+ error = EIO;
+
+ if(error == 0) {
+ offset = offs;
+ for(i = 0; i < 8; i++) {
+ blkno = flblkincache(sc, offset, BLK_FORCE);
+ blk = &sc->sc_cache->cache[blkno*512];
+ if(flputblk(sc, blk, offset, 256))
+ error = EIO;
+ if(flputblk(sc, blk + 256, offset + 256, 256))
+ error = EIO;
+ offset += DEV_BSIZE;
+ flputfree(sc, blkno);
+ }
+ }
+ return(error);
+}
+
+
+/*
+ * Read a block (512 bytes) either from cache or from flash.
+ */
+static int
+flreadblk(sc, blk, offs)
+ struct flsoftc *sc;
+ char *blk;
+ size_t offs;
+{
+ int error = 0;
+ u_int32_t blkno;
+
+ if((blkno = flblkincache(sc, offs, BLK_FIND)) != 0) {
+ bcopy(&sc->sc_cache->cache[blkno*512], blk, 512);
+ }
+ else {
+ error |= flgetblk(sc, blk, offs, 256);
+ error |= flgetblk(sc, blk+256, offs+256, 256);
+ }
+ return(error);
+}
+
+/*
+ * Write a block (512 bytes) to cache. If no room in cache
+ * make room by pushing data back into the flash memory.
+ */
+static int
+flwriteblk(sc, blk, offs)
+ struct flsoftc *sc;
+ char *blk;
+ size_t offs;
+{
+ int error = 0;
+ u_int32_t blkno, offset;
+
+ /* In cache? */
+ if((blkno = flblkincache(sc, offs, BLK_LAST)) != 0) {
+ bcopy(blk, &sc->sc_cache->cache[blkno*512], 512);
+ }
+ /* Add to cache */
+ else {
+ if(sc->sc_cache->nfree < 8) {
+ /* Push busy blocks to get a free one */
+ /* XXX We just pick first busy not in same 4k
+ * XXX as the one we need space for, now */
+ blkno = sc->sc_cache->flcblk[0].next;
+ do {
+ offset = sc->sc_cache->flcblk[blkno].offset;
+ offset <<= DEV_BSHIFT;
+ offset &= ~4095;
+ blkno = sc->sc_cache->flcblk[blkno].next;
+ } while(offset == (offs & ~4095));
+
+ error = flpushblk(sc, offset);
+ }
+ blkno = flgetfree(sc, offs);
+ if(blkno) {
+ bcopy(blk, &sc->sc_cache->cache[blkno*512], 512);
+ }
+ else {
+ error = EIO;
+ }
+ }
+ return(error);
+}
+
+
/*ARGSUSED*/
int
-flashopen(dev, flag, mode, p)
+flopen(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
{
- if (minor(dev) >= flash_cd.cd_ndevs || flash_cd.cd_devs[minor(dev)] == NULL)
+ struct flsoftc *sc;
+
+ if (FLUNIT(dev) >= fl_cd.cd_ndevs || fl_cd.cd_devs[FLUNIT(dev)] == NULL)
return (ENODEV);
+ sc = (struct flsoftc *) fl_cd.cd_devs[FLUNIT(dev)];
+ flgetdisklabel(dev, sc);
+ sc->sc_opncnt++;
return(0);
}
/*ARGSUSED*/
int
-flashclose(dev, flag, mode, p)
+flclose(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
{
+ struct flsoftc *sc;
+ u_int32_t offset, blkno;
+
+ sc = (struct flsoftc *) fl_cd.cd_devs[FLUNIT(dev)];
+ sc->sc_opncnt--;
+ if(sc->sc_opncnt == 0) {
+ while((blkno = sc->sc_cache->flcblk[0].next) != 0) {
+ offset = sc->sc_cache->flcblk[blkno].offset;
+ offset <<= DEV_BSHIFT;
+ offset &= ~4095;
+ flpushblk(sc, offset);
+ }
+ }
return(0);
}
/*ARGSUSED*/
int
-flashioctl(dev, cmd, data, flag, p)
+flioctl(dev, cmd, data, flag, p)
dev_t dev;
u_char *data;
int cmd, flag;
struct proc *p;
{
- int unit = minor(dev);
- struct flashsoftc *sc = (struct flashsoftc *) flash_cd.cd_devs[unit];
+ int unit = FLUNIT(dev);
+ struct flsoftc *sc = (struct flsoftc *) fl_cd.cd_devs[unit];
+ struct cpu_disklabel clp;
+ struct disklabel lp, *lpp;
int error = 0;
switch (cmd) {
+
+ /*
+ * Very basic disklabel handling.
+ */
+ case DIOCGDINFO:
+ *(struct disklabel *)data = sc->sc_label;
+ break;
+
+ case DIOCWDINFO:
+ case DIOCSDINFO:
+ if((flag & FWRITE) == 0) {
+ error = EBADF;
+ break;
+ }
+ error = setdisklabel(&sc->sc_label,
+ (struct disklabel *)data, 0, &clp);
+ if((error == 0) && (cmd == DIOCWDINFO)) {
+ error = writedisklabel(FLLABELDEV(dev),
+ flstrategy,
+ &sc->sc_label, &clp);
+ }
+ break;
+
+ case DIOCWLABEL:
+ if((flag & FWRITE) == 0)
+ error = EBADF;
+ break;
+
default:
- error = ENOTTY;
+ error = EINVAL;
break;
}
return(error);
}
void
-flashstrategy(bp)
+flstrategy(bp)
struct buf *bp;
{
- int unit = minor(bp->b_dev);
- struct flashsoftc *sc = (struct flashsoftc *) flash_cd.cd_devs[unit];
+ int unit = FLUNIT(bp->b_dev);
+ struct flsoftc *sc = (struct flsoftc *) fl_cd.cd_devs[unit];
int error = 0;
size_t offs, xfer, cnt;
caddr_t buf;
@@ -290,8 +735,8 @@ flashstrategy(bp)
if(bp->b_flags & B_READ) {
bp->b_resid -= xfer;
while(xfer > 0) {
- cnt = (xfer > 256) ? 256 : xfer;
- flashgetblk(sc, buf, offs, cnt);
+ cnt = (xfer > DEV_BSIZE) ? DEV_BSIZE : xfer;
+ flreadblk(sc, buf, offs, cnt);
xfer -= cnt;
offs += cnt;
buf += cnt;
@@ -299,13 +744,8 @@ flashstrategy(bp)
}
else {
while(xfer > 0) {
- if((offs & (sc->sc_ftype->fl_blksz - 1)) == 0 &&
- (xfer >= sc->sc_ftype->fl_blksz)) {
- if(flasheraseblk(sc, offs))
- error = EIO;
- }
- cnt = (xfer > 256) ? 256 : xfer;
- if(flashputblk(sc, buf, offs, cnt))
+ cnt = (xfer > DEV_BSIZE) ? DEV_BSIZE : xfer;
+ if(flwriteblk(sc, buf, offs, cnt))
error = EIO;
xfer -= cnt;
buf += cnt;
@@ -327,26 +767,26 @@ flashstrategy(bp)
/*ARGSUSED*/
int
-flashread(dev, uio, ioflag)
+flread(dev, uio, ioflag)
dev_t dev;
struct uio *uio;
int ioflag;
{
- return (physio(flashstrategy, NULL, dev, B_READ, minphys, uio));
+ return (physio(flstrategy, NULL, dev, B_READ, minphys, uio));
}
/*ARGSUSED*/
int
-flashwrite(dev, uio, ioflag)
+flwrite(dev, uio, ioflag)
dev_t dev;
struct uio *uio;
int ioflag;
{
- return (physio(flashstrategy, NULL, dev, B_WRITE, minphys, uio));
+ return (physio(flstrategy, NULL, dev, B_WRITE, minphys, uio));
}
int
-flashdump(dev, blkno, va, size)
+fldump(dev, blkno, va, size)
dev_t dev;
daddr_t blkno;
caddr_t va;
@@ -356,8 +796,57 @@ flashdump(dev, blkno, va, size)
}
int
-flashsize(dev)
+flsize(dev)
dev_t dev;
{
return(0);
}
+
+/*
+ * Create a disklabel from the flash ram info.
+ */
+static void
+flgetdisklabel(dev, sc)
+ dev_t dev;
+ struct flsoftc *sc;
+{
+ struct disklabel *lp = &sc->sc_label;
+ struct cpu_disklabel clp;
+ char *errstring;
+
+ bzero(lp, sizeof(struct disklabel));
+ bzero(&clp, sizeof(struct cpu_disklabel));
+
+ lp->d_secsize = 1 << DEV_BSHIFT;
+ lp->d_ntracks = 1;
+ lp->d_nsectors = sc->sc_size >> DEV_BSHIFT;
+ lp->d_ncylinders = 1;
+ lp->d_secpercyl = lp->d_nsectors;
+
+ strncpy(lp->d_typename, "FLASH disk", 16);
+ lp->d_type = DTYPE_SCSI; /* XXX This is a fake! */
+ strncpy(lp->d_packname, "fictitious", 16);
+ lp->d_secperunit = lp->d_nsectors;
+ lp->d_rpm = 3600;
+ lp->d_interleave = 1;
+ lp->d_flags = 0;
+
+ lp->d_partitions[RAW_PART].p_offset = 0;
+ lp->d_partitions[RAW_PART].p_size =
+ lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
+ lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+ lp->d_npartitions = RAW_PART + 1;
+
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = dkcksum(lp);
+
+ /*
+ * Call the generic disklabel extraction routine
+ */
+ errstring = readdisklabel(FLLABELDEV(dev), flstrategy, lp, &clp);
+ if (errstring) {
+ printf("%s: %s\n", sc->sc_dev.dv_xname, errstring);
+ }
+}
+
diff --git a/sys/arch/wgrisc/riscbus/riscbus.c b/sys/arch/wgrisc/riscbus/riscbus.c
index a6684b2a0fb..942b5b77571 100644
--- a/sys/arch/wgrisc/riscbus/riscbus.c
+++ b/sys/arch/wgrisc/riscbus/riscbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: riscbus.c,v 1.2 1997/02/23 21:59:31 pefo Exp $ */
+/* $OpenBSD: riscbus.c,v 1.3 1997/08/24 12:01:14 pefo Exp $ */
/*
* Copyright (c) 1996 Per Fogelstrom
@@ -113,7 +113,7 @@ struct riscbus_dev wgrisc9100_cpu[] = {
INT_MASK_5, riscbus_intrnull, (void *)RISC_COM2, },
{{ "com", 6, 0, },
INT_MASK_5, riscbus_intrnull, (void *)RISC_COM3, },
- {{ "flash", 7, 0, },
+ {{ "fl", 7, 0, },
0, NULL, (void *)NULL, },
{{ NULL, -1, NULL, },
0, NULL, (void *)NULL, },
diff --git a/sys/arch/wgrisc/wgrisc/clock_dp.c b/sys/arch/wgrisc/wgrisc/clock_dp.c
index 78cbb096e4a..1f439476313 100644
--- a/sys/arch/wgrisc/wgrisc/clock_dp.c
+++ b/sys/arch/wgrisc/wgrisc/clock_dp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock_dp.c,v 1.1 1997/02/06 16:02:47 pefo Exp $ */
+/* $OpenBSD: clock_dp.c,v 1.2 1997/08/24 12:01:14 pefo Exp $ */
/* $NetBSD: clock_mc.c,v 1.2 1995/06/28 04:30:30 cgd Exp $ */
/*
@@ -225,3 +225,66 @@ dp_read_riscbus(csc, reg)
i = inb(((struct dpclockdata *)csc->sc_data)->dp_addr + reg);
return(i);
}
+
+#define WWDELAY 50
+#define WDELAY() \
+{\
+ register int i; \
+ wbflush(); \
+ for (i = WWDELAY; i != 0; i--) continue; \
+}
+
+/*----------------------------------------------------------------------
+ * Read non-volatile ram part of clock chip.
+ * -----------------------------------------
+ *
+ * First byte is located in page 0, and read first
+ * then page 1 is switched in and the rest is read.
+ ----------------------------------------------------------------------*/
+unsigned char *ReadNVram(unsigned char *ptr)
+{
+ volatile unsigned char *clockram = (volatile unsigned char *)RISC_RTC;
+ unsigned char main_stat_save;
+ int count;
+
+ main_stat_save = inb(clockram + MAIN_STATUS);
+ WDELAY();
+ outb(clockram + MAIN_STATUS, 0);
+ WDELAY();
+ *ptr++ = inb(clockram + RAM_1E);
+ WDELAY();
+ outb(clockram + MAIN_STATUS, 0x80);
+ WDELAY();
+ for(count=1; count < 32; count++) {
+ WDELAY();
+ *ptr++ = inb(clockram + count);
+ }
+ WDELAY();
+ outb(clockram + MAIN_STATUS, main_stat_save & 0xc0);
+ return(0);
+}
+
+/*----------------------------------------------------------------------*
+ * Write non-volatile ram part of clock chip.
+ * ------------------------------------------
+ *
+ * First byte is located in page 0, and written first
+ * then page 1 is switched in and the rest is written.
+ *----------------------------------------------------------------------*/
+unsigned char *WriteNVram(unsigned char *ptr)
+{
+ volatile unsigned char *clockram = (volatile unsigned char *)RISC_RTC;
+ unsigned char main_stat_save;
+ int count;
+
+ main_stat_save = inb(clockram+MAIN_STATUS);
+ WDELAY();
+ outb(clockram + MAIN_STATUS, 0);
+ outb(clockram + RAM_1E, *ptr++);
+ outb(clockram + MAIN_STATUS, 0x80);
+ for(count=1; count < 32; count++) {
+ outb(clockram + count, *ptr++);
+ }
+ outb(clockram + MAIN_STATUS, main_stat_save & 0xc0);
+ return 0;
+}
diff --git a/sys/arch/wgrisc/wgrisc/conf.c b/sys/arch/wgrisc/wgrisc/conf.c
index 521defa04cc..096d2197674 100644
--- a/sys/arch/wgrisc/wgrisc/conf.c
+++ b/sys/arch/wgrisc/wgrisc/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.2 1997/02/23 21:59:33 pefo Exp $ */
+/* $OpenBSD: conf.c,v 1.3 1997/08/24 12:01:15 pefo Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)conf.c 8.2 (Berkeley) 11/14/93
- * $Id: conf.c,v 1.2 1997/02/23 21:59:33 pefo Exp $
+ * $Id: conf.c,v 1.3 1997/08/24 12:01:15 pefo Exp $
*/
#include <sys/param.h>
@@ -69,8 +69,8 @@ bdev_decl(fd);
bdev_decl(wd);
#include "acd.h"
bdev_decl(acd);
-#include "flash.h"
-bdev_decl(flash);
+#include "fl.h"
+bdev_decl(fl);
struct bdevsw bdevsw[] =
{
@@ -84,7 +84,7 @@ struct bdevsw bdevsw[] =
bdev_notdef(), /* 7: Floppy disk driver */
bdev_notdef(), /* 8: */
bdev_notdef(), /* 9: */
- bdev_disk_init(NFLASH,flash), /* 10: Flash ram disk driver */
+ bdev_disk_init(NFL,fl), /* 10: Flash ram disk driver */
bdev_notdef(), /* 11: */
bdev_notdef(), /* 12: */
bdev_notdef(), /* 13: */
@@ -129,7 +129,7 @@ cdev_decl(cd);
cdev_decl(uk);
cdev_decl(wd);
cdev_decl(acd);
-cdev_decl(flash);
+cdev_decl(fl);
/* open, close, read, ioctl */
@@ -164,7 +164,7 @@ struct cdevsw cdevsw[] =
cdev_disk_init(NACD,acd), /* 19: ATAPI CD-ROM */
cdev_tty_init(NPTY,pts), /* 20: pseudo-tty slave */
cdev_ptc_init(NPTY,ptc), /* 21: pseudo-tty master */
- cdev_disk_init(NFLASH,flash), /* 22: Flash memory driver */
+ cdev_disk_init(NFL,fl), /* 22: Flash memory driver */
cdev_notdef(), /* 23: */
cdev_notdef(), /* 24: */
cdev_notdef(), /* 25: */
@@ -250,7 +250,7 @@ static int chrtoblktbl[MAXDEV] = {
/* 19 */ 5,
/* 20 */ NODEV,
/* 21 */ NODEV,
- /* 22 */ NODEV,
+ /* 22 */ 10,
/* 23 */ NODEV,
/* 24 */ NODEV,
/* 25 */ NODEV,
diff --git a/sys/arch/wgrisc/wgrisc/machdep.c b/sys/arch/wgrisc/wgrisc/machdep.c
index e8521ba6373..5d90de97c66 100644
--- a/sys/arch/wgrisc/wgrisc/machdep.c
+++ b/sys/arch/wgrisc/wgrisc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.3 1997/05/11 16:26:08 pefo Exp $ */
+/* $OpenBSD: machdep.c,v 1.4 1997/08/24 12:01:15 pefo Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1992, 1993
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 8.3 (Berkeley) 1/12/94
- * $Id: machdep.c,v 1.3 1997/05/11 16:26:08 pefo Exp $
+ * $Id: machdep.c,v 1.4 1997/08/24 12:01:15 pefo Exp $
*/
/* from: Utah Hdr: machdep.c 1.63 91/04/24 */
@@ -164,11 +164,20 @@ mips_init(argc, argv, code)
caddr_t start;
struct tlb tlb;
extern char _ftext[], edata[], end[];
+ int realmemsize;
+ char nvdata[32];
/* clear the BSS segment in OpenBSD code */
sysend = (caddr_t)mips_round_page(end);
bzero(edata, sysend - edata);
+ /* Extract this from BBRAM environment variable */
+ ReadNVram(&nvdata);
+ realmemsize = nvdata[2];
+ if (realmemsize > 36 || realmemsize < 8) {
+ realmemsize = 36;
+ }
+
/* Initialize the CPU type */
cputype = WGRISC9100;
mem_layout[0].mem_start = 0;
@@ -177,9 +186,36 @@ mips_init(argc, argv, code)
mem_layout[1].mem_size = 0x400000 - (int)(CACHED_TO_PHYS(sysend));
physmem = 4096 * 1024;
- mem_layout[2].mem_start = 0x400000;
- mem_layout[2].mem_size = 0x800000;
- physmem += 8192 * 1024;
+ switch (realmemsize) {
+ default:
+ case 8: /* 8 MB (0 MB simm) */
+ mem_layout[2].mem_start = 0x400000;
+ mem_layout[2].mem_size = 0x400000;
+ physmem += 4096 * 1024;
+ break;
+ case 12: /* 12 MB (4 MB simm) */
+ mem_layout[2].mem_start = 0x400000;
+ mem_layout[2].mem_size = 0x800000;
+ physmem += 8192 * 1024;
+ break;
+ case 20: /* 20 MB (16MB SIMM + 0 in onboard Bank2) */
+ mem_layout[2].mem_start =0x1000000;
+ mem_layout[2].mem_size = 0x1000000;
+ physmem += 16 * 1024 * 1024;
+ break;
+ case 24: /* 24 MB (16MB SIMM + 4 in onboard Bank2) */
+ mem_layout[2].mem_start = 0x400000;
+ mem_layout[2].mem_size = 0x400000;
+ mem_layout[3].mem_start =0x1000000;
+ mem_layout[3].mem_size = 0x1000000;
+ physmem += 20 * 1024 * 1024;
+ break;
+ case 36: /* 36 MB (32MB SIMM and ignore bank2 onboard) */
+ mem_layout[2].mem_start = 0x400000;
+ mem_layout[2].mem_size = 0x2000000;
+ physmem += 32768 * 1024;
+ break;
+ }
switch (cputype) {
case WGRISC9100: