diff options
author | wdenk <wdenk> | 2003-03-14 20:47:52 +0000 |
---|---|---|
committer | wdenk <wdenk> | 2003-03-14 20:47:52 +0000 |
commit | 06d01dbe000057e5df4af0f113242f0eba716340 (patch) | |
tree | 9188617ad1907e44f41910b99af9bde7258338f9 | |
parent | 09127c60964c47621937ada7b0ccbf0c26329376 (diff) |
* 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.
-rw-r--r-- | CHANGELOG | 18 | ||||
-rw-r--r-- | board/csb226/csb226.c | 2 | ||||
-rw-r--r-- | board/emk/top860/config.mk | 4 | ||||
-rw-r--r-- | board/innokom/innokom.c | 4 | ||||
-rw-r--r-- | board/lubbock/flash.c | 339 | ||||
-rw-r--r-- | board/mpl/common/common_util.c | 2 | ||||
-rw-r--r-- | board/mpl/vcma9/cmd_vcma9.c | 2 | ||||
-rw-r--r-- | board/mpl/vcma9/vcma9.c | 1 | ||||
-rw-r--r-- | board/trab/vfd.c | 172 | ||||
-rw-r--r-- | common/cmd_pci.c | 79 | ||||
-rw-r--r-- | cpu/arm920t/interrupts.c | 8 | ||||
-rw-r--r-- | cpu/arm920t/start.S | 3 | ||||
-rw-r--r-- | doc/README.JFFS2 | 8 | ||||
-rw-r--r-- | drivers/cs8900.c | 4 | ||||
-rw-r--r-- | drivers/cs8900.h | 2 | ||||
-rw-r--r-- | drivers/s3c24x0_i2c.c | 2 | ||||
-rw-r--r-- | fs/jffs2/jffs2_1pass.c | 636 | ||||
-rw-r--r-- | fs/jffs2/jffs2_private.h | 33 | ||||
-rw-r--r-- | include/asm-arm/global_data.h | 1 | ||||
-rw-r--r-- | include/asm-arm/io.h | 65 | ||||
-rw-r--r-- | include/configs/innokom.h | 68 | ||||
-rw-r--r-- | include/i2c.h | 3 |
22 files changed, 842 insertions, 614 deletions
diff --git a/CHANGELOG b/CHANGELOG index 1b36b41a402..18613a82a5b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/board/csb226/csb226.c b/board/csb226/csb226.c index 11cab005c66..a79d168e044 100644 --- a/board/csb226/csb226.c +++ b/board/csb226/csb226.c @@ -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"); diff --git a/board/emk/top860/config.mk b/board/emk/top860/config.mk index 95917a18b6c..7b940cb8138 100644 --- a/board/emk/top860/config.mk +++ b/board/emk/top860/config.mk @@ -21,4 +21,8 @@ # MA 02111-1307 USA # +# +# TOP860 board +# + TEXT_BASE = 0x80000000 diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c index 17f6353d2ef..0176d9c2c33 100644 --- a/board/innokom/innokom.c +++ b/board/innokom/innokom.c @@ -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; } diff --git a/board/lubbock/flash.c b/board/lubbock/flash.c index a93875083b6..dcf829b2c55 100644 --- a/board/lubbock/flash.c +++ b/board/lubbock/flash.c @@ -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; } - diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index 0a67090feaa..19ead331b87 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -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]; diff --git a/board/mpl/vcma9/cmd_vcma9.c b/board/mpl/vcma9/cmd_vcma9.c index cdafc50d654..80bb61b2bee 100644 --- a/board/mpl/vcma9/cmd_vcma9.c +++ b/board/mpl/vcma9/cmd_vcma9.c @@ -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); diff --git a/board/mpl/vcma9/vcma9.c b/board/mpl/vcma9/vcma9.c index 8e3552e2b32..e452a7b2827 100644 --- a/board/mpl/vcma9/vcma9.c +++ b/board/mpl/vcma9/vcma9.c @@ -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; diff --git a/board/trab/vfd.c b/board/trab/vfd.c index 894e3157d68..9b61f6eb617 100644 --- a/board/trab/vfd.c +++ b/board/trab/vfd.c @@ -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 */ /************************************************************************/ diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 5a3b5574ee9..a26deddcd36 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -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; + }; } /* diff --git a/cpu/arm920t/interrupts.c b/cpu/arm920t/interrupts.c index 963ccbd2a35..195fb01477a 100644 --- a/cpu/arm920t/interrupts.c +++ b/cpu/arm920t/interrupts.c @@ -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; diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S index a858dfa05eb..4a4825ab36a 100644 --- a/cpu/arm920t/start.S +++ b/cpu/arm920t/start.S @@ -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 */ diff --git a/doc/README.JFFS2 b/doc/README.JFFS2 index 0d39c46453a..3243895150b 100644 --- a/doc/README.JFFS2 +++ b/doc/README.JFFS2 @@ -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 diff --git a/drivers/cs8900.c b/drivers/cs8900.c index b9fac8c54b1..d35332c8302 100644 --- a/drivers/cs8900.c +++ b/drivers/cs8900.c @@ -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 */ diff --git a/drivers/cs8900.h b/drivers/cs8900.h index dbfda3c15ba..d772cad667a 100644 --- a/drivers/cs8900.h +++ b/drivers/cs8900.h @@ -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 */ diff --git a/drivers/s3c24x0_i2c.c b/drivers/s3c24x0_i2c.c index bf435c9839a..b50176118ad 100644 --- a/drivers/s3c24x0_i2c.c +++ b/drivers/s3c24x0_i2c.c @@ -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) { diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index bacec8e30cd..a5d9583596c 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -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); diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index ca0af1f9a4b..c6d5fe36032 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -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 { diff --git a/include/asm-arm/global_data.h b/include/asm-arm/global_data.h index e0a95e081b4..892710df405 100644 --- a/include/asm-arm/global_data.h +++ b/include/asm-arm/global_data.h @@ -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! */ diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 0d55ca25b46..122419f1e6b 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -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) diff --git a/include/configs/innokom.h b/include/configs/innokom.h index a8ee99ae003..c2267bd86d4 100644 --- a/include/configs/innokom.h +++ b/include/configs/innokom.h @@ -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 */ diff --git a/include/i2c.h b/include/i2c.h index 43d76fd8185..6d39080d8f5 100644 --- a/include/i2c.h +++ b/include/i2c.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, |