* 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.
master
wdenk 21 years ago
parent 09127c6096
commit 06d01dbe00
  1. 18
      CHANGELOG
  2. 2
      board/csb226/csb226.c
  3. 4
      board/emk/top860/config.mk
  4. 4
      board/innokom/innokom.c
  5. 339
      board/lubbock/flash.c
  6. 2
      board/mpl/common/common_util.c
  7. 2
      board/mpl/vcma9/cmd_vcma9.c
  8. 1
      board/mpl/vcma9/vcma9.c
  9. 172
      board/trab/vfd.c
  10. 79
      common/cmd_pci.c
  11. 8
      cpu/arm920t/interrupts.c
  12. 3
      cpu/arm920t/start.S
  13. 8
      doc/README.JFFS2
  14. 4
      drivers/cs8900.c
  15. 2
      drivers/cs8900.h
  16. 2
      drivers/s3c24x0_i2c.c
  17. 636
      fs/jffs2/jffs2_1pass.c
  18. 33
      fs/jffs2/jffs2_private.h
  19. 1
      include/asm-arm/global_data.h
  20. 65
      include/asm-arm/io.h
  21. 68
      include/configs/innokom.h
  22. 3
      include/i2c.h

@ -2,6 +2,24 @@
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:
- 16/32 MB and 50/80 MHz support with auto-detection for IP860
- ETH05 and BEDBUG support for CU824

@ -38,10 +38,10 @@
int misc_init_r(void)
{
#if 0
uchar *str;
/* determine if the software update key is pressed during startup */
#if 0
/* not ported yet... */
if (GPLR0 & 0x00000800) {
printf("using bootcmd_normal (sw-update button not pressed)\n");

@ -21,4 +21,8 @@
# MA 02111-1307 USA
#
#
# TOP860 board
#
TEXT_BASE = 0x80000000

@ -39,7 +39,7 @@
* The Innokom board has GPIO70 connected to SCLK which can be toggled
* until all chips think that their current cycles are finished.
*/
int i2c_init_board(void)
void i2c_init_board(void)
{
int i;
@ -53,8 +53,6 @@ int i2c_init_board(void)
}
/* set gpio pin to input */
GPDR(70) &= ~GPIO_bit(70);
return 0;
}

@ -28,7 +28,7 @@
#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 */
#define FLASH_PORT_WIDTH32
@ -53,50 +53,47 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
* Functions
*/
static ulong flash_get_size (FPW *addr, flash_info_t *info);
static int write_data (flash_info_t *info, ulong dest, FPW data);
static void flash_get_offsets (ulong base, flash_info_t *info);
void inline spin_wheel(void);
static int write_data (flash_info_t *info, ulong dest, FPW data);
static void flash_get_offsets (ulong base, flash_info_t *info);
void inline spin_wheel (void);
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
int i;
ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
{
switch (i)
{
case 0:
flash_get_size((FPW *)PHYS_FLASH_1, &flash_info[i]);
flash_get_offsets(PHYS_FLASH_1, &flash_info[i]);
break;
case 1:
flash_get_size((FPW *)PHYS_FLASH_2, &flash_info[i]);
flash_get_offsets(PHYS_FLASH_2, &flash_info[i]);
break;
default:
panic("configured to many flash banks!\n");
break;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0]);
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]);
return size;
int i;
ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
switch (i) {
case 0:
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
break;
case 1:
flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
break;
default:
panic ("configured to many flash banks!\n");
break;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
flash_protect ( FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0] );
flash_protect ( FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
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;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL: printf ("INTEL "); break;
default: printf ("Unknown Vendor "); break;
case FLASH_MAN_INTEL:
printf ("INTEL ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F128J3A:
printf ("28F128J3A\n"); break;
default: printf ("Unknown Chip Type\n"); break;
}
case FLASH_28F128J3A:
printf ("28F128J3A\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i],
info->protect[i] ? " (RO)" : " "
);
}
printf ("\n");
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
return;
}
@ -163,37 +166,37 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)
volatile FPW value;
/* Write auto select command: read Manufacturer ID */
addr[0x5555] = (FPW)0x00AA00AA;
addr[0x2AAA] = (FPW)0x00550055;
addr[0x5555] = (FPW)0x00900090;
addr[0x5555] = (FPW) 0x00AA00AA;
addr[0x2AAA] = (FPW) 0x00550055;
addr[0x5555] = (FPW) 0x00900090;
mb();
mb ();
value = addr[0];
switch (value) {
switch (value) {
case (FPW)INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
case (FPW) INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = (FPW)0x00FF00FF; /* restore read mode */
return (0); /* no or unknown flash */
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
return (0); /* no or unknown flash */
}
mb();
value = addr[1]; /* device ID */
mb ();
value = addr[1]; /* device ID */
switch (value) {
switch (value) {
case (FPW)INTEL_ID_28F128J3A:
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x02000000;
break; /* => 16 MB */
case (FPW) INTEL_ID_28F128J3A:
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x02000000;
break; /* => 16 MB */
default:
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",
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);
}
@ -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;
ulong type, start, now, last;
int flag, prot, sect;
ulong type, start, last;
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) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
}
type = (info->flash_id & FLASH_VENDMASK);
if ((type != FLASH_MAN_INTEL)) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
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) {
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);
last = start;
last = start;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
FPWV *addr = (FPWV *)(info->start[sect]);
FPWV *addr = (FPWV *) (info->start[sect]);
FPW status;
printf("Erasing sector %2d ... ", sect);
printf ("Erasing sector %2d ... ", sect);
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
*addr = (FPW)0x00500050; /* clear status register */
*addr = (FPW)0x00200020; /* erase setup */
*addr = (FPW)0x00D000D0; /* erase confirm */
*addr = (FPW) 0x00500050; /* clear status register */
*addr = (FPW) 0x00200020; /* erase setup */
*addr = (FPW) 0x00D000D0; /* erase confirm */
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = (FPW)0x00B000B0; /* suspend erase */
*addr = (FPW)0x00FF00FF; /* reset to read mode */
*addr = (FPW) 0x00B000B0; /* suspend erase */
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
rcode = 1;
break;
}
}
}
}
*addr = 0x00500050; /* clear status register cmd. */
*addr = 0x00FF00FF; /* resest to read mode */
*addr = 0x00500050; /* clear status register cmd. */
*addr = 0x00FF00FF; /* resest to read mode */
printf (" done\n");
}
}
}
}
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)
{
ulong cp, wp;
ulong cp, wp;
FPW data;
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;
#endif
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
for (; i<port_width && cnt>0; ++i) {
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i = 0, cp = wp; i < l; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
for (; i < port_width && cnt > 0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt==0 && i<port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
--cnt;
++cp;
}
for (; cnt == 0 && i < port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
return (rc);
}
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
return (rc);
}
wp += port_width;
}
}
/*
* handle word aligned part
*/
/*
* handle word aligned part
*/
count = 0;
while (cnt >= port_width) {
data = 0;
for (i=0; i<port_width; ++i) {
for (i = 0; i < port_width; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_data(info, wp, SWAP(data))) != 0) {
return (rc);
}
wp += port_width;
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
return (rc);
}
wp += port_width;
cnt -= port_width;
if (count++ > 0x800)
{
spin_wheel();
if (count++ > 0x800) {
spin_wheel ();
count = 0;
}
}
}
if (cnt == 0) {
if (cnt == 0) {
return (0);
}
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) {
/*
* 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);
--cnt;
}
for (; i < port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
return (write_data(info, wp, SWAP(data)));
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)
{
FPWV *addr = (FPWV *)dest;
FPWV *addr = (FPWV *) dest;
ulong status;
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
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);
}
/* 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;
/* arm simple, non interrupt dependent timer */
reset_timer_masked();
reset_timer_masked ();
/* wait while polling the status register */
while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) {
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
*addr = (FPW)0x00FF00FF; /* restore read mode */
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
*addr = (FPW) 0x00FF00FF; /* restore read mode */
return (1);
}
}
}
*addr = (FPW)0x00FF00FF; /* restore read mode */
*addr = (FPW) 0x00FF00FF; /* restore read mode */
return (0);
}
void inline
spin_wheel(void)
void inline spin_wheel (void)
{
static int r=0,p=0;
static char w[] = "\\/-";
static int p = 0;
static char w[] = "\\/-";
printf("\010%c", w[p]);
(++p == 3) ? (p = 0) : 0;
printf ("\010%c", w[p]);
(++p == 3) ? (p = 0) : 0;
}

@ -49,7 +49,9 @@ int mpl_prg(unsigned long src,unsigned long size)
unsigned long start;
flash_info_t *info;
int i,rc;
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
unsigned long *magic = (unsigned long *)src;
#endif
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");
}
} 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: ");
cs8900_e2prom_read(addr, &data);

@ -183,7 +183,6 @@ static uchar Get_Board_PCB(void)
int checkboard(void)
{
unsigned char s[50];
unsigned char bc, var, rc;
int i;
backup_t *b = (backup_t *) s;

@ -59,10 +59,24 @@
#define FRAME_BUF_SIZE ((256*4*56)/8)
#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 */
#define VFD_TYPE_T119C 1 /* Noritake T119C VFD */
#define VFD_TYPE_MN11236 2
/*#define NEW_CPLD_CLK*/
int vfd_board_id;
/* taken from armboot/common/vfd.c */
unsigned long adr_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")
*/
memset ((void *)(gd->fb_base),
gd->vfd_inv_data ? 0xFF : 0,
FRAME_BUF_SIZE);
memset ((void *)(gd->fb_base), 0, FRAME_BUF_SIZE);
switch (gd->vfd_type) {
case VFD_TYPE_T119C:
@ -98,10 +110,7 @@ void init_grid_ctrl(void)
bit_nr = bit % 8;
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
temp=(*(volatile unsigned char*)(adr));
if (gd->vfd_inv_data)
temp &= ~(1<<bit_nr);
else
temp |= (1<<bit_nr);
temp |= (1<<bit_nr);
(*(volatile unsigned char*)(adr))=temp;
if(grid_cycle<55)
@ -115,10 +124,7 @@ void init_grid_ctrl(void)
bit_nr = bit%8;
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
temp=(*(volatile unsigned char*)(adr));
if (gd->vfd_inv_data)
temp &= ~(1<<bit_nr);
else
temp |= (1<<bit_nr);
temp |= (1<<bit_nr);
(*(volatile unsigned char*)(adr))=temp;
}
}
@ -136,10 +142,7 @@ void init_grid_ctrl(void)
bit_nr = bit % 8;
bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
temp=(*(volatile unsigned char*)(adr));
if (gd->vfd_inv_data)
temp &= ~(1<<bit_nr);
else
temp |= (1<<bit_nr);
temp |= (1<<bit_nr);
(*(volatile unsigned char*)(adr))=temp;
if(grid_cycle<37)
@ -152,10 +155,7 @@ void init_grid_ctrl(void)
bit_nr = bit%8;
bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
temp=(*(volatile unsigned char*)(adr));
if (gd->vfd_inv_data)
temp &= ~(1<<bit_nr);
else
temp |= (1<<bit_nr);
temp |= (1<<bit_nr);
(*(volatile unsigned char*)(adr))=temp;
}
}
@ -250,7 +250,7 @@ void create_vfd_table(void)
for(entry=0;entry<2;entry++) {
unsigned long adr = gd->fb_base;
unsigned int bit_nr = 0;
if (vfd_table[x][y][color][display][entry]) {
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];
temp=(*(volatile unsigned char*)(adr));
if (gd->vfd_inv_data) {
if (value)
temp &= ~(1<<bit_nr);
else
temp |= (1<<bit_nr);
} else {
if (value)
temp |= (1<<bit_nr);
else
temp &= ~(1<<bit_nr);
}
if (value)
temp |= (1<<bit_nr);
else
temp &= ~(1<<bit_nr);
(*(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
* 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;
rLCDCON3 = 0x0051000A;
rLCDCON4 = 0x00000001;
rLCDCON5 = 0x00000440;
/* try to determine display type from the value
* 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_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;
/* VM (GPD1) is used as clock for the CPLD */
rPDCON = (rPDCON & 0xFFFFFFF3) | 0x00000008;
return 0;
}
@ -397,7 +427,7 @@ int drv_vfd_init(void)
char *tmp;
ulong palette;
static int vfd_init_done = 0;
int vfd_id;
int vfd_inv_data = 0;
DECLARE_GLOBAL_DATA_PTR;
@ -405,17 +435,9 @@ int drv_vfd_init(void)
return (0);
vfd_init_done = 1;
/* try to determine display type from the value
* 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 */
debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_id);
debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_board_id);
switch (vfd_id) {
switch (vfd_board_id) {
case 0: /* board revision < Rev.200 */
if ((tmp = getenv ("vfd_type")) == NULL) {
break;
@ -428,19 +450,18 @@ int drv_vfd_init(void)
/* cannot use printf for a warning here */
gd->vfd_type = 0; /* unknown */
}
gd->vfd_inv_data = 0;
break;
default: /* default to MN11236, data inverted */
gd->vfd_type = VFD_TYPE_MN11236;
gd->vfd_inv_data = 1;
vfd_inv_data = 1;
setenv ("vfd_type", "MN11236");
}
debug ("VFD type: %s%s\n",
(gd->vfd_type == VFD_TYPE_T119C) ? "T119C" :
(gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :
"unknown",
gd->vfd_inv_data ? ", inverted data" : "");
vfd_inv_data ? ", inverted data" : "");
gd->fb_base = gd->fb_base;
create_vfd_table();
@ -458,11 +479,33 @@ int drv_vfd_init(void)
* (wrap around)
* see manual S3C2400
*/
/* Stopp LCD-Controller */
rLCDCON1 = 0x00000000;
/* frame buffer startadr */
rLCDSADDR1 = gd->fb_base >> 1;
/* frame buffer endadr */
rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
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 ("LCDSADDR2: %lX\n", rLCDSADDR2);
@ -471,6 +514,17 @@ int drv_vfd_init(void)
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 */
/************************************************************************/

@ -115,28 +115,65 @@ void pciinfo(int BusNum, int ShortPCIListing)
char* pci_classes_str(u8 class)
{
static char *pci_classes[] = {
"Build before PCI Rev2.0",
"Mass storage controller",
"Network controller ",
"Display controller ",
"Multimedia device ",
"Memory controller ",
"Bridge device ",
"Simple comm. controller",
"Base system peripheral ",
"Input device ",
"Docking station ",
"Processor ",
"Serial bus controller ",
"Reserved entry ",
"Does not fit any class "
};
if (class < (sizeof pci_classes / sizeof *pci_classes))
return pci_classes[(int) class];
switch (class) {
case PCI_CLASS_NOT_DEFINED:
return "Build before PCI Rev2.0";
break;
case PCI_BASE_CLASS_STORAGE:
return "Mass storage controller";
break;
case PCI_BASE_CLASS_NETWORK:
return "Network controller ";
break;
case PCI_BASE_CLASS_DISPLAY:
return "Display controller ";
break;
case PCI_BASE_CLASS_MULTIMEDIA:
return "Multimedia device ";
break;
case PCI_BASE_CLASS_MEMORY:
return "Memory controller ";
break;
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 "??? ";
break;
};
}
/*

@ -199,9 +199,9 @@ int interrupt_init (void)
/* load value for 10 ms timeout */
lastdec = rTCNTB4 = timer_load_val;
/* auto load, manual update of Timer 4 */
rTCON = 0x600000;
rTCON = (rTCON & ~0x0700000) | 0x600000;
/* auto load, start Timer 4 */
rTCON = 0x500000;
rTCON = (rTCON & ~0x0700000) | 0x500000;
timestamp = 0;
return (0);
@ -296,8 +296,10 @@ ulong get_tbclk (void)
#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
tbclk = timer_load_val * 100;
#elif defined(CONFIG_SMDK2410)
#elif defined(CONFIG_SMDK2410) || defined(CONFIG_VCMA9)
tbclk = CFG_HZ;
#else
# error "tbclk not configured"
#endif
return tbclk;

@ -446,6 +446,9 @@ fiq:
reset_cpu:
#ifdef CONFIG_S3C2400
bl disable_interrupts
# ifdef CONFIG_TRAB
bl disable_vfd
# endif
ldr r1, _rWTCON
ldr r2, _rWTCNT
/* Disable watchdog */

@ -9,6 +9,14 @@ fsload - load binary file from a file system image
fsinfo - print information about file systems
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
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 */
/***********************************************************/
void cs8900_e2prom_write(unsigned char addr, unsigned short value)
int cs8900_e2prom_write(unsigned char addr, unsigned short value)
{
cs8900_e2prom_ready();
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);
cs8900_e2prom_ready();
return;
return 0;
}
#endif /* COMMANDS & CFG_NET */

@ -253,6 +253,6 @@
#define EEPROM_ERASE_CMD 0x0300
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 */

@ -64,10 +64,12 @@ static int GetIICSDA(void)
return (rGPEDAT & 0x8000) >> 15;
}
#if 0
static void SetIICSDA(int x)
{
rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;
}
#endif
static void SetIICSCL(int x)
{

@ -1,3 +1,4 @@
/* vi: set sw=4 ts=4: */
/*
-------------------------------------------------------------------------
* 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 <config.h>
#include <malloc.h>
@ -88,124 +125,197 @@
#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
# define DEBUGF(fmt,args...) printf(fmt ,##args)
#else
# define DEBUGF(fmt,args...)
#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 *
add_node(struct b_node *tail, u32 * count, u32 * memBase)
add_node(struct b_list *list)
{
u32 index;
u32 memLimit;
u32 index = 0;
struct mem_block *memBase;
struct b_node *b;
index = (*count) * sizeof(struct b_node) % MALLOC_CHUNK;
memLimit = MALLOC_CHUNK;
memBase = list->listMemBase;
if (memBase != NULL)
index = memBase->index;
#if 0
putLabeledWord("add_node: index = ", index);
putLabeledWord("add_node: memLimit = ", memLimit);
putLabeledWord("add_node: memBase = ", *memBase);
putLabeledWord("add_node: memBase = ", list->listMemBase);
#endif
/* we need not keep a list of bases since we'll never free the */
/* memory, just jump the the kernel */
if ((index == 0) || (index > memLimit)) { /* we need mode space before we continue */
if ((*memBase = (u32) mmalloc(MALLOC_CHUNK)) == (u32) NULL) {
if (memBase == NULL || index >= NODE_CHUNK) {
/* we need more space before we continue */
memBase = mmalloc(sizeof(struct mem_block));
if (memBase == NULL) {
putstr("add_node: malloc failed\n");
return NULL;
}
memBase->next = list->listMemBase;
index = 0;
#if 0
putLabeledWord("add_node: alloced a new membase at ", *memBase);
#endif
}
/* now we have room to add it. */
b = (struct b_node *) (*memBase + index);
/* null on first call */
if (tail)
tail->next = b;
b = &memBase->nodes[index];
index ++;
#if 0
putLabeledWord("add_node: tail = ", (u32) tail);
if (tail)
putLabeledWord("add_node: tail->next = ", (u32) tail->next);
memBase->index = index;
list->listMemBase = memBase;
list->listCount++;
return b;
}
static struct b_node *
insert_node(struct b_list *list, u32 offset)
{
struct b_node *new;
#ifdef CFG_JFFS2_SORT_FRAGMENTS
struct b_node *b, *prev;
#endif
#if 0
putLabeledWord("add_node: mb+i = ", (u32) (*memBase + index));
putLabeledWord("add_node: b = ", (u32) b);
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
(*count)++;
b->next = (struct b_node *) NULL;
return b;
{
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;
}
/* we know we have empties at the start offset so we will hop */
/* t points that would be non F if there were a node here to speed this up. */
struct jffs2_empty_node {
u32 first;
u32 second;
};
#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
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 */
u32 offset = start_offset + 32;
struct jffs2_empty_node *node;
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;
}
while (offset < max && *(u32 *)offset == 0xFFFFFFFF) {
offset += sizeof(u32);
/* return if spinning is due */
if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break;
}
return start_offset;
return offset - part->offset;
}
static u32
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 *)part->jffs2_priv;
struct b_lists *pL;
pL->dirListHead = pL->dirListTail = NULL;
pL->fragListHead = pL->fragListTail = NULL;
pL->dirListCount = 0;
pL->dirListMemBase = 0;
pL->fragListCount = 0;
pL->fragListMemBase = 0;
pL->partOffset = 0x0;
if (part->jffs2_priv != NULL) {
pL = (struct b_lists *)part->jffs2_priv;
free_nodes(&pL->frag);
free_nodes(&pL->dir);
free(pL);
}
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;
}
@ -216,21 +326,18 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)
{
struct b_node *b;
struct jffs2_raw_inode *jNode;
u32 totalSize = 1;
u32 oldTotalSize = 0;
u32 size = 0;
char *lDest = (char *) dest;
u32 totalSize = 0;
u16 latestVersion = 0;
char *lDest;
char *src;
long ret;
int i;
u32 counter = 0;
char totalSizeSet = 0;
#if 0
b = pL->fragListHead;
while (b) {
for (b = pL->frag.listHead; b != NULL; b = b->next) {
jNode = (struct jffs2_raw_inode *) (b->offset);
if ((inode == jNode->ino)) {
#if 0
putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);
putLabeledWord("read_inode: inode = ", jNode->ino);
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: usercompr = ", jNode->usercompr);
putLabeledWord("read_inode: flags = ", jNode->flags);
}
b = b->next;
}
#endif
#if 1
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 */
/* get actual file length from the newest node */
if (jNode->version >= latestVersion) {
totalSize = jNode->isize;
totalSizeSet = 1;
} else if (!totalSizeSet) {
totalSize = size + jNode->dsize + 1;
latestVersion = jNode->version;
}
oldTotalSize = jNode->isize;
if(dest) {
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);
#if 0
putLabeledWord("\r\n\r\nread_inode: src = ", src);
putLabeledWord("read_inode: src = ", src);
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
switch (jNode->compr) {
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);
break;
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
putLabeledWord("read_inode: size = ", size);
putLabeledWord("read_inode: totalSize = ", totalSize);
putLabeledWord("read_inode: compr ret = ", ret);
#endif
}
b = b->next;
counter++;
}
#endif
#if 0
putLabeledWord("read_inode: returning = ", size);
putLabeledWord("read_inode: returning = ", totalSize);
#endif
return size;
return totalSize;
}
/* 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;
/* 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);
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 */
if (jDir->version < version) continue;
if(jDir->version==0) {
if(jDir->version == 0) {
/* Is this legal? */
putstr(" ** WARNING ** ");
putnstr(jDir->name, jDir->nsize);
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 ... */
putstr(" ** ERROR ** ");
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 const char *l="xwr";
int mask=1, i;
char c;
switch (mode & S_IFMT) {
case S_IFDIR: str[0]='d'; break;
case S_IFBLK: str[0]='b'; break;
case S_IFCHR: str[0]='c'; break;
case S_IFIFO: str[0]='f'; break;
case S_IFLNK: str[0]='l'; break;
case S_IFSOCK: str[0]='s'; break;
case S_IFREG: str[0]='-'; break;
default: str[0]='?';
}
for(i=0;i<9;i++) {
c=l[i%3];
str[9-i]=(mode & mask)?c:'-';
mask=mask<<1;
}
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_ISVTX) str[9]=(mode & S_IXOTH)?'t':'T';
str[10]='\0';
return str;
static const char *l = "xwr";
int mask = 1, i;
char c;
switch (mode & S_IFMT) {
case S_IFDIR: str[0] = 'd'; break;
case S_IFBLK: str[0] = 'b'; break;
case S_IFCHR: str[0] = 'c'; break;
case S_IFIFO: str[0] = 'f'; break;
case S_IFLNK: str[0] = 'l'; break;
case S_IFSOCK: str[0] = 's'; break;
case S_IFREG: str[0] = '-'; break;
default: str[0] = '?';
}
for(i = 0; i < 9; i++) {
c = l[i%3];
str[9-i] = (mode & mask)?c:'-';
mask = mask<<1;
}
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_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T';
str[10] = '\0';
return str;
}
static inline void dump_stat(struct stat *st, const char *name)
{
char str[20];
char s[64], *p;
char str[20];
char s[64], *p;
if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */
st->st_mtime = 1;
if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -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,'\r'))!=NULL) *p='\0';
if ((p = strchr(s,'\n')) != 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),
st->st_size, s, name);
printf("%6lo %s %8ld %s %s\n", st->st_mode, 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);
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)
@ -446,16 +518,16 @@ static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, st
if(!d || !i) return -1;
strncpy(fname, d->name, d->nsize);
fname[d->nsize]='\0';
fname[d->nsize] = '\0';
memset(&st,0,sizeof(st));
st.st_mtime=i->mtime;
st.st_mode=i->mode;
st.st_ino=i->ino;
st.st_mtime = i->mtime;
st.st_mode = i->mode;
st.st_ino = i->ino;
/* 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);
@ -477,18 +549,18 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
struct b_node *b;
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);
if ((pino == jDir->pino) && (jDir->ino)) { /* 0 inode for unlink */
u32 i_version=0;
struct jffs2_raw_inode *jNode, *i=NULL;
struct b_node *b2 = pL->fragListHead;
if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */
u32 i_version = 0;
struct jffs2_raw_inode *jNode, *i = NULL;
struct b_node *b2 = pL->frag.listHead;
while (b2) {
jNode = (struct jffs2_raw_inode *) (b2->offset);
if (jNode->ino == jDir->ino
&& jNode->version>=i_version)
i=jNode;
&& jNode->version >= i_version)
i = jNode;
b2 = b2->next;
}
@ -568,7 +640,7 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)
unsigned char *src;
/* 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);
if (ino == jDir->ino) {
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*) */
if (jDirFound->type != DT_LNK)
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) {
jNode = (struct jffs2_raw_inode *) (b2->offset);
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] = '\0';
/* 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(working_tmp);
putstr("\r\n");
@ -674,29 +748,30 @@ jffs2_1pass_rescan_needed(struct part_info *part)
{
struct b_node *b;
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){
DEBUGF ("rescan: First time in use\n");
return 1;
}
/* if we have no list, we need to rescan */
if (pL->fragListCount == 0) {
if (pL->frag.listCount == 0) {
DEBUGF ("rescan: fraglist zero\n");
return 1;
}
/* or if we are scanninga new partition */
/* or if we are scanning a new partition */
if (pL->partOffset != part->offset) {
DEBUGF ("rescan: different partition\n");
return 1;
}
/* but suppose someone reflashed the root partition at the same offset... */
b = pL->dirListHead;
/* but suppose someone reflashed a partition at the same offset... */
b = pL->dir.listHead;
while (b) {
node = (struct jffs2_unknown_node *) (b->offset);
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;
}
b = b->next;
@ -704,12 +779,71 @@ jffs2_1pass_rescan_needed(struct part_info *part)
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
jffs2_1pass_build_lists(struct part_info * part)
{
struct b_lists *pL;
struct jffs2_unknown_node *node;
u32 offset;
u32 offset, oldoffset = 0;
u32 max = part->size - sizeof(struct jffs2_raw_inode);
u32 counter = 0;
u32 counter4 = 0;
@ -722,71 +856,52 @@ jffs2_1pass_build_lists(struct part_info * part)
/* lcd_off(); */
/* 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);
pL=(struct b_lists *)part->jffs2_priv;
pL = (struct b_lists *)part->jffs2_priv;
pL->partOffset = part->offset;
offset = 0;
printf("Scanning JFFS2 FS: ");
/* start at the beginning of the partition */
while (offset < max) {
if (! (++counter%10000))
printf("\b\b%c ", spinner[(counter / 10000) % 4]);
if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) {
printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]);
oldoffset = offset;
}
node = (struct jffs2_unknown_node *) (part->offset + offset);
if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {
/* if its a fragment add it */
if (node->nodetype == JFFS2_NODETYPE_INODE && inode_crc((struct jffs2_raw_inode *) node)) {
if (!(pL->fragListTail = add_node(pL->fragListTail, &(pL->fragListCount),
&(pL->fragListMemBase)))) {
putstr("add_node failed!\r\n");
if (node->nodetype == JFFS2_NODETYPE_INODE &&
inode_crc((struct jffs2_raw_inode *) node)) {
if (insert_node(&pL->frag, (u32) part->offset +
offset) == NULL)
return 0;
}
pL->fragListTail->offset = (u32) (part->offset + offset);
if (!pL->fragListHead)
pL->fragListHead = pL->fragListTail;
} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&
dirent_crc((struct jffs2_raw_dirent *) node) &&
dirent_name_crc((struct jffs2_raw_dirent *) node)) {
if (! (counterN%100))
printf("\b\b. ");
#if 0
printf("Found DIRENT @ 0x%lx\n", offset);
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");
if (insert_node(&pL->dir, (u32) part->offset +
offset) == NULL)
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++;
} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {
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 {
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);
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);
} 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;
counter4++;
}
@ -799,66 +914,21 @@ jffs2_1pass_build_lists(struct part_info * part)
/* splash(); */
#if 0
putLabeledWord("dir entries = ", pL->dirListCount);
putLabeledWord("frag entries = ", pL->fragListCount);
putLabeledWord("dir entries = ", pL->dir.listCount);
putLabeledWord("frag entries = ", pL->frag.listCount);
putLabeledWord("+4 increments = ", counter4);
putLabeledWord("+file_offset increments = ", counterF);
#endif
#undef SHOW_ALL
#undef SHOW_ALL_FRAGMENTS
#ifdef SHOW_ALL
{
struct b_node *b;
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 DEBUG_DIRENTS
dump_dirents(pL);
#endif
#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 */
}
#ifdef DEBUG_FRAGMENTS
dump_fragments(pL);
#endif
#endif /* SHOW_ALL */
/* give visual feedback that we are done scanning the flash */
led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */
return 1;
@ -875,13 +945,13 @@ jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL)
struct jffs2_raw_inode *jNode;
int i;
b = pL->fragListHead;
for (i = 0; i < JFFS2_NUM_COMPR; i++) {
piL->compr_info[i].num_frags = 0;
piL->compr_info[i].compr_sum = 0;
piL->compr_info[i].decompr_sum = 0;
}
b = pL->frag.listHead;
while (b) {
jNode = (struct jffs2_raw_inode *) (b->offset);
if (jNode->compr < JFFS2_NUM_COMPR) {
@ -917,7 +987,7 @@ jffs2_1pass_ls(struct part_info * part, const char *fname)
long ret = 0;
u32 inode;
if (! (pl = jffs2_get_list(part, "ls")))
if (! (pl = jffs2_get_list(part, "ls")))
return 0;
if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {
@ -983,7 +1053,7 @@ jffs2_1pass_info(struct part_info * part)
return 0;
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("\tfrag count: %d\n", info.compr_info[i].num_frags);
printf("\tcompressed sum: %d\n", info.compr_info[i].compr_sum);

@ -3,23 +3,31 @@
#include <jffs2/jffs2.h>
struct b_node {
u32 offset;
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 {
char *partOffset;
struct b_node *dirListTail;
struct b_node *dirListHead;
u32 dirListCount;
u32 dirListMemBase;
struct b_node *fragListTail;
struct b_node *fragListHead;
u32 fragListCount;
u32 fragListMemBase;
struct b_list dir;
struct b_list frag;
};
struct b_compr_info {
u32 num_frags;
u32 compr_sum;
@ -33,11 +41,14 @@ struct b_jffs2_info {
static inline int
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_blah = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
crc_blah ^= ~0;
#else
/* what's the semantics of this? why is this here? */
u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4);
crc ^= ~0;
#endif
if (node->hdr_crc != crc) {
return 0;
} else {

@ -44,7 +44,6 @@ typedef struct global_data {
#ifdef CONFIG_VFD
unsigned long fb_base; /* base address of frame buffer */
unsigned char vfd_type; /* display type */
unsigned char vfd_inv_data; /* inverted data lines ? */
#endif
#if 0
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>
/*
* IO definitions. We define {out,in,outs,ins}[bwl] if __io is defined
* by the machine. Otherwise, these definitions are left for the machine
* specific header files to pick up.
* IO port access primitives
* -------------------------
*
* 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
* by introducing sequence points into the in*() definitions. Note that
* __raw_* do not guarantee this behaviour.
*
* The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
*/
#ifdef __io
#define outb(v,p) __raw_writeb(v,__io(p))
#define outw(v,p) __raw_writew(v,__io(p))
#define outl(v,p) __raw_writel(v,__io(p))
#define outw(v,p) __raw_writew(cpu_to_le16(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 inw(p) ({ unsigned int __v = __raw_readw(__io(p)); __v; })
#define inl(p) ({ unsigned int __v = __raw_readl(__io(p)); __v; })
#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; })
#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__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 outsw(p,d,l) __raw_writesw(__io(p),d,l)
@ -171,20 +186,20 @@ extern void __readwrite_bug(const char *fn);
*/
#ifdef __mem_pci
#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; })
#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; })
#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; })
#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; })
#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __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 writew(val,addr) __raw_writew(val,__mem_pci(addr))
#define writel(val,addr) __raw_writel(val,__mem_pci(addr))
#define writeb(v,c) __raw_writeb(v,__mem_pci(c))
#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c))
#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 memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_pci(b),(c))
#define memcpy_toio(a,b,c) _memcpy_toio(__mem_pci(a),(b),(c))
#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l))
#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l))
#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l))
#define eth_io_copy_and_sum(a,b,c,d) \
eth_copy_and_sum((a),__mem_pci(b),(c),(d))
#define eth_io_copy_and_sum(s,c,l,b) \
eth_copy_and_sum((s),__mem_pci(c),(l),(b))
static inline int
check_signature(unsigned long io_addr, const unsigned char *signature,
@ -219,14 +234,6 @@ out:
#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
* macros.
*/
@ -245,6 +252,10 @@ out:
#define isa_eth_io_copy_and_sum(a,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
isa_check_signature(unsigned long io_addr, const unsigned char *signature,
int length)

@ -60,9 +60,9 @@
#define CONFIG_ENV_OVERWRITE
#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) */
#include <cmd_confdefs.h>
@ -90,13 +90,13 @@
/*
* Size of malloc() pool; this lives below the uppermost 128 KiB which are
* used for the RAM copy of the uboot code
*
*/
/* #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) */
#define CFG_MALLOC_LEN (128*1024)
#define CFG_MALLOC_LEN (256*1024)
#define CFG_LONGHELP /* undef to save memory */
#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_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
@ -106,10 +106,7 @@
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
#define CFG_LOAD_ADDR 0xa7fe0000 /* default load address */
/* RS: where is this documented? */
/* RS: is this where U-Boot is */
/* RS: relocated to in RAM? */
#define CFG_LOAD_ADDR 0xa3000000 /* load kernel to this address */
#define CFG_HZ 3686400 /* incrementer freq: 3.6864 MHz */
/* RS: the oscillator is actually 3680130?? */
@ -128,9 +125,9 @@
/*
* I2C bus
*/
#define CONFIG_HARD_I2C 1
#define CFG_I2C_SPEED 50000
#define CFG_I2C_SLAVE 0xfe
#define CONFIG_HARD_I2C 1
#define CFG_I2C_SPEED 50000
#define CFG_I2C_SLAVE 0xfe
#define CFG_ENV_IS_IN_EEPROM 1
@ -138,9 +135,20 @@
#define CFG_ENV_SIZE 1024 /* 1 KiB */
#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_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_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
@ -168,11 +176,19 @@
#define CFG_FLASH_BASE PHYS_FLASH_1
/*
* GPIO settings;
* 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 */
/* GP15 == nCS1 is 1
/*
* GPIO settings; see BDI2000 config file for details
*
* GP15 == nCS1 is 1
* GP24 == SFRM is 1
* GP25 == TXD is 1
* GP33 == nCS5 is 1
@ -273,6 +289,7 @@
#define CFG_GAFR2_L_VAL 0xA0000000
#define CFG_GAFR2_U_VAL 0x00000002
/* FIXME: set GPIO_RER/FER */
/* RDH = 1
@ -285,9 +302,8 @@
/*
* Memory settings
*/
/* This is the configuration for nCS0/1 -> flash banks
*
* This is the configuration for nCS0/1 -> flash banks
* configuration for nCS1:
* [31] 0 - Slower Device
* [30:28] 010 - CS deselect to CS time: 2*(2*MemClk) = 40 ns
@ -321,7 +337,7 @@
* [03] 1 - 16 Bit bus width
* [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
*
@ -340,7 +356,7 @@
* [03] 1 - 16 Bit bus width
* [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
*
@ -359,16 +375,15 @@
* [12] 1 - SA1111 compatiblity mode
* [11] 1 - latch return data with return clock
* [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
* [06:05] 10 - 13 row 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
* [01] 0 - disable SDRAM partition 1
* [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
/* MDREFR: SDRAM Refresh Control Register
@ -434,11 +449,4 @@
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
#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 */

@ -51,6 +51,9 @@
* repeatedly to change the speed and slave addresses.
*/
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,

Loading…
Cancel
Save