diff options
-rw-r--r-- | sys/arch/wgrisc/conf/GENERIC | 8 | ||||
-rw-r--r-- | sys/arch/wgrisc/conf/files.wgrisc | 8 | ||||
-rw-r--r-- | sys/arch/wgrisc/dev/flash.c | 593 | ||||
-rw-r--r-- | sys/arch/wgrisc/riscbus/riscbus.c | 4 | ||||
-rw-r--r-- | sys/arch/wgrisc/wgrisc/clock_dp.c | 65 | ||||
-rw-r--r-- | sys/arch/wgrisc/wgrisc/conf.c | 16 | ||||
-rw-r--r-- | sys/arch/wgrisc/wgrisc/machdep.c | 46 |
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: |