PERFORCE change 222008 for review

Brooks Davis brooks at FreeBSD.org
Wed Feb 13 18:14:55 UTC 2013


http://p4web.freebsd.org/@@222008?ac=10

Change 222008 by brooks at brooks_zenith on 2013/02/13 18:14:19

	Add multi-byte (buffer) write support.  This brings the speed up
	to within 10% of isf(4) so CFI is useable.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_core.c#6 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_reg.h#4 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_var.h#5 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_core.c#6 (text+ko) ====

@@ -276,10 +276,16 @@
 
 	/* Get time-out values for erase and write. */
 	sc->sc_write_timeout = 1 << cfi_read_qry(sc, CFI_QRY_TTO_WRITE);
+	sc->sc_bufwrite_timeout = 1 << cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE);
 	sc->sc_erase_timeout = 1 << cfi_read_qry(sc, CFI_QRY_TTO_ERASE);
 	sc->sc_write_timeout *= 1 << cfi_read_qry(sc, CFI_QRY_MTO_WRITE);
+	sc->sc_bufwrite_timeout *= 1 << cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE);
 	sc->sc_erase_timeout *= 1 << cfi_read_qry(sc, CFI_QRY_MTO_ERASE);
 
+	/* Get the maximum size of a multibyte program */
+	sc->sc_maxbuf = 1 << (cfi_read_qry(sc, CFI_QRY_MAXBUF) |
+	    cfi_read_qry(sc, CFI_QRY_MAXBUF) << 8);
+
 	/* Get erase regions. */
 	sc->sc_regions = cfi_read_qry(sc, CFI_QRY_NREGIONS);
 	sc->sc_region = malloc(sc->sc_regions * sizeof(struct cfi_region),
@@ -389,6 +395,8 @@
 	} ptr, cpyprt;
 	register_t intr;
 	int error, i, neederase = 0;
+	uint32_t st;
+	u_int wlen;
 
 	switch (sc->sc_cmdset) {
 	case CFI_VEND_INTEL_ECS:
@@ -430,9 +438,58 @@
 	} else
 		error = 0;
 
-	/* Write the block. */
+	/* Write the block using a multibyte write if supported. */
 	ptr.x8 = sc->sc_wrbuf;
 	cpyprt.x8 = sc->sc_wrbufcpy;
+	if (sc->sc_bufwrite_timeout > 0 && sc->sc_maxbuf > sc->sc_width) {
+		switch (sc->sc_cmdset) {
+		case CFI_VEND_INTEL_ECS:
+		case CFI_VEND_INTEL_SCS:
+			for (i = 0; i < sc->sc_wrbufsz; i += wlen) {
+				wlen = MIN(sc->sc_maxbuf, sc->sc_wrbufsz - i);
+
+				do {
+					cfi_write(sc, sc->sc_wrofs + i,
+					    CFI_BCS_BUF_PROG_SETUP);
+					/* XXX: do some timeout management */
+					st = cfi_read(sc, sc->sc_wrofs + i);
+				} while (! (st & CFI_INTEL_STATUS_WSMS));
+
+				cfi_write(sc, sc->sc_wrofs + i,
+				    (wlen / sc->sc_width) - 1);
+				switch (sc->sc_width) {
+				case 1:
+					bus_space_write_region_1(sc->sc_tag,
+					    sc->sc_handle, sc->sc_wrofs + i,
+					    ptr.x8 + i, wlen);
+					break;
+				case 2:
+					bus_space_write_region_2(sc->sc_tag,
+					    sc->sc_handle, sc->sc_wrofs + i,
+					    ptr.x16 + i / 2, wlen / 2);
+					break;
+				case 4:
+					bus_space_write_region_4(sc->sc_tag,
+					    sc->sc_handle, sc->sc_wrofs + i,
+					    ptr.x32 + i / 4, wlen / 4);
+					break;
+				}
+
+				cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM);
+
+				error = cfi_wait_ready(sc, sc->sc_wrofs + i,
+				    sc->sc_write_timeout);
+
+				goto out;
+			}
+		default:
+			/* Fall through to single word case */
+			break;
+		}
+
+	}
+
+	/* Write the block one byte/word at a time. */
 	for (i = 0; i < sc->sc_wrbufsz; i += sc->sc_width) {
 
 		/* Avoid writing unless we are actually changing bits */

==== //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_reg.h#4 (text+ko) ====

@@ -70,12 +70,15 @@
 #define	CFI_QRY_VEND		offsetof(struct cfi_qry, pri_vend)
 
 #define	CFI_QRY_TTO_WRITE	offsetof(struct cfi_qry, tto_byte_write)
+#define	CFI_QRY_TTO_BUFWRITE	offsetof(struct cfi_qry, tto_buf_write)
 #define	CFI_QRY_TTO_ERASE	offsetof(struct cfi_qry, tto_block_erase)
 #define	CFI_QRY_MTO_WRITE	offsetof(struct cfi_qry, mto_byte_write)
+#define	CFI_QRY_MTO_BUFWRITE	offsetof(struct cfi_qry, mto_buf_write)
 #define	CFI_QRY_MTO_ERASE	offsetof(struct cfi_qry, mto_block_erase)
 
 #define	CFI_QRY_SIZE		offsetof(struct cfi_qry, size)
 #define	CFI_QRY_IFACE		offsetof(struct cfi_qry, iface)
+#define	CFI_QRY_MAXBUF		offsetof(struct cfi_qry, max_buf_write_size)
 #define	CFI_QRY_NREGIONS	offsetof(struct cfi_qry, nregions)
 #define	CFI_QRY_REGION0		offsetof(struct cfi_qry, region)
 #define	CFI_QRY_REGION(x)	(CFI_QRY_REGION0 + (x) * 4)
@@ -102,6 +105,7 @@
 #define	CFI_BCS_ERASE_SUSPEND	0xb0
 #define	CFI_BCS_ERASE_RESUME	0xd0	/* Equals CONFIRM */
 #define	CFI_BCS_CONFIRM		0xd0
+#define	CFI_BCS_BUF_PROG_SETUP	0xe8
 #define	CFI_BCS_READ_ARRAY	0xff
 
 /* Intel commands. */

==== //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_var.h#5 (text+ko) ====

@@ -52,8 +52,11 @@
 
 	u_int		sc_cmdset;
 	u_int		sc_erase_timeout;
+	u_int		sc_bufwrite_timeout;
 	u_int		sc_write_timeout;
 
+	u_int		sc_maxbuf;
+
 	struct cdev	*sc_nod;
 	struct proc	*sc_opened;	/* Process that has us opened. */
 


More information about the p4-projects mailing list