forked from len0rd/rockbox
Telechips NAND: split out a couple of small functions to help readability, and add a note about LPT blocks. No functional changes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18440 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
b6058de5f9
commit
e682143af5
1 changed files with 54 additions and 27 deletions
|
|
@ -184,11 +184,7 @@ static void nand_chip_select(int bank)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* NFC chip select */
|
/* NFC chip select */
|
||||||
#ifdef USE_TCC_LPT
|
|
||||||
if (!(bank & 1))
|
|
||||||
#else
|
|
||||||
if (bank & 1)
|
if (bank & 1)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
NFC_CTRL &= ~NFC_CS0;
|
NFC_CTRL &= ~NFC_CS0;
|
||||||
NFC_CTRL |= NFC_CS1;
|
NFC_CTRL |= NFC_CS1;
|
||||||
|
|
@ -524,11 +520,44 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Miscellaneous helper functions */
|
||||||
|
|
||||||
|
static inline char get_segment_type(char* spare_buf)
|
||||||
|
{
|
||||||
|
return spare_buf[OFF_SEGMENT_TYPE];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned short get_log_segment_id(char* spare_buf)
|
||||||
|
{
|
||||||
|
return (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
|
||||||
|
spare_buf[OFF_LOG_SEG_LOBYTE];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned short get_cached_page_id(char* spare_buf)
|
||||||
|
{
|
||||||
|
return (spare_buf[OFF_CACHE_PAGE_HIBYTE] << 8) |
|
||||||
|
spare_buf[OFF_CACHE_PAGE_LOBYTE];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_TCC_LPT
|
#ifdef USE_TCC_LPT
|
||||||
|
|
||||||
/* Reading the LPT from NAND is not yet fully understood. This code is therefore
|
/* Reading the LPT from NAND is not yet fully understood. This code is therefore
|
||||||
not enabled by default, as it gives much worse results than the bank-scanning
|
not enabled by default, as it gives much worse results than the bank-scanning
|
||||||
approach currently used. */
|
approach currently used.
|
||||||
|
|
||||||
|
The LPT is stored in a number of physical segments marked with type 0x12.
|
||||||
|
These are spread non-contiguously across the NAND, and are not stored in
|
||||||
|
sequential order.
|
||||||
|
|
||||||
|
The LPT data is stored in Sector 0 of the first <n> pages of each segment.
|
||||||
|
Each 32-bit value in sequence represents the physical location of a logical
|
||||||
|
segment. This is stored as (physical segment number * bank number).
|
||||||
|
|
||||||
|
NOTE: The bank numbers stored appear to be in reverse order to that required
|
||||||
|
by the nand_chip_select() function. The reason for this anomoly is unknown.
|
||||||
|
*/
|
||||||
|
|
||||||
static void read_lpt_block(int bank, int phys_segment)
|
static void read_lpt_block(int bank, int phys_segment)
|
||||||
{
|
{
|
||||||
|
|
@ -553,6 +582,10 @@ static void read_lpt_block(int bank, int phys_segment)
|
||||||
int first_bank = int_buf[0] / segments_per_bank;
|
int first_bank = int_buf[0] / segments_per_bank;
|
||||||
int first_phys_segment = int_buf[0] % segments_per_bank;
|
int first_phys_segment = int_buf[0] % segments_per_bank;
|
||||||
|
|
||||||
|
/* Reverse the stored bank number */
|
||||||
|
if (total_banks > 1)
|
||||||
|
first_bank = (total_banks-1) - first_bank;
|
||||||
|
|
||||||
unsigned char spare_buf[16];
|
unsigned char spare_buf[16];
|
||||||
|
|
||||||
nand_read_raw(first_bank,
|
nand_read_raw(first_bank,
|
||||||
|
|
@ -560,23 +593,24 @@ static void read_lpt_block(int bank, int phys_segment)
|
||||||
SECTOR_SIZE, /* offset */
|
SECTOR_SIZE, /* offset */
|
||||||
16, spare_buf);
|
16, spare_buf);
|
||||||
|
|
||||||
int first_log_segment = (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
|
int first_log_segment = get_log_segment_id(spare_buf);
|
||||||
spare_buf[OFF_LOG_SEG_LOBYTE];
|
|
||||||
|
|
||||||
lpt_ptr = &lpt_lookup[first_log_segment];
|
lpt_ptr = &lpt_lookup[first_log_segment];
|
||||||
|
|
||||||
#if defined(BOOTLOADER) && 1
|
|
||||||
printf("lpt @ %lx:%lx (ls:%lx)",
|
|
||||||
first_bank, first_phys_segment, first_log_segment);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cont && (i < SECTOR_SIZE/4))
|
while (cont && (i < SECTOR_SIZE/4))
|
||||||
{
|
{
|
||||||
if (int_buf[i] != 0xFFFFFFFF)
|
if (int_buf[i] != 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
lpt_ptr->bank = int_buf[i] / segments_per_bank;
|
int bank = int_buf[i] / segments_per_bank;
|
||||||
lpt_ptr->phys_segment = int_buf[i] % segments_per_bank;
|
int phys_segment = int_buf[i] % segments_per_bank;
|
||||||
|
|
||||||
|
/* Reverse the stored bank number */
|
||||||
|
if (total_banks > 1)
|
||||||
|
bank = (total_banks-1) - bank;
|
||||||
|
|
||||||
|
lpt_ptr->bank = bank;
|
||||||
|
lpt_ptr->phys_segment = phys_segment;
|
||||||
|
|
||||||
lpt_ptr++;
|
lpt_ptr++;
|
||||||
i++;
|
i++;
|
||||||
|
|
@ -612,11 +646,8 @@ static void read_write_cache_segment(int bank, int phys_segment)
|
||||||
SECTOR_SIZE, /* offset to first sector's spare */
|
SECTOR_SIZE, /* offset to first sector's spare */
|
||||||
16, spare_buf);
|
16, spare_buf);
|
||||||
|
|
||||||
cached_page = (spare_buf[OFF_CACHE_PAGE_HIBYTE] << 8) |
|
cached_page = get_cached_page_id(spare_buf);
|
||||||
spare_buf[OFF_CACHE_PAGE_LOBYTE];
|
log_segment = get_log_segment_id(spare_buf);
|
||||||
|
|
||||||
log_segment = (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
|
|
||||||
spare_buf[OFF_LOG_SEG_LOBYTE];
|
|
||||||
|
|
||||||
if (cached_page != 0xFFFF)
|
if (cached_page != 0xFFFF)
|
||||||
{
|
{
|
||||||
|
|
@ -775,7 +806,7 @@ int ata_init(void)
|
||||||
SECTOR_SIZE, /* offset */
|
SECTOR_SIZE, /* offset */
|
||||||
16, spare_buf);
|
16, spare_buf);
|
||||||
|
|
||||||
switch (spare_buf[4]) /* block type */
|
switch (get_segment_type(spare_buf))
|
||||||
{
|
{
|
||||||
#ifdef USE_TCC_LPT
|
#ifdef USE_TCC_LPT
|
||||||
case SEGMENT_MAIN_LPT:
|
case SEGMENT_MAIN_LPT:
|
||||||
|
|
@ -788,9 +819,7 @@ int ata_init(void)
|
||||||
case SEGMENT_MAIN_DATA2:
|
case SEGMENT_MAIN_DATA2:
|
||||||
{
|
{
|
||||||
/* Main data area segment */
|
/* Main data area segment */
|
||||||
unsigned short log_segment
|
unsigned short log_segment = get_log_segment_id(spare_buf);
|
||||||
= (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
|
|
||||||
spare_buf[OFF_LOG_SEG_LOBYTE];
|
|
||||||
|
|
||||||
if (log_segment < MAX_SEGMENTS)
|
if (log_segment < MAX_SEGMENTS)
|
||||||
{
|
{
|
||||||
|
|
@ -822,14 +851,12 @@ int ata_init(void)
|
||||||
SECTOR_SIZE, /* offset */
|
SECTOR_SIZE, /* offset */
|
||||||
16, spare_buf);
|
16, spare_buf);
|
||||||
|
|
||||||
switch (spare_buf[4]) /* block type */
|
switch (get_segment_type(spare_buf)) /* block type */
|
||||||
{
|
{
|
||||||
case SEGMENT_MAIN_DATA1:
|
case SEGMENT_MAIN_DATA1:
|
||||||
{
|
{
|
||||||
/* Main data area segment */
|
/* Main data area segment */
|
||||||
unsigned short log_segment
|
unsigned short log_segment = get_log_segment_id(spare_buf);
|
||||||
= (spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
|
|
||||||
spare_buf[OFF_LOG_SEG_LOBYTE];
|
|
||||||
|
|
||||||
if (log_segment < MAX_SEGMENTS)
|
if (log_segment < MAX_SEGMENTS)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue