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; }