mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-09-21 07:01:57 +00:00
* Avoid flicker on the TRAB's VFD by synchronizing the enable with
the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100 boards, version 153 for Rev. 200 boards). * Patch by Vladimir Gurevich, 12 Mar 2003: Fix relocation problem of statically initialized string pointers in common/cmd_pci.c * Patch by Kai-Uwe Blm, 12 Mar 2003: Cleanup & bug fixes for JFFS2 code: - the memory mangement was broken. It caused havoc on malloc by writing beyond the block boundaries. - the length calculation for files was wrong, sometimes resulting in short file reads. - data copying now optionally takes fragment version numbers into account, to avoid copying from older data. See doc/README.JFFS2 for details.
This commit is contained in:
parent
09127c6096
commit
06d01dbe00
22 changed files with 846 additions and 618 deletions
18
CHANGELOG
18
CHANGELOG
|
@ -2,6 +2,24 @@
|
||||||
Changes since U-Boot 0.2.2:
|
Changes since U-Boot 0.2.2:
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
|
* Avoid flicker on the TRAB's VFD by synchronizing the enable with
|
||||||
|
the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100
|
||||||
|
boards, version 153 for Rev. 200 boards).
|
||||||
|
|
||||||
|
* Patch by Vladimir Gurevich, 12 Mar 2003:
|
||||||
|
Fix relocation problem of statically initialized string pointers
|
||||||
|
in common/cmd_pci.c
|
||||||
|
|
||||||
|
* Patch by Kai-Uwe Blöm, 12 Mar 2003:
|
||||||
|
Cleanup & bug fixes for JFFS2 code:
|
||||||
|
- the memory mangement was broken. It caused havoc on malloc by
|
||||||
|
writing beyond the block boundaries.
|
||||||
|
- the length calculation for files was wrong, sometimes resulting
|
||||||
|
in short file reads.
|
||||||
|
- data copying now optionally takes fragment version numbers into
|
||||||
|
account, to avoid copying from older data.
|
||||||
|
See doc/README.JFFS2 for details.
|
||||||
|
|
||||||
* Patch by Josef Wagner, 12 Mar 2003:
|
* Patch by Josef Wagner, 12 Mar 2003:
|
||||||
- 16/32 MB and 50/80 MHz support with auto-detection for IP860
|
- 16/32 MB and 50/80 MHz support with auto-detection for IP860
|
||||||
- ETH05 and BEDBUG support for CU824
|
- ETH05 and BEDBUG support for CU824
|
||||||
|
|
|
@ -38,10 +38,10 @@
|
||||||
|
|
||||||
int misc_init_r(void)
|
int misc_init_r(void)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
uchar *str;
|
uchar *str;
|
||||||
|
|
||||||
/* determine if the software update key is pressed during startup */
|
/* determine if the software update key is pressed during startup */
|
||||||
#if 0
|
|
||||||
/* not ported yet... */
|
/* not ported yet... */
|
||||||
if (GPLR0 & 0x00000800) {
|
if (GPLR0 & 0x00000800) {
|
||||||
printf("using bootcmd_normal (sw-update button not pressed)\n");
|
printf("using bootcmd_normal (sw-update button not pressed)\n");
|
||||||
|
|
|
@ -21,4 +21,8 @@
|
||||||
# MA 02111-1307 USA
|
# MA 02111-1307 USA
|
||||||
#
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# TOP860 board
|
||||||
|
#
|
||||||
|
|
||||||
TEXT_BASE = 0x80000000
|
TEXT_BASE = 0x80000000
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
* The Innokom board has GPIO70 connected to SCLK which can be toggled
|
* The Innokom board has GPIO70 connected to SCLK which can be toggled
|
||||||
* until all chips think that their current cycles are finished.
|
* until all chips think that their current cycles are finished.
|
||||||
*/
|
*/
|
||||||
int i2c_init_board(void)
|
void i2c_init_board(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -53,8 +53,6 @@ int i2c_init_board(void)
|
||||||
}
|
}
|
||||||
/* set gpio pin to input */
|
/* set gpio pin to input */
|
||||||
GPDR(70) &= ~GPIO_bit(70);
|
GPDR(70) &= ~GPIO_bit(70);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <linux/byteorder/swab.h>
|
#include <linux/byteorder/swab.h>
|
||||||
|
|
||||||
|
|
||||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||||
|
|
||||||
/* Board support for 1 or 2 flash devices */
|
/* Board support for 1 or 2 flash devices */
|
||||||
#define FLASH_PORT_WIDTH32
|
#define FLASH_PORT_WIDTH32
|
||||||
|
@ -53,50 +53,47 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||||
* Functions
|
* Functions
|
||||||
*/
|
*/
|
||||||
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
||||||
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
||||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||||
void inline spin_wheel(void);
|
void inline spin_wheel (void);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long flash_init (void)
|
unsigned long flash_init (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
ulong size = 0;
|
ulong size = 0;
|
||||||
|
|
||||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
|
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||||
{
|
switch (i) {
|
||||||
switch (i)
|
case 0:
|
||||||
{
|
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
|
||||||
case 0:
|
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
|
||||||
flash_get_size((FPW *)PHYS_FLASH_1, &flash_info[i]);
|
break;
|
||||||
flash_get_offsets(PHYS_FLASH_1, &flash_info[i]);
|
case 1:
|
||||||
break;
|
flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
|
||||||
case 1:
|
flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
|
||||||
flash_get_size((FPW *)PHYS_FLASH_2, &flash_info[i]);
|
break;
|
||||||
flash_get_offsets(PHYS_FLASH_2, &flash_info[i]);
|
default:
|
||||||
break;
|
panic ("configured to many flash banks!\n");
|
||||||
default:
|
break;
|
||||||
panic("configured to many flash banks!\n");
|
}
|
||||||
break;
|
size += flash_info[i].size;
|
||||||
}
|
}
|
||||||
size += flash_info[i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Protect monitor and environment sectors
|
/* Protect monitor and environment sectors
|
||||||
*/
|
*/
|
||||||
flash_protect(FLAG_PROTECT_SET,
|
flash_protect ( FLAG_PROTECT_SET,
|
||||||
CFG_FLASH_BASE,
|
CFG_FLASH_BASE,
|
||||||
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
|
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
|
||||||
&flash_info[0]);
|
&flash_info[0] );
|
||||||
|
|
||||||
flash_protect(FLAG_PROTECT_SET,
|
flash_protect ( FLAG_PROTECT_SET,
|
||||||
CFG_ENV_ADDR,
|
CFG_ENV_ADDR,
|
||||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
|
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
|
||||||
&flash_info[0]);
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
|
@ -119,39 +116,45 @@ static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
void flash_print_info (flash_info_t *info)
|
void flash_print_info (flash_info_t *info)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (info->flash_id == FLASH_UNKNOWN) {
|
if (info->flash_id == FLASH_UNKNOWN) {
|
||||||
printf ("missing or unknown FLASH type\n");
|
printf ("missing or unknown FLASH type\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (info->flash_id & FLASH_VENDMASK) {
|
switch (info->flash_id & FLASH_VENDMASK) {
|
||||||
case FLASH_MAN_INTEL: printf ("INTEL "); break;
|
case FLASH_MAN_INTEL:
|
||||||
default: printf ("Unknown Vendor "); break;
|
printf ("INTEL ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf ("Unknown Vendor ");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||||
case FLASH_28F128J3A:
|
case FLASH_28F128J3A:
|
||||||
printf ("28F128J3A\n"); break;
|
printf ("28F128J3A\n");
|
||||||
default: printf ("Unknown Chip Type\n"); break;
|
break;
|
||||||
}
|
default:
|
||||||
|
printf ("Unknown Chip Type\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
printf (" Size: %ld MB in %d Sectors\n",
|
printf (" Size: %ld MB in %d Sectors\n",
|
||||||
info->size >> 20, info->sector_count);
|
info->size >> 20, info->sector_count);
|
||||||
|
|
||||||
printf (" Sector Start Addresses:");
|
printf (" Sector Start Addresses:");
|
||||||
for (i=0; i<info->sector_count; ++i) {
|
for (i = 0; i < info->sector_count; ++i) {
|
||||||
if ((i % 5) == 0)
|
if ((i % 5) == 0)
|
||||||
printf ("\n ");
|
printf ("\n ");
|
||||||
printf (" %08lX%s",
|
printf (" %08lX%s",
|
||||||
info->start[i],
|
info->start[i],
|
||||||
info->protect[i] ? " (RO)" : " "
|
info->protect[i] ? " (RO)" : " ");
|
||||||
);
|
}
|
||||||
}
|
printf ("\n");
|
||||||
printf ("\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,37 +166,37 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||||
volatile FPW value;
|
volatile FPW value;
|
||||||
|
|
||||||
/* Write auto select command: read Manufacturer ID */
|
/* Write auto select command: read Manufacturer ID */
|
||||||
addr[0x5555] = (FPW)0x00AA00AA;
|
addr[0x5555] = (FPW) 0x00AA00AA;
|
||||||
addr[0x2AAA] = (FPW)0x00550055;
|
addr[0x2AAA] = (FPW) 0x00550055;
|
||||||
addr[0x5555] = (FPW)0x00900090;
|
addr[0x5555] = (FPW) 0x00900090;
|
||||||
|
|
||||||
mb();
|
mb ();
|
||||||
value = addr[0];
|
value = addr[0];
|
||||||
|
|
||||||
switch (value) {
|
switch (value) {
|
||||||
|
|
||||||
case (FPW)INTEL_MANUFACT:
|
case (FPW) INTEL_MANUFACT:
|
||||||
info->flash_id = FLASH_MAN_INTEL;
|
info->flash_id = FLASH_MAN_INTEL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
info->flash_id = FLASH_UNKNOWN;
|
info->flash_id = FLASH_UNKNOWN;
|
||||||
info->sector_count = 0;
|
info->sector_count = 0;
|
||||||
info->size = 0;
|
info->size = 0;
|
||||||
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
|
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||||
return (0); /* no or unknown flash */
|
return (0); /* no or unknown flash */
|
||||||
}
|
}
|
||||||
|
|
||||||
mb();
|
mb ();
|
||||||
value = addr[1]; /* device ID */
|
value = addr[1]; /* device ID */
|
||||||
|
|
||||||
switch (value) {
|
switch (value) {
|
||||||
|
|
||||||
case (FPW)INTEL_ID_28F128J3A:
|
case (FPW) INTEL_ID_28F128J3A:
|
||||||
info->flash_id += FLASH_28F128J3A;
|
info->flash_id += FLASH_28F128J3A;
|
||||||
info->sector_count = 128;
|
info->sector_count = 128;
|
||||||
info->size = 0x02000000;
|
info->size = 0x02000000;
|
||||||
break; /* => 16 MB */
|
break; /* => 16 MB */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
info->flash_id = FLASH_UNKNOWN;
|
info->flash_id = FLASH_UNKNOWN;
|
||||||
|
@ -204,9 +207,9 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||||
printf ("** ERROR: sector count %d > max (%d) **\n",
|
printf ("** ERROR: sector count %d > max (%d) **\n",
|
||||||
info->sector_count, CFG_MAX_FLASH_SECT);
|
info->sector_count, CFG_MAX_FLASH_SECT);
|
||||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
|
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||||
|
|
||||||
return (info->size);
|
return (info->size);
|
||||||
}
|
}
|
||||||
|
@ -215,34 +218,34 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||||
{
|
{
|
||||||
int flag, prot, sect;
|
int flag, prot, sect;
|
||||||
ulong type, start, now, last;
|
ulong type, start, last;
|
||||||
int rcode = 0;
|
int rcode = 0;
|
||||||
|
|
||||||
if ((s_first < 0) || (s_first > s_last)) {
|
if ((s_first < 0) || (s_first > s_last)) {
|
||||||
if (info->flash_id == FLASH_UNKNOWN) {
|
if (info->flash_id == FLASH_UNKNOWN) {
|
||||||
printf ("- missing\n");
|
printf ("- missing\n");
|
||||||
} else {
|
} else {
|
||||||
printf ("- no sectors to erase\n");
|
printf ("- no sectors to erase\n");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = (info->flash_id & FLASH_VENDMASK);
|
type = (info->flash_id & FLASH_VENDMASK);
|
||||||
if ((type != FLASH_MAN_INTEL)) {
|
if ((type != FLASH_MAN_INTEL)) {
|
||||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||||
info->flash_id);
|
info->flash_id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
prot = 0;
|
|
||||||
for (sect=s_first; sect<=s_last; ++sect) {
|
|
||||||
if (info->protect[sect]) {
|
|
||||||
prot++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
prot = 0;
|
||||||
|
for (sect = s_first; sect <= s_last; ++sect) {
|
||||||
|
if (info->protect[sect]) {
|
||||||
|
prot++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (prot) {
|
if (prot) {
|
||||||
printf ("- Warning: %d protected sectors will not be erased!\n",
|
printf ("- Warning: %d protected sectors will not be erased!\n",
|
||||||
|
@ -252,42 +255,42 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = get_timer (0);
|
start = get_timer (0);
|
||||||
last = start;
|
last = start;
|
||||||
|
|
||||||
/* Disable interrupts which might cause a timeout here */
|
/* Disable interrupts which might cause a timeout here */
|
||||||
flag = disable_interrupts();
|
flag = disable_interrupts ();
|
||||||
|
|
||||||
/* Start erase on unprotected sectors */
|
/* Start erase on unprotected sectors */
|
||||||
for (sect = s_first; sect<=s_last; sect++) {
|
for (sect = s_first; sect <= s_last; sect++) {
|
||||||
if (info->protect[sect] == 0) { /* not protected */
|
if (info->protect[sect] == 0) { /* not protected */
|
||||||
FPWV *addr = (FPWV *)(info->start[sect]);
|
FPWV *addr = (FPWV *) (info->start[sect]);
|
||||||
FPW status;
|
FPW status;
|
||||||
|
|
||||||
printf("Erasing sector %2d ... ", sect);
|
printf ("Erasing sector %2d ... ", sect);
|
||||||
|
|
||||||
/* arm simple, non interrupt dependent timer */
|
/* arm simple, non interrupt dependent timer */
|
||||||
reset_timer_masked();
|
reset_timer_masked ();
|
||||||
|
|
||||||
*addr = (FPW)0x00500050; /* clear status register */
|
*addr = (FPW) 0x00500050; /* clear status register */
|
||||||
*addr = (FPW)0x00200020; /* erase setup */
|
*addr = (FPW) 0x00200020; /* erase setup */
|
||||||
*addr = (FPW)0x00D000D0; /* erase confirm */
|
*addr = (FPW) 0x00D000D0; /* erase confirm */
|
||||||
|
|
||||||
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
|
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||||
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
|
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
|
||||||
printf ("Timeout\n");
|
printf ("Timeout\n");
|
||||||
*addr = (FPW)0x00B000B0; /* suspend erase */
|
*addr = (FPW) 0x00B000B0; /* suspend erase */
|
||||||
*addr = (FPW)0x00FF00FF; /* reset to read mode */
|
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
|
||||||
rcode = 1;
|
rcode = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*addr = 0x00500050; /* clear status register cmd. */
|
*addr = 0x00500050; /* clear status register cmd. */
|
||||||
*addr = 0x00FF00FF; /* resest to read mode */
|
*addr = 0x00FF00FF; /* resest to read mode */
|
||||||
|
|
||||||
printf (" done\n");
|
printf (" done\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +304,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||||
|
|
||||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||||
{
|
{
|
||||||
ulong cp, wp;
|
ulong cp, wp;
|
||||||
FPW data;
|
FPW data;
|
||||||
int count, i, l, rc, port_width;
|
int count, i, l, rc, port_width;
|
||||||
|
|
||||||
|
@ -317,67 +320,66 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||||
port_width = 4;
|
port_width = 4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle unaligned start bytes
|
* handle unaligned start bytes
|
||||||
*/
|
*/
|
||||||
if ((l = addr - wp) != 0) {
|
if ((l = addr - wp) != 0) {
|
||||||
data = 0;
|
data = 0;
|
||||||
for (i=0, cp=wp; i<l; ++i, ++cp) {
|
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||||
data = (data << 8) | (*(uchar *)cp);
|
data = (data << 8) | (*(uchar *) cp);
|
||||||
}
|
}
|
||||||
for (; i<port_width && cnt>0; ++i) {
|
for (; i < port_width && cnt > 0; ++i) {
|
||||||
data = (data << 8) | *src++;
|
data = (data << 8) | *src++;
|
||||||
--cnt;
|
--cnt;
|
||||||
++cp;
|
++cp;
|
||||||
}
|
}
|
||||||
for (; cnt==0 && i<port_width; ++i, ++cp) {
|
for (; cnt == 0 && i < port_width; ++i, ++cp) {
|
||||||
data = (data << 8) | (*(uchar *)cp);
|
data = (data << 8) | (*(uchar *) cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
|
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
wp += port_width;
|
wp += port_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle word aligned part
|
* handle word aligned part
|
||||||
*/
|
*/
|
||||||
count = 0;
|
count = 0;
|
||||||
while (cnt >= port_width) {
|
while (cnt >= port_width) {
|
||||||
data = 0;
|
data = 0;
|
||||||
for (i=0; i<port_width; ++i) {
|
for (i = 0; i < port_width; ++i) {
|
||||||
data = (data << 8) | *src++;
|
data = (data << 8) | *src++;
|
||||||
}
|
}
|
||||||
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
|
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
wp += port_width;
|
wp += port_width;
|
||||||
cnt -= port_width;
|
cnt -= port_width;
|
||||||
if (count++ > 0x800)
|
if (count++ > 0x800) {
|
||||||
{
|
spin_wheel ();
|
||||||
spin_wheel();
|
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cnt == 0) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* handle unaligned tail bytes
|
|
||||||
*/
|
|
||||||
data = 0;
|
|
||||||
for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) {
|
|
||||||
data = (data << 8) | *src++;
|
|
||||||
--cnt;
|
|
||||||
}
|
|
||||||
for (; i<port_width; ++i, ++cp) {
|
|
||||||
data = (data << 8) | (*(uchar *)cp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (write_data(info, wp, SWAP(data)));
|
if (cnt == 0) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handle unaligned tail bytes
|
||||||
|
*/
|
||||||
|
data = 0;
|
||||||
|
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
|
||||||
|
data = (data << 8) | *src++;
|
||||||
|
--cnt;
|
||||||
|
}
|
||||||
|
for (; i < port_width; ++i, ++cp) {
|
||||||
|
data = (data << 8) | (*(uchar *) cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (write_data (info, wp, SWAP (data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
|
@ -388,45 +390,42 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||||
*/
|
*/
|
||||||
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
||||||
{
|
{
|
||||||
FPWV *addr = (FPWV *)dest;
|
FPWV *addr = (FPWV *) dest;
|
||||||
ulong status;
|
ulong status;
|
||||||
ulong start;
|
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
/* Check if Flash is (sufficiently) erased */
|
/* Check if Flash is (sufficiently) erased */
|
||||||
if ((*addr & data) != data) {
|
if ((*addr & data) != data) {
|
||||||
printf("not erased at %08lx (%x)\n",(ulong)addr,*addr);
|
printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
|
||||||
return (2);
|
return (2);
|
||||||
}
|
}
|
||||||
/* Disable interrupts which might cause a timeout here */
|
/* Disable interrupts which might cause a timeout here */
|
||||||
flag = disable_interrupts();
|
flag = disable_interrupts ();
|
||||||
|
|
||||||
*addr = (FPW)0x00400040; /* write setup */
|
*addr = (FPW) 0x00400040; /* write setup */
|
||||||
*addr = data;
|
*addr = data;
|
||||||
|
|
||||||
/* arm simple, non interrupt dependent timer */
|
/* arm simple, non interrupt dependent timer */
|
||||||
reset_timer_masked();
|
reset_timer_masked ();
|
||||||
|
|
||||||
/* wait while polling the status register */
|
/* wait while polling the status register */
|
||||||
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
|
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||||
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
|
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
|
||||||
*addr = (FPW)0x00FF00FF; /* restore read mode */
|
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*addr = (FPW)0x00FF00FF; /* restore read mode */
|
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inline
|
void inline spin_wheel (void)
|
||||||
spin_wheel(void)
|
|
||||||
{
|
{
|
||||||
static int r=0,p=0;
|
static int p = 0;
|
||||||
static char w[] = "\\/-";
|
static char w[] = "\\/-";
|
||||||
|
|
||||||
printf("\010%c", w[p]);
|
printf ("\010%c", w[p]);
|
||||||
(++p == 3) ? (p = 0) : 0;
|
(++p == 3) ? (p = 0) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,9 @@ int mpl_prg(unsigned long src,unsigned long size)
|
||||||
unsigned long start;
|
unsigned long start;
|
||||||
flash_info_t *info;
|
flash_info_t *info;
|
||||||
int i,rc;
|
int i,rc;
|
||||||
|
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
|
||||||
unsigned long *magic = (unsigned long *)src;
|
unsigned long *magic = (unsigned long *)src;
|
||||||
|
#endif
|
||||||
|
|
||||||
info = &flash_info[0];
|
info = &flash_info[0];
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||||
printf("\nplease defined 'ethaddr'\n");
|
printf("\nplease defined 'ethaddr'\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(argv[2], "dump") == 0) {
|
} else if (strcmp(argv[2], "dump") == 0) {
|
||||||
uchar addr, endaddr, csum; ushort data;
|
uchar addr = 0, endaddr, csum; ushort data;
|
||||||
|
|
||||||
printf("Dump of CS8900 config device: ");
|
printf("Dump of CS8900 config device: ");
|
||||||
cs8900_e2prom_read(addr, &data);
|
cs8900_e2prom_read(addr, &data);
|
||||||
|
|
|
@ -183,7 +183,6 @@ static uchar Get_Board_PCB(void)
|
||||||
int checkboard(void)
|
int checkboard(void)
|
||||||
{
|
{
|
||||||
unsigned char s[50];
|
unsigned char s[50];
|
||||||
unsigned char bc, var, rc;
|
|
||||||
int i;
|
int i;
|
||||||
backup_t *b = (backup_t *) s;
|
backup_t *b = (backup_t *) s;
|
||||||
|
|
||||||
|
|
172
board/trab/vfd.c
172
board/trab/vfd.c
|
@ -59,10 +59,24 @@
|
||||||
#define FRAME_BUF_SIZE ((256*4*56)/8)
|
#define FRAME_BUF_SIZE ((256*4*56)/8)
|
||||||
#define frame_buf_offs 4
|
#define frame_buf_offs 4
|
||||||
|
|
||||||
|
/* defines for starting Timer3 as CPLD-Clk */
|
||||||
|
#define START3 (1 << 16)
|
||||||
|
#define UPDATE3 (1 << 17)
|
||||||
|
#define INVERT3 (1 << 18)
|
||||||
|
#define RELOAD3 (1 << 19)
|
||||||
|
|
||||||
|
/* CPLD-Register for controlling vfd-blank-signal */
|
||||||
|
#define VFD_DISABLE (*(volatile uchar *)0x04038000=0x0000)
|
||||||
|
#define VFD_ENABLE (*(volatile uchar *)0x04038000=0x0001)
|
||||||
|
|
||||||
/* Supported VFD Types */
|
/* Supported VFD Types */
|
||||||
#define VFD_TYPE_T119C 1 /* Noritake T119C VFD */
|
#define VFD_TYPE_T119C 1 /* Noritake T119C VFD */
|
||||||
#define VFD_TYPE_MN11236 2
|
#define VFD_TYPE_MN11236 2
|
||||||
|
|
||||||
|
/*#define NEW_CPLD_CLK*/
|
||||||
|
|
||||||
|
int vfd_board_id;
|
||||||
|
|
||||||
/* taken from armboot/common/vfd.c */
|
/* taken from armboot/common/vfd.c */
|
||||||
unsigned long adr_vfd_table[112][18][2][4][2];
|
unsigned long adr_vfd_table[112][18][2][4][2];
|
||||||
unsigned char bit_vfd_table[112][18][2][4][2];
|
unsigned char bit_vfd_table[112][18][2][4][2];
|
||||||
|
@ -80,9 +94,7 @@ void init_grid_ctrl(void)
|
||||||
/*
|
/*
|
||||||
* clear frame buffer (logical clear => set to "black")
|
* clear frame buffer (logical clear => set to "black")
|
||||||
*/
|
*/
|
||||||
memset ((void *)(gd->fb_base),
|
memset ((void *)(gd->fb_base), 0, FRAME_BUF_SIZE);
|
||||||
gd->vfd_inv_data ? 0xFF : 0,
|
|
||||||
FRAME_BUF_SIZE);
|
|
||||||
|
|
||||||
switch (gd->vfd_type) {
|
switch (gd->vfd_type) {
|
||||||
case VFD_TYPE_T119C:
|
case VFD_TYPE_T119C:
|
||||||
|
@ -98,10 +110,7 @@ void init_grid_ctrl(void)
|
||||||
bit_nr = bit % 8;
|
bit_nr = bit % 8;
|
||||||
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
|
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
|
||||||
temp=(*(volatile unsigned char*)(adr));
|
temp=(*(volatile unsigned char*)(adr));
|
||||||
if (gd->vfd_inv_data)
|
temp |= (1<<bit_nr);
|
||||||
temp &= ~(1<<bit_nr);
|
|
||||||
else
|
|
||||||
temp |= (1<<bit_nr);
|
|
||||||
(*(volatile unsigned char*)(adr))=temp;
|
(*(volatile unsigned char*)(adr))=temp;
|
||||||
|
|
||||||
if(grid_cycle<55)
|
if(grid_cycle<55)
|
||||||
|
@ -115,10 +124,7 @@ void init_grid_ctrl(void)
|
||||||
bit_nr = bit%8;
|
bit_nr = bit%8;
|
||||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||||
temp=(*(volatile unsigned char*)(adr));
|
temp=(*(volatile unsigned char*)(adr));
|
||||||
if (gd->vfd_inv_data)
|
temp |= (1<<bit_nr);
|
||||||
temp &= ~(1<<bit_nr);
|
|
||||||
else
|
|
||||||
temp |= (1<<bit_nr);
|
|
||||||
(*(volatile unsigned char*)(adr))=temp;
|
(*(volatile unsigned char*)(adr))=temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,10 +142,7 @@ void init_grid_ctrl(void)
|
||||||
bit_nr = bit % 8;
|
bit_nr = bit % 8;
|
||||||
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
|
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
|
||||||
temp=(*(volatile unsigned char*)(adr));
|
temp=(*(volatile unsigned char*)(adr));
|
||||||
if (gd->vfd_inv_data)
|
temp |= (1<<bit_nr);
|
||||||
temp &= ~(1<<bit_nr);
|
|
||||||
else
|
|
||||||
temp |= (1<<bit_nr);
|
|
||||||
(*(volatile unsigned char*)(adr))=temp;
|
(*(volatile unsigned char*)(adr))=temp;
|
||||||
|
|
||||||
if(grid_cycle<37)
|
if(grid_cycle<37)
|
||||||
|
@ -152,10 +155,7 @@ void init_grid_ctrl(void)
|
||||||
bit_nr = bit%8;
|
bit_nr = bit%8;
|
||||||
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
|
||||||
temp=(*(volatile unsigned char*)(adr));
|
temp=(*(volatile unsigned char*)(adr));
|
||||||
if (gd->vfd_inv_data)
|
temp |= (1<<bit_nr);
|
||||||
temp &= ~(1<<bit_nr);
|
|
||||||
else
|
|
||||||
temp |= (1<<bit_nr);
|
|
||||||
(*(volatile unsigned char*)(adr))=temp;
|
(*(volatile unsigned char*)(adr))=temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ void create_vfd_table(void)
|
||||||
for(entry=0;entry<2;entry++) {
|
for(entry=0;entry<2;entry++) {
|
||||||
unsigned long adr = gd->fb_base;
|
unsigned long adr = gd->fb_base;
|
||||||
unsigned int bit_nr = 0;
|
unsigned int bit_nr = 0;
|
||||||
|
|
||||||
if (vfd_table[x][y][color][display][entry]) {
|
if (vfd_table[x][y][color][display][entry]) {
|
||||||
|
|
||||||
pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
|
pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
|
||||||
|
@ -295,18 +295,11 @@ void set_vfd_pixel(unsigned char x, unsigned char y,
|
||||||
bit_nr = bit_vfd_table[x][y][color][display][0];
|
bit_nr = bit_vfd_table[x][y][color][display][0];
|
||||||
temp=(*(volatile unsigned char*)(adr));
|
temp=(*(volatile unsigned char*)(adr));
|
||||||
|
|
||||||
if (gd->vfd_inv_data) {
|
if (value)
|
||||||
if (value)
|
temp |= (1<<bit_nr);
|
||||||
temp &= ~(1<<bit_nr);
|
else
|
||||||
else
|
temp &= ~(1<<bit_nr);
|
||||||
temp |= (1<<bit_nr);
|
|
||||||
} else {
|
|
||||||
if (value)
|
|
||||||
temp |= (1<<bit_nr);
|
|
||||||
else
|
|
||||||
temp &= ~(1<<bit_nr);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*(volatile unsigned char*)(adr))=temp;
|
(*(volatile unsigned char*)(adr))=temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,22 +356,59 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)
|
||||||
* This function initializes VFD clock that is needed for the CPLD that
|
* This function initializes VFD clock that is needed for the CPLD that
|
||||||
* manages the keyboard.
|
* manages the keyboard.
|
||||||
*/
|
*/
|
||||||
int vfd_init_clocks(void)
|
int vfd_init_clocks (void)
|
||||||
{
|
{
|
||||||
/* Port-Pins als LCD-Ausgang */
|
|
||||||
rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
|
|
||||||
/* Port-Pins als LCD-Ausgang */
|
|
||||||
rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
|
|
||||||
#ifdef CFG_WITH_VFRAME
|
|
||||||
/* mit VFRAME zum Messen */
|
|
||||||
rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rLCDCON2 = 0x000DC000;
|
/* try to determine display type from the value
|
||||||
rLCDCON3 = 0x0051000A;
|
* defined by pull-ups
|
||||||
rLCDCON4 = 0x00000001;
|
*/
|
||||||
rLCDCON5 = 0x00000440;
|
rPCUP = (rPCUP & 0xFFF0); /* activate GPC0...GPC3 pullups */
|
||||||
|
rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
|
||||||
|
udelay (10); /* allow signals to settle */
|
||||||
|
vfd_board_id = (~rPCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
|
||||||
|
|
||||||
|
VFD_DISABLE; /* activate blank for the vfd */
|
||||||
|
|
||||||
|
#define NEW_CPLD_CLK
|
||||||
|
|
||||||
|
#ifdef NEW_CPLD_CLK
|
||||||
|
if (vfd_board_id) {
|
||||||
|
/* If new board revision, then use PWM 3 as cpld-clock */
|
||||||
|
/* Enable 500 Hz timer for fill level sensor to operate properly */
|
||||||
|
/* Configure TOUT3 as functional pin, disable pull-up */
|
||||||
|
rPDCON &= ~0x30000;
|
||||||
|
rPDCON |= 0x20000;
|
||||||
|
rPDUP |= (1 << 8);
|
||||||
|
|
||||||
|
/* Configure the prescaler */
|
||||||
|
rTCFG0 &= ~0xff00;
|
||||||
|
rTCFG0 |= 0x0f00;
|
||||||
|
|
||||||
|
/* Select MUX input (divider) for timer3 (1/16) */
|
||||||
|
rTCFG1 &= ~0xf000;
|
||||||
|
rTCFG1 |= 0x3000;
|
||||||
|
|
||||||
|
/* Enable autoreload and set the counter and compare
|
||||||
|
* registers to values for the 500 Hz clock
|
||||||
|
* (for a given prescaler (15) and divider (16)):
|
||||||
|
* counter = (66000000 / 500) >> 9;
|
||||||
|
*/
|
||||||
|
rTCNTB3 = 0x101;
|
||||||
|
rTCMPB3 = 0x101 / 2;
|
||||||
|
|
||||||
|
/* Start timer */
|
||||||
|
rTCON = (rTCON | UPDATE3 | RELOAD3) & ~INVERT3;
|
||||||
|
rTCON = (rTCON | START3) & ~UPDATE3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* If old board revision, then use vm-signal as cpld-clock */
|
||||||
|
rLCDCON2 = 0x00FFC000;
|
||||||
|
rLCDCON3 = 0x0007FF00;
|
||||||
|
rLCDCON4 = 0x00000000;
|
||||||
|
rLCDCON5 = 0x00000400;
|
||||||
rLCDCON1 = 0x00000B75;
|
rLCDCON1 = 0x00000B75;
|
||||||
|
/* VM (GPD1) is used as clock for the CPLD */
|
||||||
|
rPDCON = (rPDCON & 0xFFFFFFF3) | 0x00000008;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +427,7 @@ int drv_vfd_init(void)
|
||||||
char *tmp;
|
char *tmp;
|
||||||
ulong palette;
|
ulong palette;
|
||||||
static int vfd_init_done = 0;
|
static int vfd_init_done = 0;
|
||||||
int vfd_id;
|
int vfd_inv_data = 0;
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
@ -405,17 +435,9 @@ int drv_vfd_init(void)
|
||||||
return (0);
|
return (0);
|
||||||
vfd_init_done = 1;
|
vfd_init_done = 1;
|
||||||
|
|
||||||
/* try to determine display type from the value
|
debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_board_id);
|
||||||
* defined by pull-ups
|
|
||||||
*/
|
|
||||||
rPCUP = (rPCUP & 0xFFF0); /* activate GPC0...GPC3 pullups */
|
|
||||||
rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
|
|
||||||
udelay(10); /* allow signals to settle */
|
|
||||||
|
|
||||||
vfd_id = (~rPCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
|
switch (vfd_board_id) {
|
||||||
debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_id);
|
|
||||||
|
|
||||||
switch (vfd_id) {
|
|
||||||
case 0: /* board revision < Rev.200 */
|
case 0: /* board revision < Rev.200 */
|
||||||
if ((tmp = getenv ("vfd_type")) == NULL) {
|
if ((tmp = getenv ("vfd_type")) == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -428,19 +450,18 @@ int drv_vfd_init(void)
|
||||||
/* cannot use printf for a warning here */
|
/* cannot use printf for a warning here */
|
||||||
gd->vfd_type = 0; /* unknown */
|
gd->vfd_type = 0; /* unknown */
|
||||||
}
|
}
|
||||||
gd->vfd_inv_data = 0;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: /* default to MN11236, data inverted */
|
default: /* default to MN11236, data inverted */
|
||||||
gd->vfd_type = VFD_TYPE_MN11236;
|
gd->vfd_type = VFD_TYPE_MN11236;
|
||||||
gd->vfd_inv_data = 1;
|
vfd_inv_data = 1;
|
||||||
setenv ("vfd_type", "MN11236");
|
setenv ("vfd_type", "MN11236");
|
||||||
}
|
}
|
||||||
debug ("VFD type: %s%s\n",
|
debug ("VFD type: %s%s\n",
|
||||||
(gd->vfd_type == VFD_TYPE_T119C) ? "T119C" :
|
(gd->vfd_type == VFD_TYPE_T119C) ? "T119C" :
|
||||||
(gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :
|
(gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :
|
||||||
"unknown",
|
"unknown",
|
||||||
gd->vfd_inv_data ? ", inverted data" : "");
|
vfd_inv_data ? ", inverted data" : "");
|
||||||
|
|
||||||
gd->fb_base = gd->fb_base;
|
gd->fb_base = gd->fb_base;
|
||||||
create_vfd_table();
|
create_vfd_table();
|
||||||
|
@ -458,11 +479,33 @@ int drv_vfd_init(void)
|
||||||
* (wrap around)
|
* (wrap around)
|
||||||
* see manual S3C2400
|
* see manual S3C2400
|
||||||
*/
|
*/
|
||||||
|
/* Stopp LCD-Controller */
|
||||||
|
rLCDCON1 = 0x00000000;
|
||||||
/* frame buffer startadr */
|
/* frame buffer startadr */
|
||||||
rLCDSADDR1 = gd->fb_base >> 1;
|
rLCDSADDR1 = gd->fb_base >> 1;
|
||||||
/* frame buffer endadr */
|
/* frame buffer endadr */
|
||||||
rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
|
rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
|
||||||
rLCDSADDR3 = ((256/4));
|
rLCDSADDR3 = ((256/4));
|
||||||
|
rLCDCON2 = 0x000DC000;
|
||||||
|
rLCDCON3 = 0x0051000A;
|
||||||
|
rLCDCON4 = 0x00000001;
|
||||||
|
if (gd->vfd_type && vfd_inv_data)
|
||||||
|
rLCDCON5 = 0x000004C0;
|
||||||
|
else
|
||||||
|
rLCDCON5 = 0x00000440;
|
||||||
|
|
||||||
|
/* Port pins as LCD output */
|
||||||
|
rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
|
||||||
|
rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
|
||||||
|
|
||||||
|
/* Synchronize VFD enable with LCD controller to avoid flicker */
|
||||||
|
rLCDCON1 = 0x00000B75; /* Start LCD-Controller */
|
||||||
|
while((rLCDCON5 & 0x180000)!=0x100000); /* Wait for end of VSYNC */
|
||||||
|
while((rLCDCON5 & 0x060000)!=0x040000); /* Wait for next HSYNC */
|
||||||
|
while((rLCDCON5 & 0x060000)==0x040000);
|
||||||
|
while((rLCDCON5 & 0x060000)!=0x000000);
|
||||||
|
if(gd->vfd_type)
|
||||||
|
VFD_ENABLE;
|
||||||
|
|
||||||
debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
|
debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
|
||||||
debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
|
debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
|
||||||
|
@ -471,6 +514,17 @@ int drv_vfd_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable VFD: should be run before resetting the system:
|
||||||
|
* disable VM, enable pull-up
|
||||||
|
*/
|
||||||
|
void disable_vfd (void)
|
||||||
|
{
|
||||||
|
VFD_DISABLE;
|
||||||
|
rPDCON &= ~0xC;
|
||||||
|
rPDUP &= ~0x2;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* ** ROM capable initialization part - needed to reserve FB memory */
|
/* ** ROM capable initialization part - needed to reserve FB memory */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -115,28 +115,65 @@ void pciinfo(int BusNum, int ShortPCIListing)
|
||||||
|
|
||||||
char* pci_classes_str(u8 class)
|
char* pci_classes_str(u8 class)
|
||||||
{
|
{
|
||||||
static char *pci_classes[] = {
|
switch (class) {
|
||||||
"Build before PCI Rev2.0",
|
case PCI_CLASS_NOT_DEFINED:
|
||||||
"Mass storage controller",
|
return "Build before PCI Rev2.0";
|
||||||
"Network controller ",
|
break;
|
||||||
"Display controller ",
|
case PCI_BASE_CLASS_STORAGE:
|
||||||
"Multimedia device ",
|
return "Mass storage controller";
|
||||||
"Memory controller ",
|
break;
|
||||||
"Bridge device ",
|
case PCI_BASE_CLASS_NETWORK:
|
||||||
"Simple comm. controller",
|
return "Network controller ";
|
||||||
"Base system peripheral ",
|
break;
|
||||||
"Input device ",
|
case PCI_BASE_CLASS_DISPLAY:
|
||||||
"Docking station ",
|
return "Display controller ";
|
||||||
"Processor ",
|
break;
|
||||||
"Serial bus controller ",
|
case PCI_BASE_CLASS_MULTIMEDIA:
|
||||||
"Reserved entry ",
|
return "Multimedia device ";
|
||||||
"Does not fit any class "
|
break;
|
||||||
};
|
case PCI_BASE_CLASS_MEMORY:
|
||||||
|
return "Memory controller ";
|
||||||
if (class < (sizeof pci_classes / sizeof *pci_classes))
|
break;
|
||||||
return pci_classes[(int) class];
|
case PCI_BASE_CLASS_BRIDGE:
|
||||||
|
return "Bridge device ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_COMMUNICATION:
|
||||||
|
return "Simple comm. controller";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_SYSTEM:
|
||||||
|
return "Base system peripheral ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_INPUT:
|
||||||
|
return "Input device ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_DOCKING:
|
||||||
|
return "Docking station ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_PROCESSOR:
|
||||||
|
return "Processor ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_SERIAL:
|
||||||
|
return "Serial bus controller ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_INTELLIGENT:
|
||||||
|
return "Intelligent controller ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_SATELLITE:
|
||||||
|
return "Satellite controller ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_CRYPT:
|
||||||
|
return "Cryptographic device ";
|
||||||
|
break;
|
||||||
|
case PCI_BASE_CLASS_SIGNAL_PROCESSING:
|
||||||
|
return "DSP ";
|
||||||
|
break;
|
||||||
|
case PCI_CLASS_OTHERS:
|
||||||
|
return "Does not fit any class ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return "??? ";
|
return "??? ";
|
||||||
|
break;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -199,9 +199,9 @@ int interrupt_init (void)
|
||||||
/* load value for 10 ms timeout */
|
/* load value for 10 ms timeout */
|
||||||
lastdec = rTCNTB4 = timer_load_val;
|
lastdec = rTCNTB4 = timer_load_val;
|
||||||
/* auto load, manual update of Timer 4 */
|
/* auto load, manual update of Timer 4 */
|
||||||
rTCON = 0x600000;
|
rTCON = (rTCON & ~0x0700000) | 0x600000;
|
||||||
/* auto load, start Timer 4 */
|
/* auto load, start Timer 4 */
|
||||||
rTCON = 0x500000;
|
rTCON = (rTCON & ~0x0700000) | 0x500000;
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -296,8 +296,10 @@ ulong get_tbclk (void)
|
||||||
|
|
||||||
#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
|
#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
|
||||||
tbclk = timer_load_val * 100;
|
tbclk = timer_load_val * 100;
|
||||||
#elif defined(CONFIG_SMDK2410)
|
#elif defined(CONFIG_SMDK2410) || defined(CONFIG_VCMA9)
|
||||||
tbclk = CFG_HZ;
|
tbclk = CFG_HZ;
|
||||||
|
#else
|
||||||
|
# error "tbclk not configured"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return tbclk;
|
return tbclk;
|
||||||
|
|
|
@ -446,6 +446,9 @@ fiq:
|
||||||
reset_cpu:
|
reset_cpu:
|
||||||
#ifdef CONFIG_S3C2400
|
#ifdef CONFIG_S3C2400
|
||||||
bl disable_interrupts
|
bl disable_interrupts
|
||||||
|
# ifdef CONFIG_TRAB
|
||||||
|
bl disable_vfd
|
||||||
|
# endif
|
||||||
ldr r1, _rWTCON
|
ldr r1, _rWTCON
|
||||||
ldr r2, _rWTCNT
|
ldr r2, _rWTCNT
|
||||||
/* Disable watchdog */
|
/* Disable watchdog */
|
||||||
|
|
|
@ -9,6 +9,14 @@ fsload - load binary file from a file system image
|
||||||
fsinfo - print information about file systems
|
fsinfo - print information about file systems
|
||||||
ls - list files in a directory
|
ls - list files in a directory
|
||||||
|
|
||||||
|
If you boot from a partition which is mounted writable, and you
|
||||||
|
update your boot environment by replacing single files on that
|
||||||
|
partition, you should also define CFG_JFFS2_SORT_FRAGMENTS. Scanning
|
||||||
|
the JFFS2 filesystem takes *much* longer with this feature, though.
|
||||||
|
Sorting is done while inserting into the fragment list, which is
|
||||||
|
more or less a bubble sort. That algorithm is known to be O(n^2),
|
||||||
|
thus you should really consider if you can avoid it!
|
||||||
|
|
||||||
|
|
||||||
There is two ways for JFFS2 to find the disk. The default way uses
|
There is two ways for JFFS2 to find the disk. The default way uses
|
||||||
the flash_info structure to find the start of a JFFS2 disk (called
|
the flash_info structure to find the start of a JFFS2 disk (called
|
||||||
|
|
|
@ -296,7 +296,7 @@ int cs8900_e2prom_read(unsigned char addr, unsigned short *value)
|
||||||
/* write a 16-bit word into the EEPROM */
|
/* write a 16-bit word into the EEPROM */
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
|
|
||||||
void cs8900_e2prom_write(unsigned char addr, unsigned short value)
|
int cs8900_e2prom_write(unsigned char addr, unsigned short value)
|
||||||
{
|
{
|
||||||
cs8900_e2prom_ready();
|
cs8900_e2prom_ready();
|
||||||
put_reg(PP_EECMD, EEPROM_WRITE_EN);
|
put_reg(PP_EECMD, EEPROM_WRITE_EN);
|
||||||
|
@ -307,7 +307,7 @@ void cs8900_e2prom_write(unsigned char addr, unsigned short value)
|
||||||
put_reg(PP_EECMD, EEPROM_WRITE_DIS);
|
put_reg(PP_EECMD, EEPROM_WRITE_DIS);
|
||||||
cs8900_e2prom_ready();
|
cs8900_e2prom_ready();
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* COMMANDS & CFG_NET */
|
#endif /* COMMANDS & CFG_NET */
|
||||||
|
|
|
@ -253,6 +253,6 @@
|
||||||
#define EEPROM_ERASE_CMD 0x0300
|
#define EEPROM_ERASE_CMD 0x0300
|
||||||
|
|
||||||
extern int cs8900_e2prom_read(uchar, ushort *);
|
extern int cs8900_e2prom_read(uchar, ushort *);
|
||||||
extern void cs8900_e2prom_write(uchar, ushort);
|
extern int cs8900_e2prom_write(uchar, ushort);
|
||||||
|
|
||||||
#endif /* CONFIG_DRIVER_CS8900 */
|
#endif /* CONFIG_DRIVER_CS8900 */
|
||||||
|
|
|
@ -64,10 +64,12 @@ static int GetIICSDA(void)
|
||||||
return (rGPEDAT & 0x8000) >> 15;
|
return (rGPEDAT & 0x8000) >> 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void SetIICSDA(int x)
|
static void SetIICSDA(int x)
|
||||||
{
|
{
|
||||||
rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;
|
rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void SetIICSCL(int x)
|
static void SetIICSCL(int x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
/*
|
/*
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
* Filename: jffs2.c
|
* Filename: jffs2.c
|
||||||
|
@ -75,6 +76,42 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bugfixing by Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>, (C) Mar/2003
|
||||||
|
*
|
||||||
|
* - overhaul of the memory management. Removed much of the "paper-bagging"
|
||||||
|
* in that part of the code, fixed several bugs, now frees memory when
|
||||||
|
* partition is changed.
|
||||||
|
* It's still ugly :-(
|
||||||
|
* - fixed a bug in jffs2_1pass_read_inode where the file length calculation
|
||||||
|
* was incorrect. Removed a bit of the paper-bagging as well.
|
||||||
|
* - removed double crc calculation for fragment headers in jffs2_private.h
|
||||||
|
* for speedup.
|
||||||
|
* - scan_empty rewritten in a more "standard" manner (non-paperbag, that is).
|
||||||
|
* - spinning wheel now spins depending on how much memory has been scanned
|
||||||
|
* - lots of small changes all over the place to "improve" readability.
|
||||||
|
* - implemented fragment sorting to ensure that the newest data is copied
|
||||||
|
* if there are multiple copies of fragments for a certain file offset.
|
||||||
|
*
|
||||||
|
* The fragment sorting feature must be enabled by CFG_JFFS2_SORT_FRAGMENTS.
|
||||||
|
* Sorting is done while adding fragments to the lists, which is more or less a
|
||||||
|
* bubble sort. This takes a lot of time, and is most probably not an issue if
|
||||||
|
* the boot filesystem is always mounted readonly.
|
||||||
|
*
|
||||||
|
* You should define it if the boot filesystem is mounted writable, and updates
|
||||||
|
* to the boot files are done by copying files to that filesystem.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* There's a big issue left: endianess is completely ignored in this code. Duh!
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* You still should have paper bags at hand :-(. The code lacks more or less
|
||||||
|
* any comment, and is still arcane and difficult to read in places. As this
|
||||||
|
* is incompatible with any new code from the jffs2 maintainers anyway, it
|
||||||
|
* should probably be dumped and replaced by something like jffs2reader!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
@ -88,124 +125,197 @@
|
||||||
|
|
||||||
#include "jffs2_private.h"
|
#include "jffs2_private.h"
|
||||||
|
|
||||||
/* Compression names */
|
|
||||||
static char *compr_names[] = {
|
|
||||||
"NONE",
|
|
||||||
"ZERO",
|
|
||||||
"RTIME",
|
|
||||||
"RUBINMIPS",
|
|
||||||
"COPY",
|
|
||||||
"DYNRUBIN",
|
|
||||||
"ZLIB" };
|
|
||||||
|
|
||||||
static char spinner[] = { '|', '\\', '-', '/' };
|
#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */
|
||||||
|
#define SPIN_BLKSIZE 18 /* spin after having scanned 1<<BLKSIZE bytes */
|
||||||
|
|
||||||
|
/* Debugging switches */
|
||||||
|
#undef DEBUG_DIRENTS /* print directory entry list after scan */
|
||||||
|
#undef DEBUG_FRAGMENTS /* print fragment list after scan */
|
||||||
|
#undef DEBUG /* enable debugging messages */
|
||||||
|
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define DEBUGF(fmt,args...) printf(fmt ,##args)
|
# define DEBUGF(fmt,args...) printf(fmt ,##args)
|
||||||
#else
|
#else
|
||||||
# define DEBUGF(fmt,args...)
|
# define DEBUGF(fmt,args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MALLOC_CHUNK (10*1024)
|
|
||||||
|
|
||||||
|
/* Compression names */
|
||||||
|
static char *compr_names[] = {
|
||||||
|
"NONE",
|
||||||
|
"ZERO",
|
||||||
|
"RTIME",
|
||||||
|
"RUBINMIPS",
|
||||||
|
"COPY",
|
||||||
|
"DYNRUBIN",
|
||||||
|
"ZLIB"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Spinning wheel */
|
||||||
|
static char spinner[] = { '|', '/', '-', '\\' };
|
||||||
|
|
||||||
|
/* Memory management */
|
||||||
|
struct mem_block {
|
||||||
|
u32 index;
|
||||||
|
struct mem_block *next;
|
||||||
|
struct b_node nodes[NODE_CHUNK];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_nodes(struct b_list *list)
|
||||||
|
{
|
||||||
|
while (list->listMemBase != NULL) {
|
||||||
|
struct mem_block *next = list->listMemBase->next;
|
||||||
|
free( list->listMemBase );
|
||||||
|
list->listMemBase = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct b_node *
|
static struct b_node *
|
||||||
add_node(struct b_node *tail, u32 * count, u32 * memBase)
|
add_node(struct b_list *list)
|
||||||
{
|
{
|
||||||
u32 index;
|
u32 index = 0;
|
||||||
u32 memLimit;
|
struct mem_block *memBase;
|
||||||
struct b_node *b;
|
struct b_node *b;
|
||||||
|
|
||||||
index = (*count) * sizeof(struct b_node) % MALLOC_CHUNK;
|
memBase = list->listMemBase;
|
||||||
memLimit = MALLOC_CHUNK;
|
if (memBase != NULL)
|
||||||
|
index = memBase->index;
|
||||||
#if 0
|
#if 0
|
||||||
putLabeledWord("add_node: index = ", index);
|
putLabeledWord("add_node: index = ", index);
|
||||||
putLabeledWord("add_node: memLimit = ", memLimit);
|
putLabeledWord("add_node: memBase = ", list->listMemBase);
|
||||||
putLabeledWord("add_node: memBase = ", *memBase);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* we need not keep a list of bases since we'll never free the */
|
if (memBase == NULL || index >= NODE_CHUNK) {
|
||||||
/* memory, just jump the the kernel */
|
/* we need more space before we continue */
|
||||||
if ((index == 0) || (index > memLimit)) { /* we need mode space before we continue */
|
memBase = mmalloc(sizeof(struct mem_block));
|
||||||
if ((*memBase = (u32) mmalloc(MALLOC_CHUNK)) == (u32) NULL) {
|
if (memBase == NULL) {
|
||||||
putstr("add_node: malloc failed\n");
|
putstr("add_node: malloc failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memBase->next = list->listMemBase;
|
||||||
|
index = 0;
|
||||||
#if 0
|
#if 0
|
||||||
putLabeledWord("add_node: alloced a new membase at ", *memBase);
|
putLabeledWord("add_node: alloced a new membase at ", *memBase);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
/* now we have room to add it. */
|
/* now we have room to add it. */
|
||||||
b = (struct b_node *) (*memBase + index);
|
b = &memBase->nodes[index];
|
||||||
|
index ++;
|
||||||
|
|
||||||
/* null on first call */
|
memBase->index = index;
|
||||||
if (tail)
|
list->listMemBase = memBase;
|
||||||
tail->next = b;
|
list->listCount++;
|
||||||
|
|
||||||
#if 0
|
|
||||||
putLabeledWord("add_node: tail = ", (u32) tail);
|
|
||||||
if (tail)
|
|
||||||
putLabeledWord("add_node: tail->next = ", (u32) tail->next);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
putLabeledWord("add_node: mb+i = ", (u32) (*memBase + index));
|
|
||||||
putLabeledWord("add_node: b = ", (u32) b);
|
|
||||||
#endif
|
|
||||||
(*count)++;
|
|
||||||
b->next = (struct b_node *) NULL;
|
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we know we have empties at the start offset so we will hop */
|
static struct b_node *
|
||||||
/* t points that would be non F if there were a node here to speed this up. */
|
insert_node(struct b_list *list, u32 offset)
|
||||||
struct jffs2_empty_node {
|
{
|
||||||
u32 first;
|
struct b_node *new;
|
||||||
u32 second;
|
#ifdef CFG_JFFS2_SORT_FRAGMENTS
|
||||||
};
|
struct b_node *b, *prev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(new = add_node(list))) {
|
||||||
|
putstr("add_node failed!\r\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
new->offset = offset;
|
||||||
|
|
||||||
|
#ifdef CFG_JFFS2_SORT_FRAGMENTS
|
||||||
|
if (list->listTail != NULL && list->listCompare(new, list->listTail))
|
||||||
|
prev = list->listTail;
|
||||||
|
else if (list->listLast != NULL && list->listCompare(new, list->listLast))
|
||||||
|
prev = list->listLast;
|
||||||
|
else
|
||||||
|
prev = NULL;
|
||||||
|
|
||||||
|
for (b = (prev ? prev->next : list->listHead);
|
||||||
|
b != NULL && list->listCompare(new, b);
|
||||||
|
prev = b, b = b->next) {
|
||||||
|
list->listLoops++;
|
||||||
|
}
|
||||||
|
if (b != NULL)
|
||||||
|
list->listLast = prev;
|
||||||
|
|
||||||
|
if (b != NULL) {
|
||||||
|
new->next = b;
|
||||||
|
if (prev != NULL)
|
||||||
|
prev->next = new;
|
||||||
|
else
|
||||||
|
list->listHead = new;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
new->next = (struct b_node *) NULL;
|
||||||
|
if (list->listTail != NULL) {
|
||||||
|
list->listTail->next = new;
|
||||||
|
list->listTail = new;
|
||||||
|
} else {
|
||||||
|
list->listTail = list->listHead = new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CFG_JFFS2_SORT_FRAGMENTS
|
||||||
|
static int compare_inodes(struct b_node *new, struct b_node *old)
|
||||||
|
{
|
||||||
|
struct jffs2_raw_inode *jNew = (struct jffs2_raw_inode *)new->offset;
|
||||||
|
struct jffs2_raw_inode *jOld = (struct jffs2_raw_inode *)old->offset;
|
||||||
|
|
||||||
|
return jNew->version < jOld->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compare_dirents(struct b_node *new, struct b_node *old)
|
||||||
|
{
|
||||||
|
struct jffs2_raw_dirent *jNew = (struct jffs2_raw_dirent *)new->offset;
|
||||||
|
struct jffs2_raw_dirent *jOld = (struct jffs2_raw_dirent *)old->offset;
|
||||||
|
|
||||||
|
return jNew->version > jOld->version;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
jffs2_scan_empty(u32 start_offset, struct part_info *part)
|
jffs2_scan_empty(u32 start_offset, struct part_info *part)
|
||||||
{
|
{
|
||||||
u32 max = part->size - sizeof(struct jffs2_raw_inode);
|
char *max = part->offset + part->size - sizeof(struct jffs2_raw_inode);
|
||||||
|
char *offset = part->offset + start_offset;
|
||||||
|
|
||||||
/* this would be either dir node_crc or frag isize */
|
while (offset < max && *(u32 *)offset == 0xFFFFFFFF) {
|
||||||
u32 offset = start_offset + 32;
|
offset += sizeof(u32);
|
||||||
struct jffs2_empty_node *node;
|
/* return if spinning is due */
|
||||||
|
if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break;
|
||||||
start_offset += 4;
|
|
||||||
while (offset < max) {
|
|
||||||
node = (struct jffs2_empty_node *) (part->offset + offset);
|
|
||||||
if ((node->first == 0xFFFFFFFF) && (node->second == 0xFFFFFFFF)) {
|
|
||||||
/* we presume that there were no nodes in between and advance in a hop */
|
|
||||||
/* putLabeledWord("\t\tjffs2_scan_empty: empty at offset=",offset); */
|
|
||||||
start_offset = offset + 4;
|
|
||||||
offset = start_offset + 32; /* orig 32 + 4 bytes for the second==0xfffff */
|
|
||||||
} else {
|
|
||||||
return start_offset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return start_offset;
|
|
||||||
|
return offset - part->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
jffs_init_1pass_list(struct part_info *part)
|
jffs_init_1pass_list(struct part_info *part)
|
||||||
{
|
{
|
||||||
if ( 0 != ( part->jffs2_priv=malloc(sizeof(struct b_lists)))){
|
struct b_lists *pL;
|
||||||
struct b_lists *pL =(struct b_lists *)part->jffs2_priv;
|
|
||||||
|
|
||||||
pL->dirListHead = pL->dirListTail = NULL;
|
if (part->jffs2_priv != NULL) {
|
||||||
pL->fragListHead = pL->fragListTail = NULL;
|
pL = (struct b_lists *)part->jffs2_priv;
|
||||||
pL->dirListCount = 0;
|
free_nodes(&pL->frag);
|
||||||
pL->dirListMemBase = 0;
|
free_nodes(&pL->dir);
|
||||||
pL->fragListCount = 0;
|
free(pL);
|
||||||
pL->fragListMemBase = 0;
|
}
|
||||||
pL->partOffset = 0x0;
|
if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) {
|
||||||
|
pL = (struct b_lists *)part->jffs2_priv;
|
||||||
|
|
||||||
|
memset(pL, 0, sizeof(*pL));
|
||||||
|
#ifdef CFG_JFFS2_SORT_FRAGMENTS
|
||||||
|
pL->dir.listCompare = compare_dirents;
|
||||||
|
pL->frag.listCompare = compare_inodes;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -216,21 +326,18 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
||||||
{
|
{
|
||||||
struct b_node *b;
|
struct b_node *b;
|
||||||
struct jffs2_raw_inode *jNode;
|
struct jffs2_raw_inode *jNode;
|
||||||
u32 totalSize = 1;
|
u32 totalSize = 0;
|
||||||
u32 oldTotalSize = 0;
|
u16 latestVersion = 0;
|
||||||
u32 size = 0;
|
char *lDest;
|
||||||
char *lDest = (char *) dest;
|
|
||||||
char *src;
|
char *src;
|
||||||
long ret;
|
long ret;
|
||||||
int i;
|
int i;
|
||||||
u32 counter = 0;
|
u32 counter = 0;
|
||||||
char totalSizeSet = 0;
|
|
||||||
|
|
||||||
#if 0
|
for (b = pL->frag.listHead; b != NULL; b = b->next) {
|
||||||
b = pL->fragListHead;
|
|
||||||
while (b) {
|
|
||||||
jNode = (struct jffs2_raw_inode *) (b->offset);
|
jNode = (struct jffs2_raw_inode *) (b->offset);
|
||||||
if ((inode == jNode->ino)) {
|
if ((inode == jNode->ino)) {
|
||||||
|
#if 0
|
||||||
putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);
|
putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);
|
||||||
putLabeledWord("read_inode: inode = ", jNode->ino);
|
putLabeledWord("read_inode: inode = ", jNode->ino);
|
||||||
putLabeledWord("read_inode: version = ", jNode->version);
|
putLabeledWord("read_inode: version = ", jNode->version);
|
||||||
|
@ -241,58 +348,26 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
||||||
putLabeledWord("read_inode: compr = ", jNode->compr);
|
putLabeledWord("read_inode: compr = ", jNode->compr);
|
||||||
putLabeledWord("read_inode: usercompr = ", jNode->usercompr);
|
putLabeledWord("read_inode: usercompr = ", jNode->usercompr);
|
||||||
putLabeledWord("read_inode: flags = ", jNode->flags);
|
putLabeledWord("read_inode: flags = ", jNode->flags);
|
||||||
}
|
|
||||||
|
|
||||||
b = b->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
/* get actual file length from the newest node */
|
||||||
#if 1
|
if (jNode->version >= latestVersion) {
|
||||||
b = pL->fragListHead;
|
|
||||||
while (b && (size < totalSize)) {
|
|
||||||
jNode = (struct jffs2_raw_inode *) (b->offset);
|
|
||||||
if ((inode == jNode->ino)) {
|
|
||||||
if ((jNode->isize == oldTotalSize) && (jNode->isize > totalSize)) {
|
|
||||||
/* 2 consecutive isizes indicate file length */
|
|
||||||
totalSize = jNode->isize;
|
totalSize = jNode->isize;
|
||||||
totalSizeSet = 1;
|
latestVersion = jNode->version;
|
||||||
} else if (!totalSizeSet) {
|
|
||||||
totalSize = size + jNode->dsize + 1;
|
|
||||||
}
|
}
|
||||||
oldTotalSize = jNode->isize;
|
|
||||||
|
|
||||||
if(dest) {
|
if(dest) {
|
||||||
src = ((char *) jNode) + sizeof(struct jffs2_raw_inode);
|
src = ((char *) jNode) + sizeof(struct jffs2_raw_inode);
|
||||||
/* lDest = (char *) (dest + (jNode->offset & ~3)); */
|
/* ignore data behind latest known EOF */
|
||||||
|
if (jNode->offset > totalSize)
|
||||||
|
continue;
|
||||||
|
|
||||||
lDest = (char *) (dest + jNode->offset);
|
lDest = (char *) (dest + jNode->offset);
|
||||||
#if 0
|
#if 0
|
||||||
putLabeledWord("\r\n\r\nread_inode: src = ", src);
|
putLabeledWord("read_inode: src = ", src);
|
||||||
putLabeledWord("read_inode: dest = ", lDest);
|
putLabeledWord("read_inode: dest = ", lDest);
|
||||||
putLabeledWord("read_inode: dsize = ", jNode->dsize);
|
|
||||||
putLabeledWord("read_inode: csize = ", jNode->csize);
|
|
||||||
putLabeledWord("read_inode: version = ", jNode->version);
|
|
||||||
putLabeledWord("read_inode: isize = ", jNode->isize);
|
|
||||||
putLabeledWord("read_inode: offset = ", jNode->offset);
|
|
||||||
putLabeledWord("read_inode: compr = ", jNode->compr);
|
|
||||||
putLabeledWord("read_inode: flags = ", jNode->flags);
|
|
||||||
#endif
|
#endif
|
||||||
switch (jNode->compr) {
|
switch (jNode->compr) {
|
||||||
case JFFS2_COMPR_NONE:
|
case JFFS2_COMPR_NONE:
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((dest > 0xc0092ff0) && (dest < 0xc0093000))
|
|
||||||
for (i = 0; i < first->length; i++) {
|
|
||||||
putLabeledWord("\tCOMPR_NONE: src =", src + i);
|
|
||||||
putLabeledWord("\tCOMPR_NONE: length =", first->length);
|
|
||||||
putLabeledWord("\tCOMPR_NONE: dest =", dest + i);
|
|
||||||
putLabeledWord("\tCOMPR_NONE: data =", (unsigned char) *(src + i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = (unsigned long) ldr_memcpy(lDest, src, jNode->dsize);
|
ret = (unsigned long) ldr_memcpy(lDest, src, jNode->dsize);
|
||||||
break;
|
break;
|
||||||
case JFFS2_COMPR_ZERO:
|
case JFFS2_COMPR_ZERO:
|
||||||
|
@ -320,22 +395,18 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size += jNode->dsize;
|
|
||||||
#if 0
|
#if 0
|
||||||
putLabeledWord("read_inode: size = ", size);
|
|
||||||
putLabeledWord("read_inode: totalSize = ", totalSize);
|
putLabeledWord("read_inode: totalSize = ", totalSize);
|
||||||
putLabeledWord("read_inode: compr ret = ", ret);
|
putLabeledWord("read_inode: compr ret = ", ret);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
b = b->next;
|
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
putLabeledWord("read_inode: returning = ", size);
|
putLabeledWord("read_inode: returning = ", totalSize);
|
||||||
#endif
|
#endif
|
||||||
return size;
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the inode from the slashless name given a parent */
|
/* find the inode from the slashless name given a parent */
|
||||||
|
@ -354,18 +425,19 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
/* we need to search all and return the inode with the highest version */
|
/* we need to search all and return the inode with the highest version */
|
||||||
for(b = pL->dirListHead;b;b=b->next,counter++) {
|
for(b = pL->dir.listHead; b; b = b->next, counter++) {
|
||||||
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
||||||
if ((pino == jDir->pino) && (len == jDir->nsize) && (jDir->ino) && /* 0 for unlink */
|
if ((pino == jDir->pino) && (len == jDir->nsize) &&
|
||||||
|
(jDir->ino) && /* 0 for unlink */
|
||||||
(!strncmp(jDir->name, name, len))) { /* a match */
|
(!strncmp(jDir->name, name, len))) { /* a match */
|
||||||
if (jDir->version < version) continue;
|
if (jDir->version < version) continue;
|
||||||
|
|
||||||
if(jDir->version==0) {
|
if(jDir->version == 0) {
|
||||||
/* Is this legal? */
|
/* Is this legal? */
|
||||||
putstr(" ** WARNING ** ");
|
putstr(" ** WARNING ** ");
|
||||||
putnstr(jDir->name, jDir->nsize);
|
putnstr(jDir->name, jDir->nsize);
|
||||||
putstr(" is version 0 (in find, ignoring)\r\n");
|
putstr(" is version 0 (in find, ignoring)\r\n");
|
||||||
} else if(jDir->version==version) {
|
} else if(jDir->version == version) {
|
||||||
/* Im pretty sure this isn't ... */
|
/* Im pretty sure this isn't ... */
|
||||||
putstr(" ** ERROR ** ");
|
putstr(" ** ERROR ** ");
|
||||||
putnstr(jDir->name, jDir->nsize);
|
putnstr(jDir->name, jDir->nsize);
|
||||||
|
@ -389,53 +461,53 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)
|
||||||
|
|
||||||
static char *mkmodestr(unsigned long mode, char *str)
|
static char *mkmodestr(unsigned long mode, char *str)
|
||||||
{
|
{
|
||||||
static const char *l="xwr";
|
static const char *l = "xwr";
|
||||||
int mask=1, i;
|
int mask = 1, i;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
switch (mode & S_IFMT) {
|
switch (mode & S_IFMT) {
|
||||||
case S_IFDIR: str[0]='d'; break;
|
case S_IFDIR: str[0] = 'd'; break;
|
||||||
case S_IFBLK: str[0]='b'; break;
|
case S_IFBLK: str[0] = 'b'; break;
|
||||||
case S_IFCHR: str[0]='c'; break;
|
case S_IFCHR: str[0] = 'c'; break;
|
||||||
case S_IFIFO: str[0]='f'; break;
|
case S_IFIFO: str[0] = 'f'; break;
|
||||||
case S_IFLNK: str[0]='l'; break;
|
case S_IFLNK: str[0] = 'l'; break;
|
||||||
case S_IFSOCK: str[0]='s'; break;
|
case S_IFSOCK: str[0] = 's'; break;
|
||||||
case S_IFREG: str[0]='-'; break;
|
case S_IFREG: str[0] = '-'; break;
|
||||||
default: str[0]='?';
|
default: str[0] = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i<9;i++) {
|
for(i = 0; i < 9; i++) {
|
||||||
c=l[i%3];
|
c = l[i%3];
|
||||||
str[9-i]=(mode & mask)?c:'-';
|
str[9-i] = (mode & mask)?c:'-';
|
||||||
mask=mask<<1;
|
mask = mask<<1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode & S_ISUID) str[3]=(mode & S_IXUSR)?'s':'S';
|
if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S';
|
||||||
if(mode & S_ISGID) str[6]=(mode & S_IXGRP)?'s':'S';
|
if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S';
|
||||||
if(mode & S_ISVTX) str[9]=(mode & S_IXOTH)?'t':'T';
|
if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T';
|
||||||
str[10]='\0';
|
str[10] = '\0';
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dump_stat(struct stat *st, const char *name)
|
static inline void dump_stat(struct stat *st, const char *name)
|
||||||
{
|
{
|
||||||
char str[20];
|
char str[20];
|
||||||
char s[64], *p;
|
char s[64], *p;
|
||||||
|
|
||||||
if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */
|
if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */
|
||||||
st->st_mtime = 1;
|
st->st_mtime = 1;
|
||||||
|
|
||||||
ctime_r(&st->st_mtime, s/*, 64*/); /* newlib ctime doesn't have buflen */
|
ctime_r(&st->st_mtime, s/*,64*/); /* newlib ctime doesn't have buflen */
|
||||||
|
|
||||||
if((p=strchr(s,'\n'))!=NULL) *p='\0';
|
if ((p = strchr(s,'\n')) != NULL) *p = '\0';
|
||||||
if((p=strchr(s,'\r'))!=NULL) *p='\0';
|
if ((p = strchr(s,'\r')) != NULL) *p = '\0';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str),
|
printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str),
|
||||||
st->st_size, s, name);
|
st->st_size, s, name);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name);
|
printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, struct jffs2_raw_inode *i)
|
static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, struct jffs2_raw_inode *i)
|
||||||
|
@ -446,16 +518,16 @@ static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, st
|
||||||
if(!d || !i) return -1;
|
if(!d || !i) return -1;
|
||||||
|
|
||||||
strncpy(fname, d->name, d->nsize);
|
strncpy(fname, d->name, d->nsize);
|
||||||
fname[d->nsize]='\0';
|
fname[d->nsize] = '\0';
|
||||||
|
|
||||||
memset(&st,0,sizeof(st));
|
memset(&st,0,sizeof(st));
|
||||||
|
|
||||||
st.st_mtime=i->mtime;
|
st.st_mtime = i->mtime;
|
||||||
st.st_mode=i->mode;
|
st.st_mode = i->mode;
|
||||||
st.st_ino=i->ino;
|
st.st_ino = i->ino;
|
||||||
|
|
||||||
/* neither dsize nor isize help us.. do it the long way */
|
/* neither dsize nor isize help us.. do it the long way */
|
||||||
st.st_size=jffs2_1pass_read_inode(pL, i->ino, NULL);
|
st.st_size = jffs2_1pass_read_inode(pL, i->ino, NULL);
|
||||||
|
|
||||||
dump_stat(&st, fname);
|
dump_stat(&st, fname);
|
||||||
|
|
||||||
|
@ -477,18 +549,18 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
|
||||||
struct b_node *b;
|
struct b_node *b;
|
||||||
struct jffs2_raw_dirent *jDir;
|
struct jffs2_raw_dirent *jDir;
|
||||||
|
|
||||||
for(b = pL->dirListHead;b;b=b->next) {
|
for (b = pL->dir.listHead; b; b = b->next) {
|
||||||
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
||||||
if ((pino == jDir->pino) && (jDir->ino)) { /* 0 inode for unlink */
|
if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */
|
||||||
u32 i_version=0;
|
u32 i_version = 0;
|
||||||
struct jffs2_raw_inode *jNode, *i=NULL;
|
struct jffs2_raw_inode *jNode, *i = NULL;
|
||||||
struct b_node *b2 = pL->fragListHead;
|
struct b_node *b2 = pL->frag.listHead;
|
||||||
|
|
||||||
while (b2) {
|
while (b2) {
|
||||||
jNode = (struct jffs2_raw_inode *) (b2->offset);
|
jNode = (struct jffs2_raw_inode *) (b2->offset);
|
||||||
if (jNode->ino == jDir->ino
|
if (jNode->ino == jDir->ino
|
||||||
&& jNode->version>=i_version)
|
&& jNode->version >= i_version)
|
||||||
i=jNode;
|
i = jNode;
|
||||||
b2 = b2->next;
|
b2 = b2->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +640,7 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
|
||||||
unsigned char *src;
|
unsigned char *src;
|
||||||
|
|
||||||
/* we need to search all and return the inode with the highest version */
|
/* we need to search all and return the inode with the highest version */
|
||||||
for(b = pL->dirListHead; b; b=b->next) {
|
for(b = pL->dir.listHead; b; b = b->next) {
|
||||||
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
||||||
if (ino == jDir->ino) {
|
if (ino == jDir->ino) {
|
||||||
if(jDir->version < version) continue;
|
if(jDir->version < version) continue;
|
||||||
|
@ -593,8 +665,9 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
|
||||||
/* now we found the right entry again. (shoulda returned inode*) */
|
/* now we found the right entry again. (shoulda returned inode*) */
|
||||||
if (jDirFound->type != DT_LNK)
|
if (jDirFound->type != DT_LNK)
|
||||||
return jDirFound->ino;
|
return jDirFound->ino;
|
||||||
/* so its a soft link so we follow it again. */
|
|
||||||
b2 = pL->fragListHead;
|
/* it's a soft link so we follow it again. */
|
||||||
|
b2 = pL->frag.listHead;
|
||||||
while (b2) {
|
while (b2) {
|
||||||
jNode = (struct jffs2_raw_inode *) (b2->offset);
|
jNode = (struct jffs2_raw_inode *) (b2->offset);
|
||||||
if (jNode->ino == jDirFound->ino) {
|
if (jNode->ino == jDirFound->ino) {
|
||||||
|
@ -644,7 +717,8 @@ jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino)
|
||||||
tmp[i] = c[i + 1];
|
tmp[i] = c[i + 1];
|
||||||
tmp[i] = '\0';
|
tmp[i] = '\0';
|
||||||
/* only a failure if we arent looking at top level */
|
/* only a failure if we arent looking at top level */
|
||||||
if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && (working_tmp[0])) {
|
if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) &&
|
||||||
|
(working_tmp[0])) {
|
||||||
putstr("find_inode failed for name=");
|
putstr("find_inode failed for name=");
|
||||||
putstr(working_tmp);
|
putstr(working_tmp);
|
||||||
putstr("\r\n");
|
putstr("\r\n");
|
||||||
|
@ -674,29 +748,30 @@ jffs2_1pass_rescan_needed(struct part_info *part)
|
||||||
{
|
{
|
||||||
struct b_node *b;
|
struct b_node *b;
|
||||||
struct jffs2_unknown_node *node;
|
struct jffs2_unknown_node *node;
|
||||||
struct b_lists *pL=(struct b_lists *)part->jffs2_priv;
|
struct b_lists *pL = (struct b_lists *)part->jffs2_priv;
|
||||||
|
|
||||||
if (part->jffs2_priv == 0){
|
if (part->jffs2_priv == 0){
|
||||||
DEBUGF ("rescan: First time in use\n");
|
DEBUGF ("rescan: First time in use\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* if we have no list, we need to rescan */
|
/* if we have no list, we need to rescan */
|
||||||
if (pL->fragListCount == 0) {
|
if (pL->frag.listCount == 0) {
|
||||||
DEBUGF ("rescan: fraglist zero\n");
|
DEBUGF ("rescan: fraglist zero\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* or if we are scanninga new partition */
|
/* or if we are scanning a new partition */
|
||||||
if (pL->partOffset != part->offset) {
|
if (pL->partOffset != part->offset) {
|
||||||
DEBUGF ("rescan: different partition\n");
|
DEBUGF ("rescan: different partition\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* but suppose someone reflashed the root partition at the same offset... */
|
/* but suppose someone reflashed a partition at the same offset... */
|
||||||
b = pL->dirListHead;
|
b = pL->dir.listHead;
|
||||||
while (b) {
|
while (b) {
|
||||||
node = (struct jffs2_unknown_node *) (b->offset);
|
node = (struct jffs2_unknown_node *) (b->offset);
|
||||||
if (node->nodetype != JFFS2_NODETYPE_DIRENT) {
|
if (node->nodetype != JFFS2_NODETYPE_DIRENT) {
|
||||||
DEBUGF ("rescan: fs changed beneath me? (%lx)\n", (unsigned long) b->offset);
|
DEBUGF ("rescan: fs changed beneath me? (%lx)\n",
|
||||||
|
(unsigned long) b->offset);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
b = b->next;
|
b = b->next;
|
||||||
|
@ -704,12 +779,71 @@ jffs2_1pass_rescan_needed(struct part_info *part)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_FRAGMENTS
|
||||||
|
static void
|
||||||
|
dump_fragments(struct b_lists *pL)
|
||||||
|
{
|
||||||
|
struct b_node *b;
|
||||||
|
struct jffs2_raw_inode *jNode;
|
||||||
|
|
||||||
|
putstr("\r\n\r\n******The fragment Entries******\r\n");
|
||||||
|
b = pL->frag.listHead;
|
||||||
|
while (b) {
|
||||||
|
jNode = (struct jffs2_raw_inode *) (b->offset);
|
||||||
|
putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset);
|
||||||
|
putLabeledWord("\tbuild_list: totlen = ", jNode->totlen);
|
||||||
|
putLabeledWord("\tbuild_list: inode = ", jNode->ino);
|
||||||
|
putLabeledWord("\tbuild_list: version = ", jNode->version);
|
||||||
|
putLabeledWord("\tbuild_list: isize = ", jNode->isize);
|
||||||
|
putLabeledWord("\tbuild_list: atime = ", jNode->atime);
|
||||||
|
putLabeledWord("\tbuild_list: offset = ", jNode->offset);
|
||||||
|
putLabeledWord("\tbuild_list: csize = ", jNode->csize);
|
||||||
|
putLabeledWord("\tbuild_list: dsize = ", jNode->dsize);
|
||||||
|
putLabeledWord("\tbuild_list: compr = ", jNode->compr);
|
||||||
|
putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr);
|
||||||
|
putLabeledWord("\tbuild_list: flags = ", jNode->flags);
|
||||||
|
putLabeledWord("\tbuild_list: offset = ", b->offset); // FIXME: ? [RS]
|
||||||
|
b = b->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_DIRENTS
|
||||||
|
static void
|
||||||
|
dump_dirents(struct b_lists *pL)
|
||||||
|
{
|
||||||
|
struct b_node *b;
|
||||||
|
struct jffs2_raw_dirent *jDir;
|
||||||
|
|
||||||
|
putstr("\r\n\r\n******The directory Entries******\r\n");
|
||||||
|
b = pL->dir.listHead;
|
||||||
|
while (b) {
|
||||||
|
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
||||||
|
putstr("\r\n");
|
||||||
|
putnstr(jDir->name, jDir->nsize);
|
||||||
|
putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic);
|
||||||
|
putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype);
|
||||||
|
putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc);
|
||||||
|
putLabeledWord("\tbuild_list: pino = ", jDir->pino);
|
||||||
|
putLabeledWord("\tbuild_list: version = ", jDir->version);
|
||||||
|
putLabeledWord("\tbuild_list: ino = ", jDir->ino);
|
||||||
|
putLabeledWord("\tbuild_list: mctime = ", jDir->mctime);
|
||||||
|
putLabeledWord("\tbuild_list: nsize = ", jDir->nsize);
|
||||||
|
putLabeledWord("\tbuild_list: type = ", jDir->type);
|
||||||
|
putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc);
|
||||||
|
putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc);
|
||||||
|
putLabeledWord("\tbuild_list: offset = ", b->offset); // FIXME: ? [RS]
|
||||||
|
b = b->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
jffs2_1pass_build_lists(struct part_info * part)
|
jffs2_1pass_build_lists(struct part_info * part)
|
||||||
{
|
{
|
||||||
struct b_lists *pL;
|
struct b_lists *pL;
|
||||||
struct jffs2_unknown_node *node;
|
struct jffs2_unknown_node *node;
|
||||||
u32 offset;
|
u32 offset, oldoffset = 0;
|
||||||
u32 max = part->size - sizeof(struct jffs2_raw_inode);
|
u32 max = part->size - sizeof(struct jffs2_raw_inode);
|
||||||
u32 counter = 0;
|
u32 counter = 0;
|
||||||
u32 counter4 = 0;
|
u32 counter4 = 0;
|
||||||
|
@ -722,71 +856,52 @@ jffs2_1pass_build_lists(struct part_info * part)
|
||||||
/* lcd_off(); */
|
/* lcd_off(); */
|
||||||
|
|
||||||
/* if we are building a list we need to refresh the cache. */
|
/* if we are building a list we need to refresh the cache. */
|
||||||
/* note that since we don't free our memory, eventually this will be bad. */
|
|
||||||
/* but we're a bootldr so what the hell. */
|
|
||||||
jffs_init_1pass_list(part);
|
jffs_init_1pass_list(part);
|
||||||
pL=(struct b_lists *)part->jffs2_priv;
|
pL = (struct b_lists *)part->jffs2_priv;
|
||||||
pL->partOffset = part->offset;
|
pL->partOffset = part->offset;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
printf("Scanning JFFS2 FS: ");
|
printf("Scanning JFFS2 FS: ");
|
||||||
|
|
||||||
/* start at the beginning of the partition */
|
/* start at the beginning of the partition */
|
||||||
while (offset < max) {
|
while (offset < max) {
|
||||||
if (! (++counter%10000))
|
if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) {
|
||||||
printf("\b\b%c ", spinner[(counter / 10000) % 4]);
|
printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]);
|
||||||
|
oldoffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
node = (struct jffs2_unknown_node *) (part->offset + offset);
|
node = (struct jffs2_unknown_node *) (part->offset + offset);
|
||||||
if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {
|
if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {
|
||||||
/* if its a fragment add it */
|
/* if its a fragment add it */
|
||||||
if (node->nodetype == JFFS2_NODETYPE_INODE && inode_crc((struct jffs2_raw_inode *) node)) {
|
if (node->nodetype == JFFS2_NODETYPE_INODE &&
|
||||||
if (!(pL->fragListTail = add_node(pL->fragListTail, &(pL->fragListCount),
|
inode_crc((struct jffs2_raw_inode *) node)) {
|
||||||
&(pL->fragListMemBase)))) {
|
if (insert_node(&pL->frag, (u32) part->offset +
|
||||||
putstr("add_node failed!\r\n");
|
offset) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
pL->fragListTail->offset = (u32) (part->offset + offset);
|
|
||||||
if (!pL->fragListHead)
|
|
||||||
pL->fragListHead = pL->fragListTail;
|
|
||||||
} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&
|
} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&
|
||||||
dirent_crc((struct jffs2_raw_dirent *) node) &&
|
dirent_crc((struct jffs2_raw_dirent *) node) &&
|
||||||
dirent_name_crc((struct jffs2_raw_dirent *) node)) {
|
dirent_name_crc((struct jffs2_raw_dirent *) node)) {
|
||||||
if (! (counterN%100))
|
if (! (counterN%100))
|
||||||
printf("\b\b. ");
|
printf("\b\b. ");
|
||||||
#if 0
|
if (insert_node(&pL->dir, (u32) part->offset +
|
||||||
printf("Found DIRENT @ 0x%lx\n", offset);
|
offset) == NULL)
|
||||||
putstr("\r\nbuild_lists:p&l ->");
|
|
||||||
putnstr(((struct jffs2_raw_dirent *) node)->name, ((struct jffs2_raw_dirent *) node)->nsize);
|
|
||||||
putstr("\r\n");
|
|
||||||
putLabeledWord("\tpino = ", ((struct jffs2_raw_dirent *) node)->pino);
|
|
||||||
putLabeledWord("\tnsize = ", ((struct jffs2_raw_dirent *) node)->nsize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!(pL->dirListTail = add_node(pL->dirListTail, &(pL->dirListCount), &(pL->dirListMemBase)))) {
|
|
||||||
putstr("add_node failed!\r\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
pL->dirListTail->offset = (u32) (part->offset + offset);
|
|
||||||
#if 0
|
|
||||||
putLabeledWord("\ttail = ", (u32) pL->dirListTail);
|
|
||||||
putstr("\ttailName ->");
|
|
||||||
putnstr(((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->name,
|
|
||||||
((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->nsize);
|
|
||||||
putstr("\r\n");
|
|
||||||
#endif
|
|
||||||
if (!pL->dirListHead)
|
|
||||||
pL->dirListHead = pL->dirListTail;
|
|
||||||
counterN++;
|
counterN++;
|
||||||
} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {
|
} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {
|
||||||
if (node->totlen != sizeof(struct jffs2_unknown_node))
|
if (node->totlen != sizeof(struct jffs2_unknown_node))
|
||||||
printf("OOPS Cleanmarker has bad size %d != %d\n", node->totlen, sizeof(struct jffs2_unknown_node));
|
printf("OOPS Cleanmarker has bad size "
|
||||||
|
"%d != %d\n", node->totlen,
|
||||||
|
sizeof(struct jffs2_unknown_node));
|
||||||
} else {
|
} else {
|
||||||
printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, node->totlen, offset);
|
printf("Unknown node type: %x len %d "
|
||||||
|
"offset 0x%x\n", node->nodetype,
|
||||||
|
node->totlen, offset);
|
||||||
}
|
}
|
||||||
offset += ((node->totlen + 3) & ~3);
|
offset += ((node->totlen + 3) & ~3);
|
||||||
counterF++;
|
counterF++;
|
||||||
} else if (node->magic == JFFS2_EMPTY_BITMASK && node->nodetype == JFFS2_EMPTY_BITMASK) {
|
} else if (node->magic == JFFS2_EMPTY_BITMASK &&
|
||||||
|
node->nodetype == JFFS2_EMPTY_BITMASK) {
|
||||||
offset = jffs2_scan_empty(offset, part);
|
offset = jffs2_scan_empty(offset, part);
|
||||||
} else { /* if we know nothing of the filesystem, we just step and look. */
|
} else { /* if we know nothing, we just step and look. */
|
||||||
offset += 4;
|
offset += 4;
|
||||||
counter4++;
|
counter4++;
|
||||||
}
|
}
|
||||||
|
@ -799,66 +914,21 @@ jffs2_1pass_build_lists(struct part_info * part)
|
||||||
/* splash(); */
|
/* splash(); */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
putLabeledWord("dir entries = ", pL->dirListCount);
|
putLabeledWord("dir entries = ", pL->dir.listCount);
|
||||||
putLabeledWord("frag entries = ", pL->fragListCount);
|
putLabeledWord("frag entries = ", pL->frag.listCount);
|
||||||
putLabeledWord("+4 increments = ", counter4);
|
putLabeledWord("+4 increments = ", counter4);
|
||||||
putLabeledWord("+file_offset increments = ", counterF);
|
putLabeledWord("+file_offset increments = ", counterF);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef SHOW_ALL
|
#ifdef DEBUG_DIRENTS
|
||||||
#undef SHOW_ALL_FRAGMENTS
|
dump_dirents(pL);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SHOW_ALL
|
#ifdef DEBUG_FRAGMENTS
|
||||||
{
|
dump_fragments(pL);
|
||||||
struct b_node *b;
|
#endif
|
||||||
struct b_node *b2;
|
|
||||||
struct jffs2_raw_dirent *jDir;
|
|
||||||
struct jffs2_raw_inode *jNode;
|
|
||||||
|
|
||||||
putstr("\r\n\r\n******The directory Entries******\r\n");
|
|
||||||
b = pL->dirListHead;
|
|
||||||
while (b) {
|
|
||||||
jDir = (struct jffs2_raw_dirent *) (b->offset);
|
|
||||||
putstr("\r\n");
|
|
||||||
putnstr(jDir->name, jDir->nsize);
|
|
||||||
putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic);
|
|
||||||
putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype);
|
|
||||||
putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc);
|
|
||||||
putLabeledWord("\tbuild_list: pino = ", jDir->pino);
|
|
||||||
putLabeledWord("\tbuild_list: version = ", jDir->version);
|
|
||||||
putLabeledWord("\tbuild_list: ino = ", jDir->ino);
|
|
||||||
putLabeledWord("\tbuild_list: mctime = ", jDir->mctime);
|
|
||||||
putLabeledWord("\tbuild_list: nsize = ", jDir->nsize);
|
|
||||||
putLabeledWord("\tbuild_list: type = ", jDir->type);
|
|
||||||
putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc);
|
|
||||||
putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc);
|
|
||||||
b = b->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SHOW_ALL_FRAGMENTS
|
|
||||||
putstr("\r\n\r\n******The fragment Entries******\r\n");
|
|
||||||
b = pL->fragListHead;
|
|
||||||
while (b) {
|
|
||||||
jNode = (struct jffs2_raw_inode *) (b->offset);
|
|
||||||
putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset);
|
|
||||||
putLabeledWord("\tbuild_list: totlen = ", jNode->totlen);
|
|
||||||
putLabeledWord("\tbuild_list: inode = ", jNode->ino);
|
|
||||||
putLabeledWord("\tbuild_list: version = ", jNode->version);
|
|
||||||
putLabeledWord("\tbuild_list: isize = ", jNode->isize);
|
|
||||||
putLabeledWord("\tbuild_list: atime = ", jNode->atime);
|
|
||||||
putLabeledWord("\tbuild_list: offset = ", jNode->offset);
|
|
||||||
putLabeledWord("\tbuild_list: csize = ", jNode->csize);
|
|
||||||
putLabeledWord("\tbuild_list: dsize = ", jNode->dsize);
|
|
||||||
putLabeledWord("\tbuild_list: compr = ", jNode->compr);
|
|
||||||
putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr);
|
|
||||||
putLabeledWord("\tbuild_list: flags = ", jNode->flags);
|
|
||||||
b = b->next;
|
|
||||||
}
|
|
||||||
#endif /* SHOW_ALL_FRAGMENTS */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SHOW_ALL */
|
|
||||||
/* give visual feedback that we are done scanning the flash */
|
/* give visual feedback that we are done scanning the flash */
|
||||||
led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */
|
led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -875,13 +945,13 @@ jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL)
|
||||||
struct jffs2_raw_inode *jNode;
|
struct jffs2_raw_inode *jNode;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
b = pL->fragListHead;
|
|
||||||
for (i = 0; i < JFFS2_NUM_COMPR; i++) {
|
for (i = 0; i < JFFS2_NUM_COMPR; i++) {
|
||||||
piL->compr_info[i].num_frags = 0;
|
piL->compr_info[i].num_frags = 0;
|
||||||
piL->compr_info[i].compr_sum = 0;
|
piL->compr_info[i].compr_sum = 0;
|
||||||
piL->compr_info[i].decompr_sum = 0;
|
piL->compr_info[i].decompr_sum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b = pL->frag.listHead;
|
||||||
while (b) {
|
while (b) {
|
||||||
jNode = (struct jffs2_raw_inode *) (b->offset);
|
jNode = (struct jffs2_raw_inode *) (b->offset);
|
||||||
if (jNode->compr < JFFS2_NUM_COMPR) {
|
if (jNode->compr < JFFS2_NUM_COMPR) {
|
||||||
|
@ -917,7 +987,7 @@ jffs2_1pass_ls(struct part_info * part, const char *fname)
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
u32 inode;
|
u32 inode;
|
||||||
|
|
||||||
if (! (pl = jffs2_get_list(part, "ls")))
|
if (! (pl = jffs2_get_list(part, "ls")))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {
|
if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {
|
||||||
|
@ -983,7 +1053,7 @@ jffs2_1pass_info(struct part_info * part)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
jffs2_1pass_fill_info(pl, &info);
|
jffs2_1pass_fill_info(pl, &info);
|
||||||
for (i=0; i < JFFS2_NUM_COMPR; i++) {
|
for (i = 0; i < JFFS2_NUM_COMPR; i++) {
|
||||||
printf("Compression: %s\n", compr_names[i]);
|
printf("Compression: %s\n", compr_names[i]);
|
||||||
printf("\tfrag count: %d\n", info.compr_info[i].num_frags);
|
printf("\tfrag count: %d\n", info.compr_info[i].num_frags);
|
||||||
printf("\tcompressed sum: %d\n", info.compr_info[i].compr_sum);
|
printf("\tcompressed sum: %d\n", info.compr_info[i].compr_sum);
|
||||||
|
|
|
@ -3,23 +3,31 @@
|
||||||
|
|
||||||
#include <jffs2/jffs2.h>
|
#include <jffs2/jffs2.h>
|
||||||
|
|
||||||
|
|
||||||
struct b_node {
|
struct b_node {
|
||||||
u32 offset;
|
u32 offset;
|
||||||
struct b_node *next;
|
struct b_node *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct b_list {
|
||||||
|
struct b_node *listTail;
|
||||||
|
struct b_node *listHead;
|
||||||
|
#ifdef CFG_JFFS2_SORT_FRAGMENTS
|
||||||
|
struct b_node *listLast;
|
||||||
|
int (*listCompare)(struct b_node *new, struct b_node *node);
|
||||||
|
u32 listLoops;
|
||||||
|
#endif
|
||||||
|
u32 listCount;
|
||||||
|
struct mem_block *listMemBase;
|
||||||
|
};
|
||||||
|
|
||||||
struct b_lists {
|
struct b_lists {
|
||||||
char *partOffset;
|
char *partOffset;
|
||||||
struct b_node *dirListTail;
|
struct b_list dir;
|
||||||
struct b_node *dirListHead;
|
struct b_list frag;
|
||||||
u32 dirListCount;
|
|
||||||
u32 dirListMemBase;
|
|
||||||
struct b_node *fragListTail;
|
|
||||||
struct b_node *fragListHead;
|
|
||||||
u32 fragListCount;
|
|
||||||
u32 fragListMemBase;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct b_compr_info {
|
struct b_compr_info {
|
||||||
u32 num_frags;
|
u32 num_frags;
|
||||||
u32 compr_sum;
|
u32 compr_sum;
|
||||||
|
@ -33,11 +41,14 @@ struct b_jffs2_info {
|
||||||
static inline int
|
static inline int
|
||||||
hdr_crc(struct jffs2_unknown_node *node)
|
hdr_crc(struct jffs2_unknown_node *node)
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
|
u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
|
||||||
u32 crc_blah = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
|
#else
|
||||||
|
/* what's the semantics of this? why is this here? */
|
||||||
crc_blah ^= ~0;
|
u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
|
||||||
|
|
||||||
|
crc ^= ~0;
|
||||||
|
#endif
|
||||||
if (node->hdr_crc != crc) {
|
if (node->hdr_crc != crc) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -44,7 +44,6 @@ typedef struct global_data {
|
||||||
#ifdef CONFIG_VFD
|
#ifdef CONFIG_VFD
|
||||||
unsigned long fb_base; /* base address of frame buffer */
|
unsigned long fb_base; /* base address of frame buffer */
|
||||||
unsigned char vfd_type; /* display type */
|
unsigned char vfd_type; /* display type */
|
||||||
unsigned char vfd_inv_data; /* inverted data lines ? */
|
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
unsigned long cpu_clk; /* CPU clock in Hz! */
|
unsigned long cpu_clk; /* CPU clock in Hz! */
|
||||||
|
|
|
@ -71,22 +71,37 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
|
||||||
#include <asm/arch/io.h>
|
#include <asm/arch/io.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IO definitions. We define {out,in,outs,ins}[bwl] if __io is defined
|
* IO port access primitives
|
||||||
* by the machine. Otherwise, these definitions are left for the machine
|
* -------------------------
|
||||||
* specific header files to pick up.
|
*
|
||||||
|
* The ARM doesn't have special IO access instructions; all IO is memory
|
||||||
|
* mapped. Note that these are defined to perform little endian accesses
|
||||||
|
* only. Their primary purpose is to access PCI and ISA peripherals.
|
||||||
|
*
|
||||||
|
* Note that for a big endian machine, this implies that the following
|
||||||
|
* big endian mode connectivity is in place, as described by numerious
|
||||||
|
* ARM documents:
|
||||||
|
*
|
||||||
|
* PCI: D0-D7 D8-D15 D16-D23 D24-D31
|
||||||
|
* ARM: D24-D31 D16-D23 D8-D15 D0-D7
|
||||||
|
*
|
||||||
|
* The machine specific io.h include defines __io to translate an "IO"
|
||||||
|
* address to a memory address.
|
||||||
*
|
*
|
||||||
* Note that we prevent GCC re-ordering or caching values in expressions
|
* Note that we prevent GCC re-ordering or caching values in expressions
|
||||||
* by introducing sequence points into the in*() definitions. Note that
|
* by introducing sequence points into the in*() definitions. Note that
|
||||||
* __raw_* do not guarantee this behaviour.
|
* __raw_* do not guarantee this behaviour.
|
||||||
|
*
|
||||||
|
* The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
|
||||||
*/
|
*/
|
||||||
#ifdef __io
|
#ifdef __io
|
||||||
#define outb(v,p) __raw_writeb(v,__io(p))
|
#define outb(v,p) __raw_writeb(v,__io(p))
|
||||||
#define outw(v,p) __raw_writew(v,__io(p))
|
#define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p))
|
||||||
#define outl(v,p) __raw_writel(v,__io(p))
|
#define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p))
|
||||||
|
|
||||||
#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; })
|
#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; })
|
||||||
#define inw(p) ({ unsigned int __v = __raw_readw(__io(p)); __v; })
|
#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; })
|
||||||
#define inl(p) ({ unsigned int __v = __raw_readl(__io(p)); __v; })
|
#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; })
|
||||||
|
|
||||||
#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
|
#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
|
||||||
#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
|
#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
|
||||||
|
@ -171,20 +186,20 @@ extern void __readwrite_bug(const char *fn);
|
||||||
*/
|
*/
|
||||||
#ifdef __mem_pci
|
#ifdef __mem_pci
|
||||||
|
|
||||||
#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; })
|
#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; })
|
||||||
#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; })
|
#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; })
|
||||||
#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; })
|
#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; })
|
||||||
|
|
||||||
#define writeb(val,addr) __raw_writeb(val,__mem_pci(addr))
|
#define writeb(v,c) __raw_writeb(v,__mem_pci(c))
|
||||||
#define writew(val,addr) __raw_writew(val,__mem_pci(addr))
|
#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c))
|
||||||
#define writel(val,addr) __raw_writel(val,__mem_pci(addr))
|
#define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c))
|
||||||
|
|
||||||
#define memset_io(a,b,c) _memset_io(__mem_pci(a),(b),(c))
|
#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l))
|
||||||
#define memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_pci(b),(c))
|
#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l))
|
||||||
#define memcpy_toio(a,b,c) _memcpy_toio(__mem_pci(a),(b),(c))
|
#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l))
|
||||||
|
|
||||||
#define eth_io_copy_and_sum(a,b,c,d) \
|
#define eth_io_copy_and_sum(s,c,l,b) \
|
||||||
eth_copy_and_sum((a),__mem_pci(b),(c),(d))
|
eth_copy_and_sum((s),__mem_pci(c),(l),(b))
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
check_signature(unsigned long io_addr, const unsigned char *signature,
|
check_signature(unsigned long io_addr, const unsigned char *signature,
|
||||||
|
@ -218,14 +233,6 @@ out:
|
||||||
|
|
||||||
#endif /* __mem_pci */
|
#endif /* __mem_pci */
|
||||||
|
|
||||||
/*
|
|
||||||
* remap a physical address `phys' of size `size' with page protection `prot'
|
|
||||||
* into virtual address `from'
|
|
||||||
*/
|
|
||||||
#define io_remap_page_range(from,phys,size,prot) \
|
|
||||||
remap_page_range(from,phys,size,prot)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this architecture has ISA IO, then define the isa_read/isa_write
|
* If this architecture has ISA IO, then define the isa_read/isa_write
|
||||||
* macros.
|
* macros.
|
||||||
|
@ -245,6 +252,10 @@ out:
|
||||||
#define isa_eth_io_copy_and_sum(a,b,c,d) \
|
#define isa_eth_io_copy_and_sum(a,b,c,d) \
|
||||||
eth_copy_and_sum((a),__mem_isa(b),(c),(d))
|
eth_copy_and_sum((a),__mem_isa(b),(c),(d))
|
||||||
|
|
||||||
|
#ifndef PCI_MEMORY_VADDR /* XXX problem not understood -- wd */
|
||||||
|
#define PCI_MEMORY_VADDR 0
|
||||||
|
#endif /* XXX */
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
isa_check_signature(unsigned long io_addr, const unsigned char *signature,
|
isa_check_signature(unsigned long io_addr, const unsigned char *signature,
|
||||||
int length)
|
int length)
|
||||||
|
|
|
@ -60,9 +60,9 @@
|
||||||
#define CONFIG_ENV_OVERWRITE
|
#define CONFIG_ENV_OVERWRITE
|
||||||
|
|
||||||
#define CONFIG_BAUDRATE 19200
|
#define CONFIG_BAUDRATE 19200
|
||||||
|
#define CONFIG_MISC_INIT_R 1 /* we have a misc_init_r() function */
|
||||||
|
|
||||||
#define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_I2C | CFG_CMD_EEPROM) & ~CFG_CMD_NET)
|
#define CONFIG_COMMANDS (CONFIG_CMD_DFL|CFG_CMD_I2C|CFG_CMD_EEPROM|CFG_CMD_NET|CFG_CMD_JFFS2|CFG_CMD_DHCP)
|
||||||
|
|
||||||
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
|
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
|
||||||
#include <cmd_confdefs.h>
|
#include <cmd_confdefs.h>
|
||||||
|
|
||||||
|
@ -90,13 +90,13 @@
|
||||||
/*
|
/*
|
||||||
* Size of malloc() pool; this lives below the uppermost 128 KiB which are
|
* Size of malloc() pool; this lives below the uppermost 128 KiB which are
|
||||||
* used for the RAM copy of the uboot code
|
* used for the RAM copy of the uboot code
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
/* #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) */
|
#define CFG_MALLOC_LEN (256*1024)
|
||||||
#define CFG_MALLOC_LEN (128*1024)
|
|
||||||
|
|
||||||
#define CFG_LONGHELP /* undef to save memory */
|
#define CFG_LONGHELP /* undef to save memory */
|
||||||
#define CFG_PROMPT "uboot> " /* Monitor Command Prompt */
|
#define CFG_PROMPT "uboot> " /* Monitor Command Prompt */
|
||||||
#define CFG_CBSIZE 128 /* Console I/O Buffer Size */
|
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
|
||||||
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
|
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
|
||||||
#define CFG_MAXARGS 16 /* max number of command args */
|
#define CFG_MAXARGS 16 /* max number of command args */
|
||||||
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
|
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
|
||||||
|
@ -106,10 +106,7 @@
|
||||||
|
|
||||||
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
|
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
|
||||||
|
|
||||||
#define CFG_LOAD_ADDR 0xa7fe0000 /* default load address */
|
#define CFG_LOAD_ADDR 0xa3000000 /* load kernel to this address */
|
||||||
/* RS: where is this documented? */
|
|
||||||
/* RS: is this where U-Boot is */
|
|
||||||
/* RS: relocated to in RAM? */
|
|
||||||
|
|
||||||
#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
|
#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
|
||||||
/* RS: the oscillator is actually 3680130?? */
|
/* RS: the oscillator is actually 3680130?? */
|
||||||
|
@ -128,9 +125,9 @@
|
||||||
/*
|
/*
|
||||||
* I2C bus
|
* I2C bus
|
||||||
*/
|
*/
|
||||||
#define CONFIG_HARD_I2C 1
|
#define CONFIG_HARD_I2C 1
|
||||||
#define CFG_I2C_SPEED 50000
|
#define CFG_I2C_SPEED 50000
|
||||||
#define CFG_I2C_SLAVE 0xfe
|
#define CFG_I2C_SLAVE 0xfe
|
||||||
|
|
||||||
#define CFG_ENV_IS_IN_EEPROM 1
|
#define CFG_ENV_IS_IN_EEPROM 1
|
||||||
|
|
||||||
|
@ -138,9 +135,20 @@
|
||||||
#define CFG_ENV_SIZE 1024 /* 1 KiB */
|
#define CFG_ENV_SIZE 1024 /* 1 KiB */
|
||||||
#define CFG_I2C_EEPROM_ADDR 0x50 /* A0 = 0 (hardwired) */
|
#define CFG_I2C_EEPROM_ADDR 0x50 /* A0 = 0 (hardwired) */
|
||||||
#define CFG_EEPROM_PAGE_WRITE_BITS 5 /* 5 bits = 32 octets */
|
#define CFG_EEPROM_PAGE_WRITE_BITS 5 /* 5 bits = 32 octets */
|
||||||
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* between stop and start */
|
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 15 /* between stop and start */
|
||||||
#define CFG_I2C_EEPROM_ADDR_LEN 2 /* length of address */
|
#define CFG_I2C_EEPROM_ADDR_LEN 2 /* length of address */
|
||||||
#define CFG_EEPROM_SIZE 4096 /* size in bytes */
|
#define CFG_EEPROM_SIZE 4096 /* size in bytes */
|
||||||
|
#define CFG_I2C_INIT_BOARD 1 /* board has it's own init */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SMSC91C111 Network Card
|
||||||
|
*/
|
||||||
|
#define CONFIG_DRIVER_SMC91111 1
|
||||||
|
#define CONFIG_SMC91111_BASE 0x14000000 /* chip select 5 */
|
||||||
|
#undef CONFIG_SMC_USE_32_BIT /* 16 bit bus access */
|
||||||
|
#undef CONFIG_SMC_91111_EXT_PHY /* we use internal phy */
|
||||||
|
#undef CONFIG_SHOW_ACTIVITY
|
||||||
|
#define CONFIG_NET_RETRY_COUNT 10 /* # of retries */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stack sizes
|
* Stack sizes
|
||||||
|
@ -168,11 +176,19 @@
|
||||||
|
|
||||||
#define CFG_FLASH_BASE PHYS_FLASH_1
|
#define CFG_FLASH_BASE PHYS_FLASH_1
|
||||||
|
|
||||||
/*
|
|
||||||
* GPIO settings;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* GP15 == nCS1 is 1
|
/*
|
||||||
|
* JFFS2 Partitions
|
||||||
|
*/
|
||||||
|
#define CFG_JFFS_CUSTOM_PART 1 /* see board/innokom/flash.c */
|
||||||
|
#define CONFIG_MTD_INNOKOM_16MB 1 /* development flash */
|
||||||
|
#undef CONFIG_MTD_INNOKOM_64MB /* production flash */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO settings; see BDI2000 config file for details
|
||||||
|
*
|
||||||
|
* GP15 == nCS1 is 1
|
||||||
* GP24 == SFRM is 1
|
* GP24 == SFRM is 1
|
||||||
* GP25 == TXD is 1
|
* GP25 == TXD is 1
|
||||||
* GP33 == nCS5 is 1
|
* GP33 == nCS5 is 1
|
||||||
|
@ -273,6 +289,7 @@
|
||||||
#define CFG_GAFR2_L_VAL 0xA0000000
|
#define CFG_GAFR2_L_VAL 0xA0000000
|
||||||
#define CFG_GAFR2_U_VAL 0x00000002
|
#define CFG_GAFR2_U_VAL 0x00000002
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: set GPIO_RER/FER */
|
/* FIXME: set GPIO_RER/FER */
|
||||||
|
|
||||||
/* RDH = 1
|
/* RDH = 1
|
||||||
|
@ -285,9 +302,8 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Memory settings
|
* Memory settings
|
||||||
*/
|
*
|
||||||
|
* This is the configuration for nCS0/1 -> flash banks
|
||||||
/* This is the configuration for nCS0/1 -> flash banks
|
|
||||||
* configuration for nCS1:
|
* configuration for nCS1:
|
||||||
* [31] 0 - Slower Device
|
* [31] 0 - Slower Device
|
||||||
* [30:28] 010 - CS deselect to CS time: 2*(2*MemClk) = 40 ns
|
* [30:28] 010 - CS deselect to CS time: 2*(2*MemClk) = 40 ns
|
||||||
|
@ -321,7 +337,7 @@
|
||||||
* [03] 1 - 16 Bit bus width
|
* [03] 1 - 16 Bit bus width
|
||||||
* [02:00] 100 - variable latency I/O
|
* [02:00] 100 - variable latency I/O
|
||||||
*/
|
*/
|
||||||
#define CFG_MSC1_VAL 0x132C593C /* TDM switch, DSP */
|
#define CFG_MSC1_VAL 0x123C593C /* TDM switch, DSP */
|
||||||
|
|
||||||
/* This is the configuration for nCS4/5 -> ExtBus, LAN Controller
|
/* This is the configuration for nCS4/5 -> ExtBus, LAN Controller
|
||||||
*
|
*
|
||||||
|
@ -340,7 +356,7 @@
|
||||||
* [03] 1 - 16 Bit bus width
|
* [03] 1 - 16 Bit bus width
|
||||||
* [02:00] 100 - variable latency I/O
|
* [02:00] 100 - variable latency I/O
|
||||||
*/
|
*/
|
||||||
#define CFG_MSC2_VAL 0x132C6CDC /* extra bus, LAN controller */
|
#define CFG_MSC2_VAL 0x123C6CDC /* extra bus, LAN controller */
|
||||||
|
|
||||||
/* MDCNFG: SDRAM Configuration Register
|
/* MDCNFG: SDRAM Configuration Register
|
||||||
*
|
*
|
||||||
|
@ -359,16 +375,15 @@
|
||||||
* [12] 1 - SA1111 compatiblity mode
|
* [12] 1 - SA1111 compatiblity mode
|
||||||
* [11] 1 - latch return data with return clock
|
* [11] 1 - latch return data with return clock
|
||||||
* [10] 0 - no alternate addressing for pair 0/1
|
* [10] 0 - no alternate addressing for pair 0/1
|
||||||
* [09:08] 01 - tRP=2*MemClk; CL=2; tRCD=2*MemClk; tRAS=5*MemClk; tRC=8*MemClk
|
* [09:08] 01 - tRP=2*MemClk CL=2 tRCD=2*MemClk tRAS=5*MemClk tRC=8*MemClk
|
||||||
* [7] 1 - 4 internal banks in lower partition pair
|
* [7] 1 - 4 internal banks in lower partition pair
|
||||||
* [06:05] 10 - 13 row address bits for partition 0/1
|
* [06:05] 10 - 13 row address bits for partition 0/1
|
||||||
* [04:03] 01 - 9 column address bits for partition 0/1
|
* [04:03] 01 - 9 column address bits for partition 0/1
|
||||||
* [02] 0 - SDRAM partition 0/1 width is 32 bit
|
* [02] 0 - SDRAM partition 0/1 width is 32 bit
|
||||||
* [01] 0 - disable SDRAM partition 1
|
* [01] 0 - disable SDRAM partition 1
|
||||||
* [00] 1 - enable SDRAM partition 0
|
* [00] 1 - enable SDRAM partition 0
|
||||||
*
|
|
||||||
* use the configuration above but disable partition 0
|
|
||||||
*/
|
*/
|
||||||
|
/* use the configuration above but disable partition 0 */
|
||||||
#define CFG_MDCNFG_VAL 0x000019c8
|
#define CFG_MDCNFG_VAL 0x000019c8
|
||||||
|
|
||||||
/* MDREFR: SDRAM Refresh Control Register
|
/* MDREFR: SDRAM Refresh Control Register
|
||||||
|
@ -434,11 +449,4 @@
|
||||||
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
|
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
|
||||||
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
|
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define CFG_ENV_IS_IN_FLASH 1
|
|
||||||
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C000)
|
|
||||||
/* Addr of Environment Sector */
|
|
||||||
#define CFG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __CONFIG_H */
|
#endif /* __CONFIG_H */
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
* repeatedly to change the speed and slave addresses.
|
* repeatedly to change the speed and slave addresses.
|
||||||
*/
|
*/
|
||||||
void i2c_init(int speed, int slaveaddr);
|
void i2c_init(int speed, int slaveaddr);
|
||||||
|
#ifdef CFG_I2C_INIT_BOARD
|
||||||
|
void i2c_init_board(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probe the given I2C chip address. Returns 0 if a chip responded,
|
* Probe the given I2C chip address. Returns 0 if a chip responded,
|
||||||
|
|
Loading…
Reference in a new issue