浏览代码

Plan 9 from Bell Labs 2010-04-29

David du Colombier 14 年之前
父节点
当前提交
eefd69ef86
共有 7 个文件被更改,包括 170 次插入12 次删除
  1. 2 3
      sys/src/9/kw/archkw.c
  2. 1 1
      sys/src/9/kw/devether.c
  3. 1 1
      sys/src/9/kw/devusb.c
  4. 149 0
      sys/src/9/kw/flashif.h
  5. 5 4
      sys/src/9/kw/mem.h
  6. 1 3
      sys/src/9/kw/mmu.c
  7. 11 0
      sys/src/9/kw/nandecc.h

+ 2 - 3
sys/src/9/kw/archkw.c

@@ -13,6 +13,7 @@
 #include "../port/netif.h"
 #include "etherif.h"
 // #include "../port/flashif.h"
+#include "flashif.h"
 
 #include "arm.h"
 
@@ -471,7 +472,6 @@ archconsole(void)
 //serialputs("uart0 console @ 115200\n", strlen("uart0 console @ 115200\n"));
 }
 
-#ifdef USE_FLASH
 void
 archflashwp(Flash*, int)
 {
@@ -489,9 +489,8 @@ archflashreset(int bank, Flash *f)
 		return -1;
 	f->type = "nand";
 	f->addr = (void*)PHYSNAND;
-	f->size = 0;	/* done by probe */
+	f->size = 0;		/* done by probe */
 	f->width = 1;
 	f->interleave = 0;
 	return 0;
 }
-#endif

+ 1 - 1
sys/src/9/kw/devether.c

@@ -412,7 +412,7 @@ etherreset(void)
 					" addr %#lux", PADDR(ether->mem));
 			if(ether->size)
 				i += snprint(buf+i, sizeof buf - i,
-					" size 0x%luX", ether->size);
+					" size %#luX", ether->size);
 			i += snprint(buf+i, sizeof buf - i,
 				": %2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
 				ether->ea[0], ether->ea[1], ether->ea[2],

+ 1 - 1
sys/src/9/kw/devusb.c

@@ -695,7 +695,7 @@ hciprobe(int cardno, int ctlrno)
 
 	snprint(name, sizeof(name), "usb%s", hcitypes[cardno].type);
 	intrenable(Irqlo, hp->irq, hp->interrupt, hp, name);
-	print("#u/usb/ep%d.0: %s: port 0x%luX irq %d\n",
+	print("#u/usb/ep%d.0: %s: port %#luX irq %d\n",
 		epnb, hcitypes[cardno].type, hp->port, hp->irq);
 	epnb++;
 	return hp;

+ 149 - 0
sys/src/9/kw/flashif.h

@@ -0,0 +1,149 @@
+typedef struct Flash Flash;
+typedef struct Flashchip Flashchip;
+typedef struct Flashpart Flashpart;
+typedef struct Flashregion Flashregion;
+
+/*
+ * logical partitions
+ */
+enum {
+	Maxflashpart = 8
+};
+
+struct Flashpart {
+	char*	name;
+	ulong	start;
+	ulong	end;
+};
+
+enum {
+	Maxflashregion = 4
+};
+
+/*
+ * physical erase block regions
+ */
+struct Flashregion {
+	int	n;		/* number of blocks in region */
+	ulong	start;		/* physical base address (allowing for banks) */
+	ulong	end;
+	ulong	erasesize;
+	ulong	pagesize;	/* if non-0, size of pages within erase block */
+};
+
+/*
+ * one of a set of chips in a given region
+ */
+struct Flashchip {
+	int	nr;
+	Flashregion regions[Maxflashregion];
+
+	uchar	id;		/* flash manufacturer ID */
+	ushort	devid;		/* flash device ID */
+	int	width;		/* bytes per flash line */
+	int	maxwb;		/* max write buffer size */
+	ulong	devsize;	/* physical device size */
+	int	alg;		/* programming algorithm (if CFI) */
+	int	protect;	/* software protection */
+};
+
+/*
+ * structure defining a contiguous region of flash memory
+ */
+struct Flash {
+	QLock;			/* interlock on flash operations */
+	Flash*	next;
+
+	/* following are filled in before calling Flash.reset */
+	char*	type;
+	void*	addr;
+	ulong	size;
+	int	xip;		/* executing in place: don't query */
+	int	(*reset)(Flash*);
+
+	/* following are filled in by the reset routine */
+	int	(*eraseall)(Flash*);
+	int	(*erasezone)(Flash*, Flashregion*, ulong);
+	/* (optional) reads of correct width and alignment */
+	int	(*read)(Flash*, ulong, void*, long);
+	/* writes of correct width and alignment */
+	int	(*write)(Flash*, ulong, void*, long);
+	int	(*suspend)(Flash*);
+	int	(*resume)(Flash*);
+	int	(*attach)(Flash*);
+
+	/* following might be filled in by either archflashreset or reset routine */
+	int	nr;
+	Flashregion regions[Maxflashregion];
+
+	uchar	id;		/* flash manufacturer ID */
+	ushort	devid;		/* flash device ID */
+	int	width;		/* bytes per flash line */
+	int	interleave;	/* addresses are interleaved across set of chips */
+	int	bshift;		/* byte addresses are shifted */
+	ulong	cmask;		/* command mask for interleaving */
+	int	maxwb;		/* max write buffer size */
+	ulong	devsize;	/* physical device size */
+	int	alg;		/* programming algorithm (if CFI) */
+	void*	data;		/* flash type routines' private storage, or nil */
+	Flashpart part[Maxflashpart];	/* logical partitions */
+	int	protect;	/* software protection */
+	char*	sort;		/* "nand", "nor", "serial", nil (unspecified) */
+};
+
+/*
+ * called by link routine of driver for specific flash type: arguments are
+ * conventional name for card type/model, and card driver's reset routine.
+ */
+void	addflashcard(char*, int (*)(Flash*));
+
+/*
+ * called by devflash.c:/^flashreset; if flash exists,
+ * sets type, address, and size in bytes of flash
+ * and returns 0; returns -1 if flash doesn't exist
+ */
+int	archflashreset(int, Flash*);
+
+/*
+ * enable/disable write protect
+ */
+void	archflashwp(Flash*, int);
+
+/*
+ * flash access taking width and interleave into account
+ */
+int	flashget(Flash*, ulong);
+void	flashput(Flash*, ulong, int);
+
+/*
+ * Architecture specific routines for managing nand devices
+ */
+
+/*
+ * do any device spcific initialisation
+ */
+void archnand_init(Flash*);
+
+/*
+ * if claim is 1, claim device exclusively, and enable it (power it up)
+ * if claim is 0, release, and disable it (power it down)
+ * claiming may be as simple as a qlock per device
+ */
+void archnand_claim(Flash*, int claim);
+
+/*
+ * set command latch enable (CLE) and address latch enable (ALE)
+ * appropriately
+ */
+void archnand_setCLEandALE(Flash*, int cle, int ale);
+
+/*
+ * write a sequence of bytes to the device
+ */
+void archnand_write(Flash*, void *buf, int len);
+
+/*
+ * read a sequence of bytes from the device
+ * if buf is 0, throw away the data
+ */
+void archnand_read(Flash*, void *buf, int len);

+ 5 - 4
sys/src/9/kw/mem.h

@@ -127,15 +127,16 @@
  * Physical machine information from here on.
  */
 #define PHYSDRAM	0
+
 /* from 0x80000000 up is uncached by L2 (see archkw.c) */
 #define PHYSCESASRAM	0xc8010000
-#define PHYSNAND	0xd8000000
-#define FLASHSIZE	(128*MiB)
 #define PHYSSPIFLASH	0xe8000000
-#define PHYSBOOTROM	0xffff0000		/* boot rom */
-
 /* this address is configured by u-boot, and is 0xd0000000 at reset */
 #define PHYSIO		0xf1000000		/* internal registers */
 #define PHYSCONS	(PHYSIO + 0x12000)	/* uart */
+#define PHYSNAND	0xf9000000
+#define PHYSBOOTROM	0xffff0000		/* boot rom */
+
+#define FLASHSIZE	(512*MiB)		/* but not addressed linearly */
 
 #define VIRTIO		PHYSIO

+ 1 - 3
sys/src/9/kw/mmu.c

@@ -65,10 +65,8 @@ mmuinit(void)
 	l1 = KADDR(pa);
 
 	/* identity-map nand flash */
-	for (fpa = PHYSNAND; fpa < PHYSNAND + FLASHSIZE; fpa += MiB)
+	for (fpa = PHYSNAND; (fpa >> 24) != 0; fpa += MiB)
 		l1[L1X(fpa)] = fpa|Dom0|L1AP(Krw)|Section;
-	for (fpa = 0xf9000000; fpa < 0xf9000000 + 8*MB; fpa += MiB)
-		l1[L1X(fpa)] = fpa|Dom0|L1AP(Krw)|Section|Cached|Buffered;
 
 	/* identity-map spi flash */
 	for (fpa = PHYSSPIFLASH; fpa < PHYSSPIFLASH + FLASHSIZE; fpa += MiB)

+ 11 - 0
sys/src/9/kw/nandecc.h

@@ -0,0 +1,11 @@
+typedef enum NandEccError {
+	NandEccErrorBad,
+	NandEccErrorGood,
+	NandEccErrorOneBit,
+	NandEccErrorOneBitInEcc,
+} NandEccError;
+
+ulong nandecc(uchar buf[256]);
+NandEccError nandecccorrect(uchar buf[256], ulong calcecc, ulong *storedecc,
+	int reportbad);
+