[coreboot] r51 - in trunk/filo-0.5: drivers/flash fs i386 include main

svn at coreboot.org svn at coreboot.org
Mon Aug 4 23:13:36 CEST 2008


Author: stepan
Date: 2008-08-04 23:13:36 +0200 (Mon, 04 Aug 2008)
New Revision: 51

Modified:
   trunk/filo-0.5/drivers/flash/lxflash.c
   trunk/filo-0.5/drivers/flash/lxflash.h
   trunk/filo-0.5/fs/blockdev.c
   trunk/filo-0.5/fs/vfs.c
   trunk/filo-0.5/i386/artecboot.c
   trunk/filo-0.5/i386/ldscript
   trunk/filo-0.5/i386/linux_load.c
   trunk/filo-0.5/i386/switch.S
   trunk/filo-0.5/include/fs.h
   trunk/filo-0.5/main/elfload.c
Log:
merge from may 2008 artec branch.


Modified: trunk/filo-0.5/drivers/flash/lxflash.c
===================================================================
--- trunk/filo-0.5/drivers/flash/lxflash.c	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/drivers/flash/lxflash.c	2008-08-04 21:13:36 UTC (rev 51)
@@ -34,7 +34,7 @@
 
 static FLASH_INFO g_flashInfo;		// flash info structure
 static uint32_t	g_deviceID = 0;		// flash memory ID
-static uint32_t	g_chipID = 0;		// chip ID
+static int32_t	g_chipID = -1;		// chip ID
 static uint16_t	g_baseAddr = 0;		// port mapped controller IO base address
 
 static uint8_t g_eccTest[MAX_ECC_SIZE];	// used to retrieve/store ECC
@@ -44,6 +44,8 @@
 static uint8_t g_pageBuf[MAX_PAGE_SIZE];
 static uint8_t *g_pBBT=NULL;
 
+static msr_t g_orig_flsh;
+
 ////////////////////////////////////////////////////////////////////////////////
 // ECC structs and routines
 
@@ -518,71 +520,78 @@
 ////////////////////////////////////////////////////////////////////////////////
 // 
 
+int NAND_close(void)
+{
+	if (g_chipID >= 0)
+		wrmsr(MSR_DIVIL_LBAR_FLSH0 + g_chipID, g_orig_flsh);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// 
+
 int NAND_initChip(int chipNum)
 {
 	msr_t msr;
 
+	if (g_chipID == chipNum) return 0;
+	if (g_chipID != -1) NAND_close();
+	
 	memset(&g_flashInfo, 0, sizeof(g_flashInfo));
 
-	g_chipID = chipNum;
+	g_chipID = -1;
 
 	///////////////////////////////////////////////////////////////////////////////////
 	// init the MSR_DIVIL_BALL_OPTS register, enable flash mode
 	
 	msr = rdmsr(MSR_DIVIL_BALL_OPTS);
-	msr.lo &= ~PIN_OPT_IDE;
-	wrmsr(MSR_DIVIL_BALL_OPTS, msr);
-	msr = rdmsr(MSR_DIVIL_BALL_OPTS);
-	debug("MSR_DIVIL_BALL_OPTS = 0x%08x 0x%08x\n", msr.hi, msr.lo);
-
+	
+	if (msr.lo & PIN_OPT_IDE) {
+		printf("NAND controller not enabled!\n");
+		return -1;
+	}
+	
 	///////////////////////////////////////////////////////////////////////////////////
-	// init the MSR_DIVIL_LBAR_FLSHx register, I/O mapped mode, set base address
+	// init the MSR_DIVIL_LBAR_FLSHx register, I/O mapped mode, set a hardcoded base address
+	// Later we restore initial state
 	
+	g_orig_flsh = rdmsr(MSR_DIVIL_LBAR_FLSH0 + chipNum);
+	if (!(g_orig_flsh.hi & NOR_NAND)) {
+		printf("CS%d set up for NOR, aborting!\n", chipNum);
+		return -1;
+	}
+	
 	msr.hi = SET_FLSH_HIGH;
 	msr.lo = SET_FLSH_LOW;
-	wrmsr(MSR_DIVIL_LBAR_FLSH0 + g_chipID, msr);
+	wrmsr(MSR_DIVIL_LBAR_FLSH0 + chipNum, msr);
 	g_baseAddr = SET_FLSH_LOW;	// set the IO base address
 
 	// read the register back
-	msr = rdmsr(MSR_DIVIL_LBAR_FLSH0 + g_chipID);
-	debug("MSR_DIVIL_LBAR_FLSH%d = 0x%08x 0x%08x\n", (int)g_chipID, msr.hi, msr.lo);
+	msr = rdmsr(MSR_DIVIL_LBAR_FLSH0 + chipNum);
+	debug("MSR_DIVIL_LBAR_FLSH%d = 0x%08x 0x%08x\n", (int)chipNum, msr.hi, msr.lo);
 
-	///////////////////////////////////////////////////////////////////////////////////
-	// init the MSR_NANDF_DATA NAND timing register
-
-	msr.hi = 0;
-	msr.lo = SET_NANDF_DATA_LOW;
-	wrmsr(MSR_NANDF_DATA, msr);
-
-	msr = rdmsr(MSR_NANDF_DATA);
-	debug("MSR_NANDF_DATA = 0x%08x 0x%08x\n", msr.hi, msr.lo);
-
-	///////////////////////////////////////////////////////////////////////////////////
-	// init the MSR_NANDF_CTL NAND timing register
-
-	msr.hi = 0;
-	msr.lo = SET_NANDF_CTL_LOW;
-	wrmsr(MSR_NANDF_CTL, msr);
-
-	msr = rdmsr(MSR_NANDF_CTL);
-	debug("MSR_NANDF_CTL = 0x%08x 0x%08x\n", msr.hi, msr.lo);
-
 	// read out flash chip ID
 	g_deviceID = NAND_readFlashID();
 	
 	switch(g_deviceID)	// allow only known flash chips
 	{
 	case SAMSUNG_NAND_64MB:
-	case SST_NAND_64MB:
-
+	case ST_NAND_64MB:
+		
 		g_flashInfo.numBlocks = 4096;
 		g_flashInfo.pagesPerBlock = 32;
 		g_flashInfo.dataBytesPerPage = 512;
 		g_flashInfo.flashType = FLASH_NAND;
 
 		break;
+
+	case ST_NAND_128MB:
+
+		g_flashInfo.numBlocks = 1024;
+		g_flashInfo.pagesPerBlock = 64;
+		g_flashInfo.dataBytesPerPage = 2048;
+		g_flashInfo.flashType = FLASH_NAND;
 		
-	case SST_NAND_512MB:
+	case ST_NAND_512MB:
 
 		g_flashInfo.numBlocks = 4096;
 		g_flashInfo.pagesPerBlock = 64;
@@ -608,6 +617,8 @@
 	debug("bad block table allocated, size %d\n", g_flashInfo.numBlocks);
 	memset(g_pBBT, BLOCK_UNKNOWN, g_flashInfo.numBlocks);
 
+	g_chipID = chipNum;
+	
 	printf("Geode LX flash driver initialized, device ID 0x%x\n", g_deviceID);
 	debug("FlashChip = 0x%x\n", g_chipID);
 	debug("NumBlocks = 0x%x\n", g_flashInfo.numBlocks);

Modified: trunk/filo-0.5/drivers/flash/lxflash.h
===================================================================
--- trunk/filo-0.5/drivers/flash/lxflash.h	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/drivers/flash/lxflash.h	2008-08-04 21:13:36 UTC (rev 51)
@@ -45,6 +45,7 @@
 #define MSR_DIVIL_LBAR_FLSH1	0x51400011	// Flash Chip Select 1
 #define MSR_DIVIL_LBAR_FLSH2	0x51400012	// Flash Chip Select 2
 #define MSR_DIVIL_LBAR_FLSH3	0x51400013	// Flash Chip Select 3
+#define NOR_NAND				(1UL<<1)	// 1 for NAND, 0 for NOR
 
 #define MSR_DIVIL_BALL_OPTS		0x51400015
 #define PIN_OPT_IDE				(1UL<<0)	// 0 for flash, 1 for IDE
@@ -56,8 +57,6 @@
 
 #define SET_FLSH_HIGH			0x0000FFF3
 #define SET_FLSH_LOW			0x0000C000
-#define SET_NANDF_DATA_LOW		0x01200120
-#define SET_NANDF_CTL_LOW		0x00000120
 
 // ThinCan defaults
 
@@ -138,8 +137,9 @@
 #define FLASH_NAND					1
 
 #define SAMSUNG_NAND_64MB			0xc0a576ec
-#define SST_NAND_64MB				0x76207620
-#define SST_NAND_512MB				0x9580dc20
+#define ST_NAND_64MB				0x76207620
+#define ST_NAND_512MB				0x9580dc20
+#define ST_NAND_128MB				0x1d80f120
 
 #define ERROR_SUCCESS				0
 #define ERROR_BAD_PARAMS			-1

Modified: trunk/filo-0.5/fs/blockdev.c
===================================================================
--- trunk/filo-0.5/fs/blockdev.c	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/fs/blockdev.c	2008-08-04 21:13:36 UTC (rev 51)
@@ -196,7 +196,7 @@
     uint32_t disk_size = 0;
 
     /* Don't re-open the device that's already open */
-    if (strcmp(name, dev_name) == 0) {
+    if (strcmp(name, dev_name) == 0 && dev_type != -1 ) {
 	debug("already open\n");
 	*reopen = 1;
 	return 1;
@@ -207,6 +207,10 @@
 	debug("failed to parse device name: %s\n", name);
 	return 0;
     }
+    
+    /* If we have another dev open, close it first! */
+    if (dev_type != type && dev_type != -1)
+    	devclose();
 
     /* Do simple sanity check first */
     if (offset & DEV_SECTOR_MASK) {
@@ -313,6 +317,17 @@
     return 1;
 }
 
+void devclose(void)
+{
+#ifdef FLASH_DISK
+	/* Try to close NAND if it was left open */
+	if (dev_type == DISK_FLASH)
+		NAND_close();
+#endif
+	
+	dev_type = -1;
+}
+
 /* Read a sector from opened device with simple/stupid buffer cache */
 static void *read_sector(unsigned long sector)
 {

Modified: trunk/filo-0.5/fs/vfs.c
===================================================================
--- trunk/filo-0.5/fs/vfs.c	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/fs/vfs.c	2008-08-04 21:13:36 UTC (rev 51)
@@ -202,5 +202,6 @@
 
 void file_close(void)
 {
+	devclose();
 }
 

Modified: trunk/filo-0.5/i386/artecboot.c
===================================================================
--- trunk/filo-0.5/i386/artecboot.c	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/i386/artecboot.c	2008-08-04 21:13:36 UTC (rev 51)
@@ -53,6 +53,7 @@
 	if(file_read(&bootHdr, sizeof(ARTECBOOT_HEADER)) != sizeof(ARTECBOOT_HEADER))
 	{
 		printf("Boot error: failed reading the boot image header\n");
+		file_close();
 		return LOADER_NOT_SUPPORT;
 	}
 	
@@ -60,6 +61,7 @@
 	if(bootHdr.magicHeader != ARTECBOOT_HEADER_MAGIC)
 	{
 		debug("No Artecboot signature found, aborting\n");
+		file_close();
 		return LOADER_NOT_SUPPORT;
 	}
 
@@ -67,6 +69,7 @@
 	if(bootHdr.bootVersion > CURRENT_VERSION)
 	{
 		printf("Boot error: incompatible version number: %x\n", bootHdr.bootVersion);
+		file_close();
 		return LOADER_NOT_SUPPORT;
 	}
 	
@@ -150,5 +153,6 @@
 		return LOADER_NOT_SUPPORT;
 	}
 	
+	file_close();
 	return 0;
 }

Modified: trunk/filo-0.5/i386/ldscript
===================================================================
--- trunk/filo-0.5/i386/ldscript	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/i386/ldscript	2008-08-04 21:13:36 UTC (rev 51)
@@ -6,9 +6,12 @@
 /* Initial load address
  * To be loaded by GRUB, this must be >= 1MB
  */
-BASE_ADDR = 0x100000;
+/* When started from General Software BIOS */
+//BASE_ADDR = 0x40000;
+/* When started from LinuxBIOS */
+BASE_ADDR = 0x100000;          
 
-/* 32KB heap and 16k stack */
+/* 32KB heap and 16KB stack */
 HEAP_SIZE = 32768;
 STACK_SIZE = 16384;
 
@@ -31,6 +34,7 @@
     .note : { *(.note.ELFBoot) }
 
     /* Normal sections */
+    .boot : { *(.boot) *(.boot.*) }
     .text : { *(.text) *(.text.*) }
     .rodata : {
 	. = ALIGN(4);

Modified: trunk/filo-0.5/i386/linux_load.c
===================================================================
--- trunk/filo-0.5/i386/linux_load.c	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/i386/linux_load.c	2008-08-04 21:13:36 UTC (rev 51)
@@ -640,8 +640,10 @@
 	return -1;
 
     kern_addr = load_linux_header(&hdr);
-    if (kern_addr == 0)
-	return LOADER_NOT_SUPPORT;
+    if (kern_addr == 0) {
+    	file_close();
+    	return LOADER_NOT_SUPPORT;
+    }
 
     params = phys_to_virt(LINUX_PARAM_LOC);
     init_linux_params(params, &hdr);
@@ -653,6 +655,7 @@
     if (kern_size == 0) {
 	if (initrd_file)
 	    free(initrd_file);
+	file_close();
 	return -1;
     }
 
@@ -660,10 +663,13 @@
 	if (load_initrd(&hdr, info, kern_addr+kern_size, params, initrd_file)
 		!= 0) {
 	    free(initrd_file);
+	    file_close();
 	    return -1;
 	}
 	free(initrd_file);
     }
+    
+    file_close();
 
     hardware_setup();
 

Modified: trunk/filo-0.5/i386/switch.S
===================================================================
--- trunk/filo-0.5/i386/switch.S	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/i386/switch.S	2008-08-04 21:13:36 UTC (rev 51)
@@ -1,6 +1,6 @@
 	.globl	entry, __switch_context, __exit_context, halt
 
-	.text
+	.section ".boot", "xa"
 	.align	4
 
 /*

Modified: trunk/filo-0.5/include/fs.h
===================================================================
--- trunk/filo-0.5/include/fs.h	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/include/fs.h	2008-08-04 21:13:36 UTC (rev 51)
@@ -22,6 +22,7 @@
 #ifdef FLASH_DISK
 int flash_probe(int drive);
 int flash_read(int drive, sector_t sector, void *buffer);
+int NAND_close(void);
 #endif
 
 #define DISK_IDE 1
@@ -30,6 +31,7 @@
 #define DISK_FLASH 4
 
 int devopen(const char *name, int *reopen);
+void devclose(void);
 int devread(unsigned long sector, unsigned long byte_offset,
 	unsigned long byte_len, void *buf);
 void dev_set_partition(unsigned long start, unsigned long size);

Modified: trunk/filo-0.5/main/elfload.c
===================================================================
--- trunk/filo-0.5/main/elfload.c	2008-08-04 20:19:53 UTC (rev 50)
+++ trunk/filo-0.5/main/elfload.c	2008-08-04 21:13:36 UTC (rev 51)
@@ -345,6 +345,8 @@
 	    goto out;
     }
 
+    file_close();
+    
     boot_notes = build_boot_notes(info, cmdline);
 
 #if PCMCIA_CF
@@ -373,5 +375,6 @@
 	free(image_name);
     if (image_version)
 	free(image_version);
+    file_close();
     return retval;
 }





More information about the coreboot mailing list