Date: Wed, 13 Feb 2013 18:14:54 GMT From: Brooks Davis <brooks@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 222008 for review Message-ID: <201302131814.r1DIEsaM073316@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@222008?ac=10 Change 222008 by brooks@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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302131814.r1DIEsaM073316>
