Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 May 2012 23:36:15 GMT
From:      Brooks Davis <brooks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 212065 for review
Message-ID:  <201205312336.q4VNaFSj097041@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@212065?ac=10

Change 212065 by brooks@brooks_ecr_current on 2012/05/31 23:35:16

	Checkpoint a version of the isf(4) driver with the ability to read.
	
	It appears that both devices are talking to the same 32MB chip which
	clearly isn't right, but the result should still be partially useful.
	
	       Keep the hints commented out as it conflicts with the device required
	for Simon's useful flashprog tool.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/dev/isf/isf.c#3 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/isf/isf.h#3 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/isf/isf_nexus.c#3 edit
.. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#14 edit
.. //depot/projects/ctsrd/beribsd/src/sys/mips/conf/BERI_DE4.hints#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/mips/conf/BERI_DE4_SDROOT#2 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/dev/isf/isf.c#3 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2012 Robert N. M. Watson
+ # Copyright (c) 2012 SRI International
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -32,17 +33,19 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
 #include <sys/bus.h>
-#include <sys/condvar.h>
 #include <sys/conf.h>
+#include <sys/endian.h>
 #include <sys/bio.h>
-#include <sys/kernel.h>
+#include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
-#include <sys/module.h>
 #include <sys/mutex.h>
 #include <sys/rman.h>
-#include <sys/systm.h>
 #include <sys/taskqueue.h>
 
 #include <machine/bus.h>
@@ -52,7 +55,63 @@
 
 #include <dev/isf/isf.h>
 
+/* Read Mode */
+#define	ISF_CMD_RA	0xFF	/* Read Array mode */
+#define	ISF_CMD_RSR	0x70	/* Read Status Register mode */
+#define	ISF_CMD_RDI	0x90	/* Read Device ID/Config Reg mode */
+#define	ISF_CMD_RQ	0x98	/* Read Query mode */
+#define	ISF_CMD_CSR	0x50	/* Clear Status Register */
+
+/* Write Mode */
+#define	ISF_CMD_WPS	0x40	/* Word Program Setup */
+#define	ISF_CMD_BPC	0xD0	/* Buffered Program Confirm */
+
+/* Erase Mode */
+#define	ISF_CMD_BES	0x20	/* Block Erase Setup */
+#define IFS_CMD_BEC	0xD0	/* Block Erase Confirm */
+
+/* Block Locking/Unlocking */
+#define	ISF_CMD_LBS	0x60	/* Lock Block Setup */
+#define	IFS_CMD_LB	0x01	/* Lock Block */
+#define	IFS_CMD_UB	0xD0	/* Unlock Block */
+
+/*
+ * Read Device Identifier registers.
+ *
+ * NOTE: ISF_RDIR_BLC is relative to the block base address.
+ */
+#define	ISF_REG_MC	0x00	/* Manufacture Code */
+#define ISF_REG_ID	0x01	/* Device ID Code */
+#define	ISF_REG_BLC	0x02	/* Block Lock Configuration */
+#define ISF_REG_RCR	0x05	/* Read Configuration Register */
+
 /*
+ * Protection Registers
+ */
+#define ISF_REG_L0	0x80	/* Lock Register 0 */
+#define ISF_REG_FPP	0x81	/* 64-bit Factory Protection Register */
+#define ISF_REG_UPP	0x85	/* 64-bit User Protection Register */
+#define ISF_REG_L1	0x89	/* Lock Register 1 */
+#define ISF_REG_PP1	0x8A	/* 128-bit Protection Register 1 */
+#define ISF_REG_PP2	0x92	/* 128-bit Protection Register 2 */
+#define ISF_REG_PP3	0x9A	/* 128-bit Protection Register 3 */
+#define ISF_REG_PP4	0xA2	/* 128-bit Protection Register 4 */
+#define ISF_REG_PP5	0xAA	/* 128-bit Protection Register 5 */
+#define ISF_REG_PP6	0xB2	/* 128-bit Protection Register 6 */
+#define ISF_REG_PP7	0xBA	/* 128-bit Protection Register 7 */
+#define ISF_REG_PP8	0xC2	/* 128-bit Protection Register 8 */
+#define ISF_REG_PP9	0xCA	/* 128-bit Protection Register 9 */
+#define ISF_REG_PP10	0xD2	/* 128-bit Protection Register 10 */
+#define ISF_REG_PP11	0xDA	/* 128-bit Protection Register 11 */
+#define ISF_REG_PP12	0xE2	/* 128-bit Protection Register 12 */
+#define ISF_REG_PP13	0xEA	/* 128-bit Protection Register 13 */
+#define ISF_REG_PP14	0xF2	/* 128-bit Protection Register 14 */
+#define ISF_REG_PP15	0xFA	/* 128-bit Protection Register 15 */
+#define ISF_REG_PP16	0x102	/* 128-bit Protection Register 16 */
+
+static void	isf_task(void *arg);
+
+/* 
  * Device driver for the Intel StrataFlash NOR flash device.  This
  * implementation is known to work with 256Mb instances of the device, but may
  * also work with other 64/128/512Mb parts without much work.  Multiple
@@ -61,25 +120,37 @@
  * part.
  */
 
-#if 0
-/*
- * XXXRW: Sample bus_space I/O routines which we would like to model isf
- * register and command routines on.
- */
 static uint16_t
-isf_read_rr1(struct isf_softc *sc)
+isf_read_reg(struct isf_softc *sc, uint32_t reg)
+{
+
+	device_printf(sc->isf_dev, "isf_read_reg(0x%02x)\n", reg);
+	return (le16toh(bus_read_2(sc->isf_res, reg * 2)));
+}
+
+static uint64_t
+isf_read_reg64(struct isf_softc *sc, uint32_t reg)
 {
+	uint64_t val;
+	uint16_t *val16 = (uint16_t *)&val;
 
-	return (le16toh(bus_read_2(sc->isf_res, ISF_OFF_RR1)));
+	device_printf(sc->isf_dev, "isf_read_reg64(0x%02x)\n", reg);
+	val16[0] = bus_read_2(sc->isf_res, reg * 2);
+	val16[1] = bus_read_2(sc->isf_res, (reg+1) * 2);
+	val16[2] = bus_read_2(sc->isf_res, (reg+2) * 2);
+	val16[3] = bus_read_2(sc->isf_res, (reg+3) * 2);
+
+	return(le64toh(val));
 }
 
 static void
-isf_write_cmd_arg(struct isf_softc *sc, uint32_t cmd_arg)
+isf_write_cmd(struct isf_softc *sc, off_t off, uint16_t cmd)
 {
-
-	bus_write_4(sc->isf_res, ISF_OFF_CMD_ARG, htole32(cmd_arg));
+	
+	device_printf(sc->isf_dev, "isf_write_cmd(0x%08jx, 0x%02x)\n",
+	    off, cmd);
+	bus_write_2(sc->isf_res, off, htole16(cmd));
 }
-#endif
 
 static void
 isf_read(struct isf_softc *sc, off_t off, void *data, size_t len)
@@ -115,14 +186,6 @@
  * disk(9) methods.
  */
 static int
-isf_disk_dump(void *arg, void *virtual, vm_offset_t physical,
-    off_t offset, size_t length)
-{
-
-	panic("%s: not yet", __func__);
-}
-
-static int
 isf_disk_ioctl(struct disk *disk, u_long cmd, void *data, int fflag,
     struct thread *td)
 {
@@ -134,8 +197,7 @@
 static void
 isf_disk_strategy(struct bio *bp)
 {
-	struct isf_softc *sc;
-	int error;
+	struct isf_softc *sc = bp->bio_disk->d_drv1;;
 
 	/*
 	 * We advertise a block size and maximum I/O size up the stack; catch
@@ -144,39 +206,89 @@
 	KASSERT(bp->bio_bcount == ISF_SECTORSIZE,
 	    ("%s: I/O size not %d", __func__, ISF_SECTORSIZE));
 
-	/*
-	 * Although the flash doesn't need sorting, we don't want to introduce
-	 * barriers, so use bioq_disksort().
-	 */
-	sc = bp->bio_disk->d_drv1;
 	ISF_LOCK(sc);
-	error = 0;
-	switch (bp->bio_cmd) {
-	case BIO_READ:
-		isf_read(sc, bp->bio_pblkno * ISF_SECTORSIZE, bp->bio_data,
-		    bp->bio_bcount);
-		break;
+	bioq_disksort(&sc->isf_bioq, bp);
+	ISF_WAKEUP(sc);
+	ISF_UNLOCK(sc);
+}
+
+static void
+isf_task(void *arg)
+{
+	struct isf_softc	*sc = arg;
+	struct bio		*bp;
+	int			ss = sc->isf_disk->d_sectorsize;
+
+	for (;;) {
+		ISF_LOCK(sc);
+		do {
+			bp = bioq_first(&sc->isf_bioq);
+			if (bp == NULL)
+				ISF_SLEEP(sc);
+		} while (bp == NULL);
+		bioq_remove(&sc->isf_bioq, bp);
+
+		switch (bp->bio_cmd) {
+		case BIO_READ:
+			isf_read(sc, bp->bio_pblkno * ss, bp->bio_data,
+			    bp->bio_bcount);
+			biodone(bp);
+			break;
 
-	case BIO_WRITE:
-		error = ENXIO;
+		case BIO_WRITE:
 #ifdef NOTYET
-		/*
-		 * XXXRW: copied and pasted from altera_sdcard -- obviously
-		 * won't work.
-		 */
-		isf_write(sc, bp->bio_pbklno * ISF_SECTORSIZE, bp->bio_data,
-		    bp->bio_bcount);
+			/*
+			 * XXXRW: copied and pasted from altera_sdcard --
+			 *  obviously won't work.
+			 */
+			isf_write(sc, bp->bio_pbklno * ss, bp->bio_data,
+			    bp->bio_bcount);
 #endif
-		break;
+			biofinish(bp, NULL, ENXIO);
+			break;
+
+		default:
+			panic("%s: unsupported I/O operation %d", __func__,
+			    bp->bio_cmd);
+		}
+		ISF_UNLOCK(sc);
+	}
+}
+
+static void
+isf_dump_info(struct isf_softc *sc)
+{
+	int i;
+	int32_t reg;
+	
+	isf_write_cmd(sc, 0, ISF_CMD_RDI);
+	device_printf(sc->isf_dev, "manufacturer code: 0x%04x\n",
+	    isf_read_reg(sc, ISF_REG_MC));
+	device_printf(sc->isf_dev, "device id code: 0x%04x\n",
+	    isf_read_reg(sc, ISF_REG_ID));
+	device_printf(sc->isf_dev, "read config register: 0x%04x\n",
+	    isf_read_reg(sc, ISF_REG_RCR));
+
+	device_printf(sc->isf_dev, "lock register 0: 0x%04x\n",
+	    isf_read_reg(sc, ISF_REG_L0));
+	device_printf(sc->isf_dev, "lock register 1: 0x%04x\n",
+	    isf_read_reg(sc, ISF_REG_L1));
+
+	device_printf(sc->isf_dev, "factory PPR: 0x%016jx\n",
+	    (uintmax_t)isf_read_reg64(sc, ISF_REG_FPP));
+	device_printf(sc->isf_dev, "user PPR (64-bit): 0x%016jx\n",
+	    (uintmax_t)isf_read_reg64(sc, ISF_REG_UPP));
 
-	default:
-		panic("%s: unsupported I/O operation %d", __func__,
-		    bp->bio_cmd);
+	for (reg = ISF_REG_PP1, i = 1; reg <= ISF_REG_PP16; reg += 8, i++) {
+		/* XXX: big-endian ordering of uint64_t's */
+		device_printf(sc->isf_dev,
+		    "user PPR [%02d]: 0x%016jx%016jx\n", i,
+		    (uintmax_t)isf_read_reg64(sc, reg+4),
+		    (uintmax_t)isf_read_reg64(sc, reg));
 	}
-	if (error == 0)
-		bp->bio_resid = 0;
-	biofinish(bp, NULL, error);
-	ISF_UNLOCK(sc);
+
+
+	isf_write_cmd(sc, 0, ISF_CMD_RA);
 }
 
 static void
@@ -184,20 +296,26 @@
 {
 	struct disk *disk;
 
+	kproc_create(&isf_task, sc, &sc->isf_proc, 0, 0, "isf");
+
 	disk = disk_alloc();
 	disk->d_drv1 = sc;
 	disk->d_name = "isf";
 	disk->d_unit = sc->isf_unit;
 	disk->d_strategy = isf_disk_strategy;
-	disk->d_dump = isf_disk_dump;
 	disk->d_ioctl = isf_disk_ioctl;
 	disk->d_sectorsize = ISF_SECTORSIZE;
 	disk->d_mediasize = ISF_MEDIASIZE;
 	disk->d_maxsize = ISF_SECTORSIZE;
 	sc->isf_disk = disk;
+
+	/* XXXBED: put under bootverbose */
+	isf_dump_info(sc);
+
 	disk_create(disk, DISK_VERSION);
 	device_printf(sc->isf_dev, "%juM flash device\n",
-	    (uintmax_t)disk->d_maxsize / (1024 * 1024));
+	    (uintmax_t)disk->d_mediasize / (1024 * 1024));
+
 }
 
 static void
@@ -237,6 +355,7 @@
 		    "Unsupported flash size %lu\n", size);
 		return (ENXIO);
 	}
+	bioq_init(&sc->isf_bioq);
 	ISF_LOCK_INIT(sc);
 	sc->isf_disk = NULL;
 	isf_disk_insert(sc);

==== //depot/projects/ctsrd/beribsd/src/sys/dev/isf/isf.h#3 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2012 Robert N. M. Watson
+ * Copyright (c) 2012 SRI International
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -49,6 +50,7 @@
 	int			 isf_rid;
 	struct mtx		 isf_lock;
 	struct disk		*isf_disk;
+	struct proc		*isf_proc;
 
 	/*
 	 * Fields relating to in-progress and pending I/O, if any.
@@ -61,7 +63,10 @@
 #define	ISF_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->isf_lock)
 #define	ISF_LOCK_INIT(sc)	mtx_init(&(sc)->isf_lock, "isf", NULL,	\
 				    MTX_DEF)
+#define	ISF_SLEEP(sc)		mtx_sleep((sc), &(sc)->isf_lock, PRIBIO, \
+				    "isf", 0)
 #define	ISF_UNLOCK(sc)		mtx_unlock(&(sc)->isf_lock)
+#define	ISF_WAKEUP(sc)		wakeup((sc))
 
 int	isf_attach(struct isf_softc *sc);
 void	isf_detach(struct isf_softc *sc);

==== //depot/projects/ctsrd/beribsd/src/sys/dev/isf/isf_nexus.c#3 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2012 Robert N. M. Watson
+ * Copyright (c) 2012 SRI International
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of

==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#14 (text+ko) ====

@@ -13,6 +13,8 @@
 dev/terasic/mtl/terasic_mtl_reg.c	optional terasic_mtl
 dev/terasic/mtl/terasic_mtl_syscons.c	optional terasic_mtl
 dev/terasic/mtl/terasic_mtl_text.c	optional terasic_mtl
+dev/isf/isf.c				optional isf
+dev/isf/isf_nexus.c			optional isf
 mips/beri/beri_machdep.c		standard
 mips/mips/intr_machdep.c		standard
 mips/mips/tick.c			standard

==== //depot/projects/ctsrd/beribsd/src/sys/mips/conf/BERI_DE4.hints#2 (text+ko) ====

@@ -42,3 +42,15 @@
 hint.altera_avgen.0.fileio="rw"
 hint.altera_avgen.0.mmapio="rwx"
 hint.altera_avgen.0.devname="de4flash"
+
+#
+# General Intel StrataFlash driver
+#
+# To enable this you must disable the altera_avgen de4flash mapping.
+#
+#hint.isf.0.at="nexus0"
+#hint.isf.0.maddr=0x74000000
+#hint.isf.0.msize=0x2000000
+#hint.isf.1.at="nexus0"
+#hint.isf.1.maddr=0x76000000
+#hint.isf.1.msize=0x2000000

==== //depot/projects/ctsrd/beribsd/src/sys/mips/conf/BERI_DE4_SDROOT#2 (text+ko) ====

@@ -51,6 +51,7 @@
 device		altera_sdcard
 device		terasic_de4led
 device		terasic_mtl
+device		isf
 
 device		md
 device		ether



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205312336.q4VNaFSj097041>