diff options
Diffstat (limited to 'c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c')
-rw-r--r-- | c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c b/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c deleted file mode 100644 index f68e74a2ac..0000000000 --- a/c/src/lib/libbsp/arm/nds/libfat/source/disc_io/io_efa2.c +++ /dev/null @@ -1,307 +0,0 @@ -/* -io_efa2.c by CyteX - -Based on io_mpfc.c by chishm (Michael Chisholm) - -Hardware Routines for reading the NAND flash located on -EFA2 flash carts - -This software is completely free. No warranty is provided. -If you use it, please give me credit and email me about your -project at cytex <at> gmx <dot> de and do not forget to also -drop chishm <at> hotmail <dot> com a line - - Use with permission by Michael "Chishm" Chisholm -*/ - -#include "io_efa2.h" - -// -// EFA2 register addresses -// - -// RTC registers -#define REG_RTC_CLK (*(vu16*)0x080000c4) -#define REG_RTC_EN (*(vu16*)0x080000c8) - -// "Magic" registers used for unlock/lock sequences -#define REG_EFA2_MAGIC_A (*(vu16*)0x09fe0000) -#define REG_EFA2_MAGIC_B (*(vu16*)0x08000000) -#define REG_EFA2_MAGIC_C (*(vu16*)0x08020000) -#define REG_EFA2_MAGIC_D (*(vu16*)0x08040000) -#define REG_EFA2_MAGIC_E (*(vu16*)0x09fc0000) - -// NAND flash lock/unlock register -#define REG_EFA2_NAND_LOCK (*(vu16*)0x09c40000) -// NAND flash enable register -#define REG_EFA2_NAND_EN (*(vu16*)0x09400000) -// NAND flash command write register -#define REG_EFA2_NAND_CMD (*(vu8*)0x09ffffe2) -// NAND flash address/data write register -#define REG_EFA2_NAND_WR (*(vu8*)0x09ffffe0) -// NAND flash data read register -#define REG_EFA2_NAND_RD (*(vu8*)0x09ffc000) - -// ID of Samsung K9K1G NAND flash chip -#define EFA2_NAND_ID 0xEC79A5C0 - -// first sector of udisk -#define EFA2_UDSK_START 0x40 - -// -// EFA2 access functions -// - -// deactivate RTC ports -static inline void _EFA2_rtc_deactivate(void) { - REG_RTC_EN = 0; -} - -// unlock register access -static void _EFA2_reg_unlock(void) { - REG_EFA2_MAGIC_A = 0x0d200; - REG_EFA2_MAGIC_B = 0x01500; - REG_EFA2_MAGIC_C = 0x0d200; - REG_EFA2_MAGIC_D = 0x01500; -} - -// finish/lock register access -static inline void _EFA2_reg_lock(void) { - REG_EFA2_MAGIC_E = 0x1500; -} - -// global reset/init/enable/unlock ? -static void _EFA2_global_unlock(void) { - _EFA2_reg_unlock(); - *(vu16*)0x09880000 = 0x08000; - _EFA2_reg_lock(); -} - -// global lock, stealth mode -/*static void _EFA2_global_lock(void) { - // quite sure there is such a sequence, but haven't had - // a look for it upto now -}*/ - -// unlock NAND Flash -static void _EFA2_nand_unlock(void) { - _EFA2_reg_unlock(); - REG_EFA2_NAND_LOCK = 0x01500; - _EFA2_reg_lock(); -} - -// lock NAND Flash -static void _EFA2_nand_lock(void) { - _EFA2_reg_unlock(); - REG_EFA2_NAND_LOCK = 0x0d200; - _EFA2_reg_lock(); -} - -// -// Set NAND Flash chip enable and write protection bits ? -// -// val | ~CE | ~WP | -// -----+-----+-----+ -// 0 | 0 | 0 | -// 1 | 1 | 0 | -// 3 | 1 | 1 | -// -----+-----+-----+ -// -static void _EFA2_nand_enable(u16 val) { - _EFA2_reg_unlock(); - REG_EFA2_NAND_EN = val; - _EFA2_reg_lock(); -} - -// -// Perform NAND reset -// NAND has to be unlocked and enabled when called -// -static inline void _EFA2_nand_reset(void) { - REG_EFA2_NAND_CMD = 0xff; // write reset command -} - -// -// Read out NAND ID information, could be used for card detection -// -// | EFA2 1GBit | -// ------------------+------------+ -// maker code | 0xEC | -// device code | 0x79 | -// don't care | 0xA5 | -// multi plane code | 0xC0 | -// ------------------+------------+ -// -static u32 _EFA2_nand_id(void) { - u8 byte; - u32 id; - - _EFA2_nand_unlock(); - _EFA2_nand_enable(1); - - REG_EFA2_NAND_CMD = 0x90; // write id command - REG_EFA2_NAND_WR = 0x00; // (dummy) address cycle - byte = REG_EFA2_NAND_RD; // read maker code - id = byte; - byte = REG_EFA2_NAND_RD; // read device code - id = (id << 8) | byte; - byte = REG_EFA2_NAND_RD; // read don't care - id = (id << 8) | byte; - byte = REG_EFA2_NAND_RD; // read multi plane code - id = (id << 8) | byte; - - _EFA2_nand_enable(0); - _EFA2_nand_lock(); - return (id); -} - -// -// Start of gba_nds_fat block device description -// - -/*----------------------------------------------------------------- -EFA2_clearStatus -Reads and checks NAND status information -bool return OUT: true if NAND is idle ------------------------------------------------------------------*/ -static bool _EFA2_clearStatus (void) -{ - // tbd: currently there is no write support, so always return - // true, there is no possibility for pending operations - return true; -} - -/*----------------------------------------------------------------- -EFA2_isInserted -Checks to see if the NAND chip used by the EFA2 is present -bool return OUT: true if the correct NAND chip is found ------------------------------------------------------------------*/ -static bool _EFA2_isInserted (void) -{ - _EFA2_clearStatus(); - return (_EFA2_nand_id() == EFA2_NAND_ID); -} - -/*----------------------------------------------------------------- -EFA2_readSectors -Read "numSecs" 512 byte sectors starting from "sector" into "buffer" -No error correction, no use of spare cells, no use of R/~B signal -u32 sector IN: number of first 512 byte sector to be read -u32 numSecs IN: number of 512 byte sectors to read, -void* buffer OUT: pointer to 512 byte buffer to store data in -bool return OUT: true if successful ------------------------------------------------------------------*/ -static bool _EFA2_readSectors (u32 sector, u32 numSecs, void* buffer) -{ - int i; - -#ifndef _IO_ALLOW_UNALIGNED - u8 byte; - u16 word; -#endif - - // NAND page 0x40 (EFA2_UDSK_START) contains the MBR of the - // udisk and thus is sector 0. The original EFA2 firmware - // does never look at this, it only watches page 0x60, which - // contains the boot block of the FAT16 partition. That is - // fixed, so the EFA2 udisk must not be reformated, else - // the ARK Octopus and also the original Firmware won't be - // able to access the udisk anymore and I have to write a - // recovery tool. - u32 page = EFA2_UDSK_START + sector; - - // future enhancement: wait for possible write operations to - // be finisched - if (!_EFA2_clearStatus()) return false; - - _EFA2_nand_unlock(); - _EFA2_nand_enable(1); - _EFA2_nand_reset(); - - // set NAND to READ1 operation mode and transfer page address - REG_EFA2_NAND_CMD = 0x00; // write READ1 command - REG_EFA2_NAND_WR = 0x00; // write address [7:0] - REG_EFA2_NAND_WR = (page ) & 0xff; // write address [15:8] - REG_EFA2_NAND_WR = (page >> 8 ) & 0xff; // write address[23:16] - REG_EFA2_NAND_WR = (page >> 16) & 0xff; // write address[26:24] - - // Due to a bug in EFA2 design there is need to waste some cycles - // "by hand" instead the possibility to check the R/~B port of - // the NAND flash via a register. The RTC deactivation is only - // there to make sure the loop won't be optimized by the compiler - for (i=0 ; i < 3 ; i++) _EFA2_rtc_deactivate(); - - while (numSecs--) - { - // read page data -#ifdef _IO_ALLOW_UNALIGNED - // slow byte access to RAM, but works in principle - for (i=0 ; i < 512 ; i++) - ((u8*)buffer)[i] = REG_EFA2_NAND_RD; -#else - // a bit faster, but DMA is not possible - for (i=0 ; i < 256 ; i++) { - byte = REG_EFA2_NAND_RD; // read lo-byte - word = byte; - byte = REG_EFA2_NAND_RD; // read hi-byte - word = word | (byte << 8); - ((u16*)buffer)[i] = word; - } -#endif - } - - _EFA2_nand_enable(0); - _EFA2_nand_lock(); - return true; -} - - -/*----------------------------------------------------------------- -EFA2_writeSectors -Write "numSecs" 512 byte sectors starting at "sector" from "buffer" -u32 sector IN: address of 512 byte sector on card to write -u32 numSecs IN: number of 512 byte sectors to write -1 to 256 sectors can be written, 0 = 256 -void* buffer IN: pointer to 512 byte buffer to read data from -bool return OUT: true if successful ------------------------------------------------------------------*/ -static bool _EFA2_writeSectors (u32 sector, u8 numSecs, void* buffer) -{ - // Upto now I focused on reading NAND, write operations - // will follow - return false; -} - -/*----------------------------------------------------------------- -EFA2_shutdown -unload the EFA2 interface ------------------------------------------------------------------*/ -static bool _EFA2_shutdown(void) -{ - return _EFA2_clearStatus(); -} - -/*----------------------------------------------------------------- -EFA2_startUp -initializes the EFA2 card, returns true if successful, -otherwise returns false ------------------------------------------------------------------*/ -static bool _EFA2_startUp(void) -{ - _EFA2_global_unlock(); - return (_EFA2_nand_id() == EFA2_NAND_ID); -} - -/*----------------------------------------------------------------- -the actual interface structure ------------------------------------------------------------------*/ -const IO_INTERFACE _io_efa2 = { - DEVICE_TYPE_EFA2, - FEATURE_MEDIUM_CANREAD | FEATURE_SLOT_GBA, - (FN_MEDIUM_STARTUP)&_EFA2_startUp, - (FN_MEDIUM_ISINSERTED)&_EFA2_isInserted, - (FN_MEDIUM_READSECTORS)&_EFA2_readSectors, - (FN_MEDIUM_WRITESECTORS)&_EFA2_writeSectors, - (FN_MEDIUM_CLEARSTATUS)&_EFA2_clearStatus, - (FN_MEDIUM_SHUTDOWN)&_EFA2_shutdown -}; |