[inferno-kirkwood] 2 new revisions pushed by mechiel@ueber.net on 2010-03-17 16:41 GMT

2 views
Skip to first unread message

inferno-...@googlecode.com

unread,
Mar 17, 2010, 12:42:26 PM3/17/10
to inferno-kirk...@googlegroups.com
2 new revisions:

Revision: bdd6e07c70
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Wed Mar 17 05:01:18 2010
Log: split devsdio....
http://code.google.com/p/inferno-kirkwood/source/detail?r=bdd6e07c70

Revision: 51c19b3059
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Wed Mar 17 09:41:13 2010
Log: improve devsdio.c, i've briefly ran kfs on it....
http://code.google.com/p/inferno-kirkwood/source/detail?r=51c19b3059

==============================================================================
Revision: bdd6e07c70
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Wed Mar 17 05:01:18 2010
Log: split devsdio.

devsdio.c is now only the host controller code.
sdcard.[ch] has functions to deal with info about/on the card.
http://code.google.com/p/inferno-kirkwood/source/detail?r=bdd6e07c70

Added:
/sdcard.c
/sdcard.h
Modified:
/README
/archkirkwood.c
/devsdio.c
/fns.h
/sheeva

=======================================
--- /dev/null
+++ /sdcard.c Wed Mar 17 05:01:18 2010
@@ -0,0 +1,224 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+#include "io.h"
+#include "sdcard.h"
+
+
+static int
+min(int a, int b)
+{
+ if(a < b)
+ return a;
+ return b;
+}
+
+ulong
+bits(uchar *p, int msb, int lsb)
+{
+ ulong v;
+ int nbits, o, n;
+
+ nbits = msb-lsb+1;
+ n = lsb/8;
+ p += n;
+ lsb -= n*8;
+
+ n = min(nbits, 8-lsb);
+ nbits -= n;
+ v = (*p++>>lsb) & MASK(n);
+ o = n;
+
+ while(nbits > 0) {
+ n = min(nbits, 8);
+ nbits -= n;
+ v |= ((ulong)*p++ & MASK(n)) << o;
+ o += n;
+ }
+ return v;
+}
+
+int
+parsecid(Cid *c, uchar *r)
+{
+ uchar *p;
+
+ c->mon = bits(r, 11, 8);
+ c->year = 2000 + bits(r, 19, 16)*10 + bits(r, 15, 12);
+ c->serial = bits(r, 55, 24);
+ c->rev = bits(r, 63, 56);
+
+ p = r+64/8;
+ c->prodname[0] = p[4];
+ c->prodname[1] = p[3];
+ c->prodname[2] = p[2];
+ c->prodname[3] = p[1];
+ c->prodname[4] = p[0];
+ c->prodname[5] = '\0';
+
+ p = r+104/8;
+ c->oid[0] = p[1];
+ c->oid[1] = p[0];
+ c->oid[2] = '\0';
+
+ c->mid = bits(r, 127, 120);
+ return 0;
+}
+
+char*
+cidstr(char *p, char *e, Cid *c)
+{
+ return seprint(p, e,
+ "product %s, rev %#ux, serial %#lux, made %04d-%02d, oem %s,
manufacturer %#ux\n",
+ c->prodname,
+ c->rev,
+ c->serial,
+ c->year, c->mon,
+ c->oid,
+ c->mid);
+}
+
+int
+parsecsd(Csd *c, uchar *r)
+{
+ c->version = bits(r, 127, 126);
+ if(c->version != 0 && c->version != 1)
+ return -1;
+
+ c->taac = bits(r, 119, 112);
+ c->nsac = bits(r, 111, 104);
+ c->xferspeed = bits(r, 103, 96);
+ c->cmdclasses = bits(r, 95, 84);
+ c->readblocklength = bits(r, 83, 80);
+ c->readblockpartial = bits(r, 79, 79);
+ c->writeblockmisalign = bits(r, 78, 78);
+ c->readblockmisalign = bits(r, 77, 77);
+ c->dsr = bits(r, 76, 76);
+ if(c->version == 0) {
+ c->size = bits(r, 75, 62);
+ c->v0.vddrmin = bits(r, 61, 59);
+ c->v0.vddrmax = bits(r, 58, 56);
+ c->v0.vddwmin = bits(r, 55, 53);
+ c->v0.vddwmax = bits(r, 52, 50);
+ c->v0.sizemult = bits(r, 49, 47);
+ } else {
+ c->size = bits(r, 69, 48);
+ }
+ c->eraseblockenable = bits(r, 46, 46);
+ c->erasesectorsize = bits(r, 45, 39);
+ c->wpgroupsize = bits(r, 38, 32);
+ c->wpgroupenable = bits(r, 31, 31);
+ c->writespeedfactor = bits(r, 28, 26);
+ c->writeblocklength = bits(r, 25, 22);
+ c->writeblockpartial = bits(r, 21, 21);
+ c->fileformatgroup = bits(r, 15, 15);
+ c->copy = bits(r, 14, 14);
+ c->permwriteprotect = bits(r, 13, 13);
+ c->tmpwriteprotect = bits(r, 12, 12);
+ c->fileformat = bits(r, 11, 10);
+
+ return 0;
+}
+
+char*
+csdstr(char *p, char *e, Csd *c)
+{
+ char versbuf[128];
+
+ versbuf[0] = '\0';
+ if(c->version == 0)
+ snprint(versbuf, sizeof versbuf,
+ "vddrmin %x\n"
+ "vddrmax %x\n"
+ "vddwmin %x\n"
+ "vddwmax %x\n"
+ "sizemult %x\n",
+ c->v0.vddrmin,
+ c->v0.vddrmax,
+ c->v0.vddwmin,
+ c->v0.vddwmax,
+ c->v0.sizemult);
+ return seprint(p, e,
+ "version %x\n"
+ "taac %x\n"
+ "nsac %x\n"
+ "xferspeed %x\n"
+ "cmdclasses %x\n"
+ "readblocklength %x\n"
+ "readblockpartial %x\n"
+ "writeblockmisalign %x\n"
+ "readblockmisalign %x\n"
+ "dsr %x\n"
+ "devsize %x\n"
+ "%s"
+ "eraseblockenable %x\n"
+ "erasesectorsize %x\n"
+ "wpgroupsize %x\n"
+ "wpgroupenable %x\n"
+ "writespeedfactor %x\n"
+ "writeblocklength %x\n"
+ "writeblockpartial %x\n"
+ "fileformatgroup %x\n"
+ "copy %x\n"
+ "permwriteprotect %x\n"
+ "tmpwriteprotect %x\n"
+ "fileformat %x\n",
+ c->version,
+ c->taac,
+ c->nsac,
+ c->xferspeed,
+ c->cmdclasses,
+ c->readblocklength,
+ c->readblockpartial,
+ c->writeblockmisalign,
+ c->readblockmisalign,
+ c->dsr,
+ c->size,
+ versbuf,
+ c->eraseblockenable,
+ c->erasesectorsize,
+ c->wpgroupsize,
+ c->wpgroupenable,
+ c->writespeedfactor,
+ c->writeblocklength,
+ c->writeblockpartial,
+ c->fileformatgroup,
+ c->copy,
+ c->permwriteprotect,
+ c->tmpwriteprotect,
+ c->fileformat);
+}
+
+char*
+cardtype(Card *c)
+{
+ if(c->mmc)
+ return "mmc";
+ if(c->sdhc)
+ return "sdhc";
+ return "sd";
+}
+
+char*
+cardstr(Card *c, char *buf, int n)
+{
+ snprint(buf, n,
+ "card %s\n"
+ "type %s\n"
+ "size %lld bytes\n"
+ "blocksize %lud\n"
+ "manufactured %d-%02d\n"
+ "rev %#ux\n"
+ "serial %#lux\n",
+ c->cid.prodname,
+ cardtype(c),
+ c->size,
+ c->bs,
+ c->cid.year, c->cid.mon,
+ c->cid.rev,
+ c->cid.serial);
+ return buf;
+}
=======================================
--- /dev/null
+++ /sdcard.h Wed Mar 17 05:01:18 2010
@@ -0,0 +1,70 @@
+enum {
+ Respmax = (136+8-1)/8,
+};
+
+typedef struct Card Card;
+typedef struct Cid Cid;
+typedef struct Csd Csd;
+
+struct Cid
+{
+ uint mid; /* manufacturer id */
+ char oid[2+1]; /* oem id */
+ char prodname[5+1]; /* product name */
+ uint rev; /* product revision */
+ ulong serial;
+ int year;
+ int mon;
+};
+
+/* xxx make shorter but still readable names */
+struct Csd
+{
+ int version;
+ int taac, nsac;
+ int xferspeed;
+ int cmdclasses;
+ int readblocklength, readblockpartial;
+ int writeblockmisalign, readblockmisalign;
+ int dsr;
+ int size;
+ union {
+ struct {
+ int vddrmin, vddrmax, vddwmin, vddwmax;
+ int sizemult;
+ } v0;
+ };
+ int eraseblockenable, erasesectorsize;
+ int wpgroupsize, wpgroupenable;
+ int writespeedfactor;
+ int writeblocklength, writeblockpartial;
+ int fileformatgroup;
+ int copy;
+ int permwriteprotect, tmpwriteprotect;
+ int fileformat;
+};
+
+struct Card {
+ int valid;
+ Cid cid;
+ Csd csd;
+ ulong bs;
+ uvlong size;
+ int mmc;
+ int sd2;
+ int sdhc;
+ uint rca;
+ uchar resp[Respmax];
+ int lastcmd;
+ int lastisapp;
+ int lasterr;
+};
+
+ulong bits(uchar *p, int msb, int lsb);
+
+int parsecid(Cid *c, uchar *r);
+char* cidstr(char *p, char *e, Cid *c);
+int parsecsd(Csd *c, uchar *r);
+char* csdstr(char *p, char *e, Csd *c);
+char* cardtype(Card *c);
+char* cardstr(Card *c, char *buf, int n);
=======================================
--- /README Mon Mar 15 06:57:05 2010
+++ /README Wed Mar 17 05:01:18 2010
@@ -5,9 +5,7 @@
nand flash pages.

next steps:
-- find out why jumping to eg dcflushinvalall hangs (perhaps the test &
clean cache operation with r15 as arg is not right?)
-- better dcache flushing
-- l2 cache
+- l2 cache, does not seem to speed up much. something wrong?
- better nand support
- delay/microdelay calibration
- better sata support
=======================================
--- /archkirkwood.c Mon Mar 15 06:57:05 2010
+++ /archkirkwood.c Wed Mar 17 05:01:18 2010
@@ -9,6 +9,14 @@
#include "../port/netif.h"
#include "etherif.h"
#include "../port/flashif.h"
+
+/* read register to force a write. (writes to soc registers are in-order
within functional parts, not across them) */
+void
+regreadl(ulong *v)
+{
+ volatile ulong p = *v;
+ USED(p);
+}

static char *
devidstr(ulong v)
=======================================
--- /devsdio.c Mon Mar 15 06:57:05 2010
+++ /devsdio.c Wed Mar 17 05:01:18 2010
@@ -5,6 +5,7 @@
#include "fns.h"
#include "../port/error.h"
#include "io.h"
+#include "sdcard.h"

static int debug = 0;
#define dprint if(debug)print
@@ -25,7 +26,6 @@
TMswwrite = 1<<6,

/* cmd */
- Respmax = (136+7)/8,
#define CMDresp(x) ((x)<<0)
CMDrespnone = 0<<0,
CMDresp136 = 1<<0,
@@ -124,63 +124,6 @@
ESAcmd12RespStartBitErr = 1<<6,
};

-typedef struct Card Card;
-typedef struct Cid Cid;
-typedef struct Csd Csd;
-
-struct Cid
-{
- uint mid; /* manufacturer id */
- char oid[2+1]; /* oem id */
- char prodname[5+1]; /* product name */
- uint rev; /* product revision */
- ulong serial;
- int year;
- int mon;
-};
-
-/* xxx make shorter but still readable names */
-struct Csd
-{
- int version;
- int taac, nsac;
- int xferspeed;
- int cmdclasses;
- int readblocklength, readblockpartial;
- int writeblockmisalign, readblockmisalign;
- int dsr;
- int size;
- union {
- struct {
- int vddrmin, vddrmax, vddwmin, vddwmax;
- int sizemult;
- } v0;
- };
- int eraseblockenable, erasesectorsize;
- int wpgroupsize, wpgroupenable;
- int writespeedfactor;
- int writeblocklength, writeblockpartial;
- int fileformatgroup;
- int copy;
- int permwriteprotect, tmpwriteprotect;
- int fileformat;
-};
-
-struct Card {
- int valid;
- Cid cid;
- Csd csd;
- ulong bs;
- uvlong size;
- int mmc;
- int sd2;
- int sdhc;
- uint rca;
- uchar resp[Respmax];
- int lastcmd;
- int lastisapp;
- int lasterr;
-};

static Card card;
static Rendez dmar;
@@ -199,39 +142,6 @@
"sdioinfo", {Qinfo}, 0, 0444,
"sdio", {Qdata}, 0, 0666,
};
-
-static int
-min(int a, int b)
-{
- if(a < b)
- return a;
- return b;
-}
-
-static ulong
-bits(uchar *p, int msb, int lsb)
-{
- ulong v;
- int nbits, o, n;
-
- nbits = msb-lsb+1;
- n = lsb/8;
- p += n;
- lsb -= n*8;
-
- n = min(nbits, 8-lsb);
- nbits -= n;
- v = (*p++>>lsb) & MASK(n);
- o = n;
-
- while(nbits > 0) {
- n = min(nbits, 8);
- nbits -= n;
- v |= ((ulong)*p++ & MASK(n)) << o;
- o += n;
- }
- return v;
-}

static void
putle(uchar *p, uvlong v, int n)
@@ -483,7 +393,7 @@
printstatus("success", reg->status, reg->errstatus, reg->acmd12errstatus);

/* fetch the response */
- memset(c->resp, '\0', Respmax);
+ memset(c->resp, 0, sizeof c->resp);
switch(resptype) {
case CMDrespnone:
break;
@@ -532,188 +442,6 @@
c->lasterr = sdcmd0(c, 1, cmd, arg);
return c->lasterr;
}
-
-static int
-parsecid(Cid *c, uchar *r)
-{
- uchar *p;
-
- c->mon = bits(r, 11, 8);
- c->year = 2000 + bits(r, 19, 16)*10 + bits(r, 15, 12);
- c->serial = bits(r, 55, 24);
- c->rev = bits(r, 63, 56);
-
- p = r+64/8;
- c->prodname[0] = p[4];
- c->prodname[1] = p[3];
- c->prodname[2] = p[2];
- c->prodname[3] = p[1];
- c->prodname[4] = p[0];
- c->prodname[5] = '\0';
-
- p = r+104/8;
- c->oid[0] = p[1];
- c->oid[1] = p[0];
- c->oid[2] = '\0';
-
- c->mid = bits(r, 127, 120);
- return 0;
-}
-
-static char*
-cidstr(char *p, char *e, Cid *c)
-{
- return seprint(p, e,
- "product %s, rev %#ux, serial %#lux, made %04d-%02d, oem %s,
manufacturer %#ux\n",
- c->prodname,
- c->rev,
- c->serial,
- c->year, c->mon,
- c->oid,
- c->mid);
-}
-
-static int
-parsecsd(Csd *c, uchar *r)
-{
- c->version = bits(r, 127, 126);
- if(c->version != 0 && c->version != 1)
- return -1;
-
- c->taac = bits(r, 119, 112);
- c->nsac = bits(r, 111, 104);
- c->xferspeed = bits(r, 103, 96);
- c->cmdclasses = bits(r, 95, 84);
- c->readblocklength = bits(r, 83, 80);
- c->readblockpartial = bits(r, 79, 79);
- c->writeblockmisalign = bits(r, 78, 78);
- c->readblockmisalign = bits(r, 77, 77);
- c->dsr = bits(r, 76, 76);
- if(c->version == 0) {
- c->size = bits(r, 75, 62);
- c->v0.vddrmin = bits(r, 61, 59);
- c->v0.vddrmax = bits(r, 58, 56);
- c->v0.vddwmin = bits(r, 55, 53);
- c->v0.vddwmax = bits(r, 52, 50);
- c->v0.sizemult = bits(r, 49, 47);
- } else {
- c->size = bits(r, 69, 48);
- }
- c->eraseblockenable = bits(r, 46, 46);
- c->erasesectorsize = bits(r, 45, 39);
- c->wpgroupsize = bits(r, 38, 32);
- c->wpgroupenable = bits(r, 31, 31);
- c->writespeedfactor = bits(r, 28, 26);
- c->writeblocklength = bits(r, 25, 22);
- c->writeblockpartial = bits(r, 21, 21);
- c->fileformatgroup = bits(r, 15, 15);
- c->copy = bits(r, 14, 14);
- c->permwriteprotect = bits(r, 13, 13);
- c->tmpwriteprotect = bits(r, 12, 12);
- c->fileformat = bits(r, 11, 10);
-
- return 0;
-}
-
-static char*
-csdstr(char *p, char *e, Csd *c)
-{
- char versbuf[128];
-
- versbuf[0] = '\0';
- if(c->version == 0)
- snprint(versbuf, sizeof versbuf,
- "vddrmin %x\n"
- "vddrmax %x\n"
- "vddwmin %x\n"
- "vddwmax %x\n"
- "sizemult %x\n",
- c->v0.vddrmin,
- c->v0.vddrmax,
- c->v0.vddwmin,
- c->v0.vddwmax,
- c->v0.sizemult);
- return seprint(p, e,
- "version %x\n"
- "taac %x\n"
- "nsac %x\n"
- "xferspeed %x\n"
- "cmdclasses %x\n"
- "readblocklength %x\n"
- "readblockpartial %x\n"
- "writeblockmisalign %x\n"
- "readblockmisalign %x\n"
- "dsr %x\n"
- "devsize %x\n"
- "%s"
- "eraseblockenable %x\n"
- "erasesectorsize %x\n"
- "wpgroupsize %x\n"
- "wpgroupenable %x\n"
- "writespeedfactor %x\n"
- "writeblocklength %x\n"
- "writeblockpartial %x\n"
- "fileformatgroup %x\n"
- "copy %x\n"
- "permwriteprotect %x\n"
- "tmpwriteprotect %x\n"
- "fileformat %x\n",
- c->version,
- c->taac,
- c->nsac,
- c->xferspeed,
- c->cmdclasses,
- c->readblocklength,
- c->readblockpartial,
- c->writeblockmisalign,
- c->readblockmisalign,
- c->dsr,
- c->size,
- versbuf,
- c->eraseblockenable,
- c->erasesectorsize,
- c->wpgroupsize,
- c->wpgroupenable,
- c->writespeedfactor,
- c->writeblocklength,
- c->writeblockpartial,
- c->fileformatgroup,
- c->copy,
- c->permwriteprotect,
- c->tmpwriteprotect,
- c->fileformat);
-}
-
-static char*
-cardtype(Card *c)
-{
- if(c->mmc)
- return "mmc";
- if(c->sdhc)
- return "sdhc";
- return "sd";
-}
-
-static char*
-cardstr(Card *c, char *buf, int n)
-{
- snprint(buf, n,
- "card %s\n"
- "type %s\n"
- "size %lld bytes\n"
- "blocksize %lud\n"
- "manufactured %d-%02d\n"
- "rev %#ux\n"
- "serial %#lux\n",
- c->cid.prodname,
- cardtype(c),
- c->size,
- c->bs,
- c->cid.year, c->cid.mon,
- c->cid.rev,
- c->cid.serial);
- return buf;
-}

static void
sdinit(void)
=======================================
--- /fns.h Tue Mar 16 10:55:21 2010
+++ /fns.h Wed Mar 17 05:01:18 2010
@@ -33,6 +33,7 @@
void links(void);
void microdelay(int us);
int pcmspecial(char *, ISAConf *);
+void regreadl(ulong *);
void screeninit(void);
void trapinit(void);
void uartconsole(void);
@@ -92,4 +93,3 @@
void mvfeatset(ulong);

int segflush(void*, ulong);
-
=======================================
--- /sheeva Mon Mar 15 06:57:05 2010
+++ /sheeva Wed Mar 17 05:01:18 2010
@@ -18,7 +18,7 @@
boot
flash
ftl
- sdio
+ sdio sdcard
sheeva
efuse
sata

==============================================================================
Revision: 51c19b3059
Author: Mechiel Lukkien <mec...@ueber.net>
Date: Wed Mar 17 09:41:13 2010
Log: improve devsdio.c, i've briefly ran kfs on it.

this makes writing work. the magic bit that set "start writing
data to sd card after it responded to the write request" has been
found.

this also changes many cosmetic things, so this commit is a bit
messy... more to come!
http://code.google.com/p/inferno-kirkwood/source/detail?r=51c19b3059

Modified:
/devsdio.c
/io.h
/sheeva

=======================================
--- /devsdio.c Wed Mar 17 05:01:18 2010
+++ /devsdio.c Wed Mar 17 09:41:13 2010
@@ -7,8 +7,8 @@
#include "io.h"
#include "sdcard.h"

-static int debug = 0;
-#define dprint if(debug)print
+#define DEBUG 0
+#define dprint if(DEBUG)print

char Enocard[] = "no card";

@@ -21,9 +21,10 @@

enum {
/* transfer mode */
- TMautocmd12 = 1<<2,
- TMxfertohost = 1<<4,
- TMswwrite = 1<<6,
+ TMdatawrite = 1<<1, /* write data after response, for write commands */
+ TMautocmd12 = 1<<2, /* hardware sends cmd12 (note: doc contradicts
itself) */
+ TMxfertohost = 1<<4, /* data flows from sd to host */
+ TMswwrite = 1<<6, /* software-controlled, not dma */

/* cmd */
#define CMDresp(x) ((x)<<0)
@@ -34,12 +35,12 @@

CMDdatacrccheck = 1<<2,
CMDcmdcrccheck = 1<<3,
- CMDcmdindexcheck = 1<<4,
+ CMDcmdindexcheck= 1<<4,
CMDdatapresent = 1<<5,
CMDunexpresp = 1<<7,
#define CMDcmd(x) ((x)<<8)

- /* hwstate */
+ /* hoststate */
HScmdinhibit = 1<<0,
HScardbusy = 1<<1,
HStxactive = 1<<8,
@@ -65,7 +66,7 @@
/* swreset */
SRresetall = 1<<8,

- /* status */
+ /* st, status */
NScmdcomplete = 1<<0,
NSxfercomplete = 1<<1,
NSblockgapevent = 1<<2,
@@ -81,7 +82,7 @@
NSunexpresp = 1<<14,
NSerror = 1<<15,

- /* errstatus */
+ /* est, error status */
EScmdtimeout = 1<<0,
EScmdcrc = 1<<1,
EScmdendbit = 1<<2,
@@ -103,6 +104,14 @@
#define AICMDINDEX(x) ((x)<<8)
};

+enum {
+ /* sd commands */
+ CMDRead = 17,
+ CMDReadmulti = 18,
+ CMDWrite = 24,
+ CMDWritemulti = 25,
+};
+
enum {
CMD8pattern = 0xaa,
CMD8patternmask = MASK(8),
@@ -133,14 +142,16 @@
Qctl,
Qinfo,
Qdata,
+ Qstatus,
};

static
-Dirtab sdiotab[]={
+Dirtab sdiotab[] = {
".", {Qdir, 0, QTDIR}, 0, 0555,
"sdioctl", {Qctl}, 0, 0666,
"sdioinfo", {Qinfo}, 0, 0444,
"sdio", {Qdata}, 0, 0666,
+ "sdiostatus", {Qstatus}, 0, 0444,
};

static void
@@ -232,7 +243,7 @@
return p;
}

-char *acmd12errstatusstrs[] = {
+char *acmd12ststrs[] = {
"acmd12notexe",
"acmd12timeout",
"acmd12crcerr",
@@ -243,31 +254,31 @@
};

static char *
-acmd12errstatusstr(char *p, char *e, ulong v)
+acmd12ststr(char *p, char *e, ulong v)
{
int i;
- for(i = 0; i < nelem(acmd12errstatusstrs); i++)
+ for(i = 0; i < nelem(acmd12ststrs); i++)
if(v & (1<<i))
- p = seprint(p, e, " %q", acmd12errstatusstrs[i]);
+ p = seprint(p, e, " %q", acmd12ststrs[i]);
return p;
}

static void
-printstatus(char *s, ulong status, ulong errstatus, ulong acmd12errstatus)
+printstatus(char *s, ulong st, ulong est, ulong acmd12st)
{
char *p, *e;

- if(!debug)
+ if(!DEBUG)
return;

p = up->genbuf;
e = p+sizeof (up->genbuf);

- p = statusstr(p, e, status);
+ p = statusstr(p, e, st);
p = seprint(p, e, ";");
- p = errstatusstr(p, e, errstatus);
+ p = errstatusstr(p, e, est);
p = seprint(p, e, ";");
- p = acmd12errstatusstr(p, e, acmd12errstatus);
+ p = acmd12ststr(p, e, acmd12st);
USED(p);

print("status: %s%s\n", s, up->genbuf);
@@ -299,28 +310,29 @@
static int
dmafinished(void*)
{
+ SdioReg *r = SDIOREG;
ulong need = NScmdcomplete|NSdmaintr;

- if((SDIOREG->status & need) == need) {
+ if((r->st & need) == need) {
dprint("dmadone\n");
return 1;
}
dprint("not dmadone\n");
- SDIOREG->statusirqmask = NSdmaintr;
+ r->stirq = NSdmaintr;
return 0;
}

static int
sdcmd0(Card *c, int isapp, ulong cmd, ulong arg)
{
- SdioReg *reg = SDIOREG;
+ SdioReg *r = SDIOREG;
int i, s;
- ulong resptype, cmdopts, txmode, v, need;
+ ulong resptype, cmdopts, mode, v, need;
uvlong w;

i = 0;
for(;;) {
- if((reg->hwstate & (HScmdinhibit|HScardbusy)) == 0)
+ if((r->hoststate & (HScmdinhibit|HScardbusy)) == 0)
break;
if(i++ >= 50)
return SDCardbusy;
@@ -334,49 +346,69 @@
dprint("sdcmd, isapp %d, cmd %lud, arg %#lux\n", isapp, cmd, arg);

/* clear status */
- reg->status = ~0;
- reg->errstatus = ~0;
- reg->acmd12errstatus = ~0;
- printstatus("before cmd: ", reg->status, reg->errstatus,
reg->acmd12errstatus);
+ r->st = ~0;
+ r->est = ~0;
+ r->acmd12st = ~0;
+ printstatus("before cmd: ", r->st, r->est, r->acmd12st);

microdelay(1000);
/* prepare args & execute command */
- reg->argcmdlo = (arg>>0) & MASK(16);
- reg->argcmdhi = (arg>>16) & MASK(16);
+ r->arglo = (arg>>0) & MASK(16);
+ r->arghi = (arg>>16) & MASK(16);
cmdopts = 0;
- txmode = 0;
- if(cmd == 17 || cmd == 18) {
- txmode = TMxfertohost;
- if(cmd == 18) {
- txmode |= TMautocmd12;
- reg->acmd12arglo = 0;
- reg->acmd12arghi = 0;
- reg->acmd12idx = AIcheckbusy|AIcheckindex|AICMDINDEX(12);
- }
+ mode = 0;
+ switch(cmd) {
+ case CMDRead:
+ case CMDReadmulti:
+ mode |= TMxfertohost;
+ /* fallthrough */
+ case CMDWrite:
+ case CMDWritemulti:
cmdopts = CMDdatapresent;
}
- reg->txmode = txmode;
+
+ switch(cmd) {
+ case CMDWrite:
+ case CMDWritemulti:
+ mode |= TMdatawrite;
+ }
+
+ switch(cmd) {
+ case CMDReadmulti:
+ case CMDWritemulti:
+ mode |= TMautocmd12;
+ r->acmd12arglo = 0;
+ r->acmd12arghi = 0;
+ r->acmd12idx = AIcheckbusy|AIcheckindex|AICMDINDEX(12);
+ }
+ r->mode = mode;
resptype = getresptype(isapp, cmd);
- reg->cmd = CMDresp(resptype)|cmdopts|CMDcmd(cmd);
-
- if(cmd == 17 || cmd == 18) {
+ r->cmd = CMDresp(resptype)|cmdopts|CMDcmd(cmd);
+
+ switch(cmd) {
+ case CMDRead:
+ case CMDReadmulti:
+ case CMDWrite:
+ case CMDWritemulti:
/* wait for dma interrupt that signals completion */
tsleep(&dmar, dmafinished, nil, 5000);

need = NScmdcomplete|NSdmaintr;
- if((reg->status & need) != need || (reg->status & (NSerror|
NSunexpresp)) != 0) {
- printstatus("dma err: ", reg->status, reg->errstatus,
reg->acmd12errstatus);
+ if((r->st & need) != need || (r->st & (NSerror|NSunexpresp)) != 0) {
+ printstatus("dma err: ", r->st, r->est, r->acmd12st);
return SDError;
}
- } else {
+ break;
+
+ default:
/* poll for completion/error */
need = NScmdcomplete;
i = 0;
for(;;) {
- v = reg->status;
+ v = r->st;
if(v & (NSerror|NSunexpresp)) {
- printstatus("error: ", v, reg->errstatus, reg->acmd12errstatus);
- if(reg->errstatus & EScmdtimeout)
+ printstatus("error: ", v, r->est, r->acmd12st);
+ if(r->est & EScmdtimeout)
return SDTimeout;
return SDError;
}
@@ -384,13 +416,13 @@
break;
if(i++ >= 100) {
print("command unfinished\n");
- printstatus("timeout: ", v, reg->errstatus, reg->acmd12errstatus);
+ printstatus("timeout: ", v, r->est, r->acmd12st);
return SDError;
}
tsleep(&up->sleep, return0, nil, 10);
}
}
- printstatus("success", reg->status, reg->errstatus, reg->acmd12errstatus);
+ printstatus("success", r->st, r->est, r->acmd12st);

/* fetch the response */
memset(c->resp, 0, sizeof c->resp);
@@ -399,26 +431,26 @@
break;
case CMDresp136:
w = 0;
- w |= (uvlong)reg->resp[7] & MASK(14);
- w |= (uvlong)reg->resp[6]<<(0*16+14);
- w |= (uvlong)reg->resp[5]<<(1*16+14);
- w |= (uvlong)reg->resp[4]<<(2*16+14);
- w |= (uvlong)reg->resp[3]<<(3*16+14);
+ w |= (uvlong)r->resp[7] & MASK(14);
+ w |= (uvlong)r->resp[6]<<(0*16+14);
+ w |= (uvlong)r->resp[5]<<(1*16+14);
+ w |= (uvlong)r->resp[4]<<(2*16+14);
+ w |= (uvlong)r->resp[3]<<(3*16+14);
putle(c->resp+1, w, 8);

w = 0;
- w |= (uvlong)reg->resp[3]>>2;
- w |= (uvlong)reg->resp[2]<<(0*16+14);
- w |= (uvlong)reg->resp[1]<<(1*16+14);
- w |= (uvlong)reg->resp[0]<<(2*16+14);
+ w |= (uvlong)r->resp[3]>>2;
+ w |= (uvlong)r->resp[2]<<(0*16+14);
+ w |= (uvlong)r->resp[1]<<(1*16+14);
+ w |= (uvlong)r->resp[0]<<(2*16+14);
putle(c->resp+1+8, w, 8);
break;
case CMDresp48:
case CMDresp48busy:
w = 0;
- w |= (uvlong)reg->resp[2] & MASK(6);
- w |= (uvlong)reg->resp[1]<<(0*16+6);
- w |= (uvlong)reg->resp[0]<<(1*16+6);
+ w |= (uvlong)r->resp[2] & MASK(6);
+ w |= (uvlong)r->resp[1]<<(0*16+6);
+ w |= (uvlong)r->resp[0]<<(1*16+6);
putle(c->resp+1, w, 4);
break;
}
@@ -448,10 +480,10 @@
{
int i, s;
ulong v;
- SdioReg *reg = SDIOREG;
+ SdioReg *r = SDIOREG;

sdclock(400*1000);
- reg->hostctl &= ~HChighspeed;
+ r->hostctl &= ~HChighspeed;

/* force card to idle state */
if(sdcmd(&card, 0, 0) < 0)
@@ -539,7 +571,7 @@
card.size = card.csd.size+1;
card.size *= 1<<(card.csd.v0.sizemult+2);
card.size *= 1<<card.csd.readblocklength;
- kprint("csd0, block length read/write %d/%d, size %lld bytes,
eraseblock %d\n",
+ print("csd0, block length read/write %d/%d, size %lld bytes,
eraseblock %d\n",
1<<card.csd.readblocklength,
1<<card.csd.writeblocklength,
card.size,
@@ -547,13 +579,13 @@
} else {
card.bs = 512;
card.size = (vlong)(card.csd.size+1)*card.bs*1024;
- kprint("csd1, fixed 512 block length, size %lld bytes, eraseblock fixed
512\n", card.size);
+ print("csd1, fixed 512 block length, size %lld bytes, eraseblock fixed
512\n", card.size);
}

if(card.sdhc) {
dprint("enabling sdhc & setting clock to 50mhz\n");
sdclock(50*1000*1000);
- reg->hostctl |= HChighspeed;
+ r->hostctl |= HChighspeed;
} else {
dprint("leaving sdhc off & setting clock to 25mhz\n");
sdclock(25*1000*1000);
@@ -569,21 +601,19 @@
if(sdcmd(&card, 16, card.bs) < 0)
errorsd("setting block length");

+ sdiotab[Qdata].length = card.size;
card.valid = 1;
- kprint("%s", cardstr(&card, up->genbuf, sizeof (up->genbuf)));
+ print("%s", cardstr(&card, up->genbuf, sizeof (up->genbuf)));
}


static long
sdio(uchar *a, long n, vlong offset, int iswrite)
{
- SdioReg *reg = SDIOREG;
- ulong arg;
-
- if(iswrite)
- error("not yet implemented");
-
- if(!card.valid)
+ SdioReg *r = SDIOREG;
+ ulong cmd, arg;
+
+ if(card.valid == 0)
error(Enocard);

/* xxx we should cover this cases with a buffer, and then use the same
code to allow non-sector-aligned reads? */
@@ -596,10 +626,10 @@
error("not multiple of sector size");

dcwbinv(a, n);
- reg->dmaaddrlo = (ulong)a & MASK(16);
- reg->dmaaddrhi = ((ulong)a>>16) & MASK(16);
- reg->blksize = card.bs;
- reg->blkcount = n/card.bs;
+ r->dmaaddrlo = (ulong)a & MASK(16);
+ r->dmaaddrhi = ((ulong)a>>16) & MASK(16);
+ r->blksize = card.bs;
+ r->blkcount = n/card.bs;
if(card.sdhc)
arg = offset/card.bs;
else
@@ -608,7 +638,8 @@
dprint("sdio, a %#lux, dmaddrlo %#lux dmaadrhi %#lux blksize %lud
blkcount %lud cmdarg %#lux\n",
a, (ulong)a & MASK(16), ((ulong)a>>16) & MASK(16), card.bs, n/card.bs,
arg);
//tsleep(&up->sleep, return0, nil, 250);
- if(sdcmd(&card, 18, arg) < 0)
+ cmd = iswrite ? CMDWritemulti : CMDReadmulti;
+ if(sdcmd(&card, cmd, arg) < 0)
errorsd(iswrite ? "writing" : "reading");

return n;
@@ -617,23 +648,23 @@
static void
sdiointr(Ureg*, void*)
{
- SdioReg *reg = SDIOREG;
+ SdioReg *r = SDIOREG;
char buf[128];
char *p, *e;

- if(debug) {
+ if(DEBUG) {
iprint("sdio intr %lux %lux %lux %lux\n",
- reg->status,
- reg->status & reg->statusirqmask,
- reg->errstatus,
- reg->errstatus & reg->errstatusirqmask);
+ r->st,
+ r->st & r->stirq,
+ r->est,
+ r->est & r->estirq);

p = buf;
e = p+sizeof (buf);

- p = statusstr(p, e, reg->status);
+ p = statusstr(p, e, r->st);
p = seprint(p, e, ";");
- p = errstatusstr(p, e, reg->errstatus);
+ p = errstatusstr(p, e, r->est);
USED(p);

iprint("intr: %s\n", buf);
@@ -645,48 +676,48 @@
* before this interrupt is handled.
*/
wakeup(&dmar);
- reg->statusirqmask &= ~NSdmaintr;
+ r->stirq &= ~NSdmaintr;
intrclear(Irqlo, IRQ0sdio);
}

static void
sdioreset(void)
{
- SdioReg *reg = SDIOREG;
+ SdioReg *r = SDIOREG;

/* disable all interrupts. dma interrupt will be enabled as required.
all bits lead to IRQ0sdio. */
- reg->statusirqmask = 0;
- reg->errstatusirqmask = 0;
+ r->stirq = 0;
+ r->estirq = 0;
intrenable(Irqlo, IRQ0sdio, sdiointr, nil, "sdio");
}

static void
sdioinit(void)
{
- SdioReg *reg = SDIOREG;
+ SdioReg *r = SDIOREG;

card.valid = 0;

/* reset the bus, forcing all cards to idle state */
- reg->swreset = SRresetall;
+ r->swreset = SRresetall;
tsleep(&up->sleep, return0, nil, 50);

sdclock(25*1000*1000);

/* configure host controller */
- reg->hostctl = HCpushpull|HCcardtypememonly|HCbigendian|HCdatawidth4|
HCtimeout(15)|HCtimeoutenable;
+ r->hostctl = HCpushpull|HCcardtypememonly|HCbigendian|HCdatawidth4|
HCtimeout(15)|HCtimeoutenable;

/* clear status */
- reg->status = ~0;
- reg->errstatus = ~0;
+ r->st = ~0;
+ r->est = ~0;

/* enable most status reporting */
- reg->statusmask = ~(NStxready|NSfifo8wavail);
- reg->errstatusmask = ~0;
+ r->stena = ~(NStxready|NSfifo8wavail);
+ r->estena = ~0;

/* disable all interrupts. dma interrupt will be enabled as required.
all bits lead to IRQ0sdio. */
- reg->statusirqmask = 0;
- reg->errstatusirqmask = 0;
+ r->stirq = 0;
+ r->estirq = 0;
}

static Chan*
@@ -723,6 +754,7 @@
sdioread(Chan* c, void* a, long n, vlong offset)
{
char *buf, *p, *e;
+ SdioReg *r = SDIOREG;

switch((ulong)c->qid.path){
case Qdir:
@@ -746,6 +778,33 @@
n = sdio(a, n, offset, 0);
dprint("returning %ld bytes\n", n);
break;
+ case Qstatus:
+ p = buf = smalloc(READSTR);
+ e = p+READSTR;
+
+ p = seprint(p, e, "st: ");
+ p = statusstr(p, e, r->st);
+ p = seprint(p, e, "\nest: ");
+ p = errstatusstr(p, e, r->est);
+ p = seprint(p, e, "\nacmd12st: ");
+ p = acmd12ststr(p, e, r->acmd12st);
+
+ p = seprint(p, e, "\nstena: ");
+ p = statusstr(p, e, r->stena);
+ p = seprint(p, e, "\nestena: ");
+ p = errstatusstr(p, e, r->estena);
+
+ p = seprint(p, e, "\nstirq: ");
+ p = statusstr(p, e, r->stirq);
+ p = seprint(p, e, "\nestirq: ");
+ p = errstatusstr(p, e, r->estirq);
+
+ p = seprint(p, e, "\nhoststate %#lux\n", r->hoststate);
+ USED(p);
+
+ n = readstr(offset, a, n, buf);
+ free(buf);
+ break;
default:
n = 0;
break;
@@ -754,13 +813,13 @@
}

enum {
- CMreset, CMinit, CMdebug,
+ CMreset, CMinit, CMclean,
};
static Cmdtab sdioctl[] =
{
CMreset, "reset", 1,
CMinit, "init", 1,
- CMdebug, "debug", 2,
+ CMclean, "clean", 1,
};

static long
@@ -768,6 +827,7 @@
{
Cmdbuf *cb;
Cmdtab *ct;
+ SdioReg *r = SDIOREG;

switch((ulong)c->qid.path){
case Qctl:
@@ -787,13 +847,11 @@
case CMinit:
sdinit();
break;
- case CMdebug:
- if(strcmp(cb->f[1], "on") == 0)
- debug = 1;
- else if(strcmp(cb->f[1], "off") == 0)
- debug = 0;
- else
- error(Ebadctl);
+ case CMclean:
+ r->st = ~0;
+ r->est = ~0;
+ r->acmd12st = ~0;
+ break;
}
poperror();
free(cb);
=======================================
--- /io.h Tue Mar 16 15:41:07 2010
+++ /io.h Wed Mar 17 09:41:13 2010
@@ -581,26 +581,26 @@
ulong dmaaddrhi;
ulong blksize;
ulong blkcount;
- ulong argcmdlo;
- ulong argcmdhi;
- ulong txmode;
- ulong cmd;
+ ulong arglo;
+ ulong arghi;
+ ulong mode;
+ ulong cmd; /* cmds, write starts transaction */
ulong resp[8];
ulong fifo;
ulong crc7rsp;
- ulong hwstate;
+ ulong hoststate;
ulong pad0;
ulong hostctl;
ulong blkgapctl;
ulong clkctl;
ulong swreset;
- ulong status;
- ulong errstatus;
- ulong statusmask;
- ulong errstatusmask;
- ulong statusirqmask;
- ulong errstatusirqmask;
- ulong acmd12errstatus;
+ ulong st; /* status */
+ ulong est; /* error status */
+ ulong stena; /* status enable */
+ ulong estena; /* error status enable */
+ ulong stirq; /* status irq enable */
+ ulong estirq; /* error status irq enable */
+ ulong acmd12st; /* auto cmd 12 status */
ulong currbyteleft;
ulong currblkleft;
ulong acmd12arglo;
=======================================
--- /sheeva Wed Mar 17 05:01:18 2010
+++ /sheeva Wed Mar 17 09:41:13 2010
@@ -98,6 +98,7 @@
/chan /
/dev /
/dis /
+ /dis/disk /
/env /
/fd /
/keydb /
@@ -160,6 +161,7 @@
/dis/dossrv.dis
/dis/zeros.dis

+ /dis/disk/kfs.dis
/dis/sh/std.dis

/dis/ip/dhcp.dis

Reply all
Reply to author
Forward
0 new messages