From: wdenk Date: Thu, 27 Dec 2001 23:04:49 +0000 (+0000) Subject: * Add support for AMX860 EDO RAM extension module X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f6aae77c1f33ff495c8f13361173697474951304;p=users%2Frw%2Fppcboot.git * Add support for AMX860 EDO RAM extension module * Improved flash handling for FLAGADM board Patch by Kári Davíðsson, 19 Dec 2001 * Make CPU clock measurement more accurate and repeatable. Patch by Dave Ellis, 20 Dec 2001 --- diff --git a/CHANGELOG b/CHANGELOG index e2e234d..7641689 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,14 @@ To do: Modifications for 1.1.3: ====================================================================== +* Add support for AMX860 EDO RAM extension module + +* Improved flash handling for FLAGADM board + Patch by Kári Davíðsson, 19 Dec 2001 + +* Make CPU clock measurement more accurate and repeatable. + Patch by Dave Ellis, 20 Dec 2001 + * Make PPCBoot build in Cygwin environment Patch by Davide Viti, 5 Dec 2001 diff --git a/board/flagadm/flagadm.c b/board/flagadm/flagadm.c index e467430..fb30116 100644 --- a/board/flagadm/flagadm.c +++ b/board/flagadm/flagadm.c @@ -24,149 +24,128 @@ #include #include "mpc8xx.h" -/* ------------------------------------------------------------------------- */ - -#if 0 -static long int dram_size (long int, long int *, long int); -#endif - -/* ------------------------------------------------------------------------- */ - #define _NOT_USED_ 0xFFFFFFFF +/*Orginal table, GPL4 disabled*/ const uint sdram_table[] = { - /* Single read cycle */ -0x1F07D004, 0xEEAEE004, 0x11ADD004, 0xEFBBA000, -0x1FF75447, -0x1FF77C34, /*Load mode register*/ -0xEFEABC34, 0x1FB57C35, - /* Burst read */ -0x1F07D004, 0xEEAEE004, 0x00ADC004, 0x00AFC000, -0x00AFC000, 0x01AFC000, 0x0FBB8000, 0x1FF75447, -_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, -_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, - /* Single write cycle */ -0x1F27D004, 0xEEAEA000, 0x01B90004, 0x1FF75447, -_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, - /* Burst Write cycle */ -0x1F07D004, 0xEEAEA000, 0x00AD4000, 0x00AFC000, -0x00AFC000, 0x01BB8004, 0x1FF75447, _NOT_USED_, -_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, -_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, - /* reFresh cycle */ -0x1FF5DC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, -0xFFFFFC84, 0xFFFFFC07, _NOT_USED_, _NOT_USED_, -_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, - /* Exception */ -0x7FFFFC07, _NOT_USED_, _NOT_USED_, _NOT_USED_ + /* single read (offset 0x00 in upm ram) */ + 0x1f07c004, 0xeeaee004, 0x11adc004, 0xefbba000, + 0x1ff74447, + /* Precharge */ + 0x1FF74C05, + _NOT_USED_, + _NOT_USED_, + /* burst read (offset 0x08 in upm ram) */ + 0x1f07c004, 0xeeaee004, 0x00adc004, 0x00afc000, + 0x00afc000, 0x01afc000, 0x0fbb8001, 0x1ff74447, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* single write (offset 0x18 in upm ram) */ + 0x1f27c004, 0xeeaea000, 0x01b90004, 0x1ff74447, + /* Load moderegister */ + 0x1FF74C34, /*Precharge*/ + 0xEFEA8C34, /*NOP*/ + 0x1FB54C35, /*Load moderegister*/ + _NOT_USED_, + + /* burst write (offset 0x20 in upm ram) */ + 0x1f07c004, 0xeeaea000, 0x00ad4000, 0x00afc000, + 0x00afc000, 0x01bb8004, 0x1ff74447, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* refresh (offset 0x30 in upm ram) */ + 0x1ff5cc84, 0xffffec04, 0xffffec04, 0xffffec04, + 0xffffec84, 0xffffec07, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* exception (offset 0x3C in upm ram) */ + 0x7fffec07, _NOT_USED_, _NOT_USED_, _NOT_USED_, }; -/* ------------------------------------------------------------------------- */ +/* GPL5 driven every cycle */ +/* the display and the DSP */ +const uint dsp_disp_table[] = +{ + /* single read (offset 0x00 in upm ram) */ + 0xefffc00c, 0x0fffc004, 0x0fffd004, 0x0fffc000, + 0x3fffe004, 0xffffdfff, _NOT_USED_, _NOT_USED_, + /* burst read (offset 0x08 in upm ram) */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* single write (offset 0x18 in upm ram) */ + 0xefffc00c, 0x0fffc004, 0x0fffd004, 0x0fffc000, + 0x3fffe004, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* burst write (offset 0x20 in upm ram) */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* refresh (offset 0x30 in upm ram) */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, + /* exception (offset 0x3C in upm ram) */ + _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +}; int checkboard (void) { - puts("FlagaDM V3.0"); + puts("FlagaDM V3.0 "); return 3; //Version 3 } -/* ------------------------------------------------------------------------- */ - long int initdram (int board_type) { volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile memctl8xx_t *memctl = &immap->im_memctl; long int size_b0; - memctl->memc_or2 = CFG_OR2_PRELIM; - memctl->memc_br2 = CFG_BR2_PRELIM; + memctl->memc_or2 = CFG_OR2; + memctl->memc_br2 = CFG_BR2; - udelay(1000); + udelay(100); upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint)); memctl->memc_mptpr = MPTPR_PTP_DIV16; + memctl->memc_mamr = CFG_MAMR_48_SDR | MAMR_TLFA_1X; - memctl->memc_mamr = CFG_MAMR_48_SDR_8; - memctl->memc_mcr = 0x80004130; // a refresh cycle - udelay(100); - - //Mode register programming - memctl->memc_mamr = CFG_MAMR_48_SDR_4; + /*Do the initialization of the SDRAM*/ + /*Start with the precharge cycle*/ + memctl->memc_mcr = (MCR_OP_RUN | MCR_UPM_A | MCR_MB_CS2 | \ + MCR_MLCF(1) | MCR_MAD(0x5)); - memctl->memc_mar = 0x00000088; - memctl->memc_mcr = 0x80004105; - - memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */ + /*Then we need two refresh cycles*/ + memctl->memc_mamr = CFG_MAMR_48_SDR | MAMR_TLFA_2X; + memctl->memc_mcr = (MCR_OP_RUN | MCR_UPM_A | MCR_MB_CS2 | \ + MCR_MLCF(2) | MCR_MAD(0x30)); + + /*Mode register programming*/ + memctl->memc_mar = 0x00000088; /*CAS Latency = 2 and burst length = 4*/ + memctl->memc_mcr = (MCR_OP_RUN | MCR_UPM_A | MCR_MB_CS2 | \ + MCR_MLCF(1) | MCR_MAD(0x1C)); + + /* That should do it, just enable the periodic refresh in burst of 4*/ + memctl->memc_mamr = CFG_MAMR_48_SDR | MAMR_TLFA_4X; + memctl->memc_mamr |= (MAMR_PTAE | MAMR_GPL_B4DIS); - udelay(100); - -#if 0 - size_b0 = dram_size (CFG_MAMR_48_SDR_4, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE); -#else size_b0 = 16*1024*1024; -#endif /* - * No bank 1 - * + * No bank 1 or 3 * invalidate bank */ + memctl->memc_br1 = 0; memctl->memc_br3 = 0; - return (size_b0); -} - -/* ------------------------------------------------------------------------- */ + upmconfig(UPMB, (uint *)dsp_disp_table, + sizeof(dsp_disp_table)/sizeof(uint)); -#if 0 -/* - * Check memory range for valid RAM. A simple memory test determines - * the actually available RAM size between addresses `base' and - * `base + maxsize'. Some (not all) hardware errors are detected: - * - short between address lines - * - short between data lines - */ + memctl->memc_or4 = CFG_OR4; + memctl->memc_br4 = CFG_BR4; -static long int dram_size (long int mamr_value, long int *base, long int maxsize) -{ - volatile immap_t *immap = (immap_t *)CFG_IMMR; - volatile memctl8xx_t *memctl = &immap->im_memctl; - volatile long int *addr; - ulong cnt, val; - ulong save[32]; /* to make test non-destructive */ - unsigned char i = 0; - - memctl->memc_mamr = mamr_value; - - for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) { - addr = base + cnt; /* pointer arith! */ - - save[i++] = *addr; - *addr = ~cnt; - } - - /* write 0 to base address */ - addr = base; - save[i] = *addr; - *addr = 0; - - /* check at base address */ - if ((val = *addr) != 0) { - *addr = save[i]; - return (0); - } - - for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) { - addr = base + cnt; /* pointer arith! */ - - val = *addr; - *addr = save[--i]; - - if (val != (~cnt)) { - return (cnt * sizeof(long)); - } - } - return (maxsize); + return (size_b0); } -#endif /* 0 */ + diff --git a/board/flagadm/flash.c b/board/flagadm/flash.c index e581920..7359ccf 100644 --- a/board/flagadm/flash.c +++ b/board/flagadm/flash.c @@ -23,28 +23,18 @@ #include #include +#include flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ -#if defined(CFG_ENV_IS_IN_FLASH) -# ifndef CFG_ENV_ADDR -# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET) -# endif -# ifndef CFG_ENV_SIZE -# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE -# endif -# ifndef CFG_ENV_SECT_SIZE -# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE -# endif -#endif - /*----------------------------------------------------------------------- * Functions */ -static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static ulong flash_recognize (vu_long *base); static int write_word (flash_info_t *info, ulong dest, ulong data); -static void flash_get_offsets (ulong base, flash_info_t *info); -static void sector_protect(flash_info_t *info, int on, int s_start, int s_end); +static void flash_get_geometry (vu_long *base, flash_info_t *info); +static void flash_unprotect(flash_info_t *info); +static int _flash_real_protect(flash_info_t *info, long idx, int prot); /*----------------------------------------------------------------------- */ @@ -53,44 +43,33 @@ unsigned long flash_init (void) { volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile memctl8xx_t *memctl = &immap->im_memctl; -// volatile ip860_bcsr_t *bcsr = (ip860_bcsr_t *)BCSR_BASE; - unsigned long size; int i; - - /* Init: enable write, - * or we cannot even write flash commands - */ -// bcsr->bd_ctrl |= BD_CTRL_FLWE; + int rec; for (i=0; imemc_or0 = CFG_OR_TIMING_FLASH | (-size & 0xFFFF8000); -// memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | -// (memctl->memc_br0 & ~(BR_BA_MSK)); - memctl->memc_or0 = CFG_OR0_PRELIM; - memctl->memc_br0 = CFG_BR0_PRELIM; + memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-flash_info[0].size & 0xFFFF8000); + memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | + (memctl->memc_br0 & ~(BR_BA_MSK)); - /* Re-do sizing to get full correct info */ - size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]); + rec = flash_recognize((vu_long*)CFG_FLASH_BASE); - flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]); + if (rec == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + flash_info[0].size, flash_info[0].size >> 20); + } - flash_info[0].size = size; + /*Unprotect all the flash memory*/ + flash_unprotect(&flash_info[0]); - sector_protect(&flash_info[0], 0, 0,CFG_MAX_FLASH_SECT); - *(vu_short*)CFG_FLASH_BASE = 0xFF; //Reset flash + *((vu_short*)CFG_FLASH_BASE) = 0xffff; #if CFG_MONITOR_BASE >= CFG_FLASH_BASE /* monitor protection ON by default */ @@ -103,28 +82,124 @@ unsigned long flash_init (void) #ifdef CFG_ENV_IS_IN_FLASH /* ENV protection ON by default */ flash_protect(FLAG_PROTECT_SET, - CFG_ENV_ADDR, - CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1, + CFG_ENV_OFFSET, + CFG_ENV_OFFSET+CFG_ENV_SIZE-1, &flash_info[0]); #endif - return (size); + return (flash_info[0].size); } -/*----------------------------------------------------------------------- - */ -static void flash_get_offsets (ulong base, flash_info_t *info) + +int flash_get_protect_status(flash_info_t * info, long idx) { - int i; + vu_short * base; + ushort res; + +#if DEBUG + printf ("\n Attempting to set protection info with %d sectors\n", + info->sector_count); +#endif + + + base = (vu_short*)info->start[idx]; + + *(base) = 0xffff; + + *(base + 0x55) = 0x0098; + res = base[0x2]; + + *(base) = 0xffff; + + if(res != 0) + res = 1; + + return res; +} + +static void flash_get_geometry (vu_long *base, flash_info_t *info) +{ + int i,j; + ulong ner = 0; + vu_short * sb = (vu_short*)base; + ulong offset = (ulong)base; + + /* Read Device geometry */ + + *sb = 0xffff; + + *sb = 0x0090; + + info->flash_id = ((ulong)base[0x0]); +#if DEBUG + printf("Id is %x\n", (uint)(ulong)info->flash_id); +#endif + + *sb = 0xffff; + + *(sb+0x55) = 0x0098; + + info->size = 1 << (sb[0x27]); /* Read flash size */ + +#if DEBUG + printf("Size is %x\n", (uint)(ulong)info->size); +#endif + + *sb = 0xffff; + + *(sb + 0x55) = 0x0098; + ner = sb[0x2c] ; /*Number of erase regions*/ + +#if DEBUG + printf("Number of erase regions %x\n", (uint)ner); +#endif - for (i = 0; i < 8; i++) { - info->start[i] = base; - base += 0x00002000; + info->sector_count = 0; + + for(i = 0; i < ner; i++) { + uint s; + uint count; + uint t1,t2,t3,t4; + + *sb = 0xffff; + + *(sb + 0x55) = 0x0098; + + t1 = sb[0x2d + i*4]; + t2 = sb[0x2e + i*4]; + t3 = sb[0x2f + i*4]; + t4 = sb[0x30 + i*4]; + + /*sector count*/ + count = ((t1 & 0x00ff) | (((t2 & 0x00ff) << 8) & 0xff00) )+ 1; + /*Sector size*/ + s = ((t3 & 0x00ff) | (((t4 & 0x00ff) << 8) & 0xff00)) * 256; + +#if DEBUG + printf("count and size %x, %x\n", count, s); + printf("sector count for erase region %d is %d\n", i, count); +#endif + for(j = 0; j < count; j++) { +#if DEBUG + printf("%x, ", (uint)offset); +#endif + info->start[ info->sector_count + j] = offset; + offset += s; + } + info->sector_count += count; } - /* set up sector start address table */ - for (; i < info->sector_count; i++) { - info->start[i] = base; - base += 0x00010000; + + if ((offset - (ulong)base) != info->size) { + printf ("WARNING " + "reported size %x does not match to calculted size %x.\n", + (uint)info->size, (uint)(offset - (ulong)base) ); } + + /* Next check if there are any sectors protected.*/ + + for(i = 0; i < info->sector_count; i++) + info->protect[i] = flash_get_protect_status(info, i); + + *sb = 0xffff; } /*----------------------------------------------------------------------- @@ -139,15 +214,24 @@ void flash_print_info (flash_info_t *info) } switch (info->flash_id & FLASH_VENDMASK) { - case FLASH_MAN_INTEL: printf ("Intel "); break; - default: printf ("Unknown Vendor "); break; + case INTEL_MANUFACT & FLASH_VENDMASK: + printf ("Intel "); + break; + default: + printf ("Unknown Vendor "); + break; } switch (info->flash_id & FLASH_TYPEMASK) { - case FLASH_28F320C3: printf ("28F320RC3(4 MB)\n"); - break; - default: printf ("Unknown Chip Type\n"); - break; + case INTEL_ID_28F320C3 & FLASH_TYPEMASK: + printf ("28F320RC3(4 MB)\n"); + break; + case INTEL_ID_28F320JA3 & FLASH_TYPEMASK: + printf("28F320JA3 (4 MB)\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; } printf (" Size: %ld MB in %d Sectors\n", @@ -155,10 +239,10 @@ void flash_print_info (flash_info_t *info) printf (" Sector Start Addresses:"); for (i=0; isector_count; ++i) { - if ((i % 5) == 0) - printf ("\n "); - printf (" %08lX%s", - info->start[i], + if ((i % 4) == 0) + puts ("\n "); + printf (" %02d %08lX%s", + i, info->start[i], info->protect[i] ? " (RO)" : " " ); } @@ -166,81 +250,30 @@ void flash_print_info (flash_info_t *info) return ; } -/*----------------------------------------------------------------------- - */ - - -/*----------------------------------------------------------------------- - */ - -/* - * The following code cannot be run from FLASH! - */ - -static ulong flash_get_size (vu_long *addr, flash_info_t *info) +static ulong flash_recognize (vu_long *base) { - short i; - ulong value; - ulong base = (ulong)addr; - - /* Write "Intelligent Identifier" command: read Manufacturer ID */ - *addr = 0x90909090; - - value = addr[0]; - switch (value & 0x00FF0000) - { - case (MT_MANUFACT & 0x00FF0000): /* MT or => Intel */ - case (INTEL_ALT_MANU & 0x00FF0000): - info->flash_id = FLASH_MAN_INTEL; - break; - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - return (0); /* no or unknown flash */ - } + ulong id; + ulong res = FLASH_UNKNOWN; + vu_short * sb = (vu_short*)base; -// value = addr[1]; /* device ID */ + *sb = 0xffff; - switch (value & 0x0000FFFF) { - case (INTEL_ID_28F320C3 & 0x0000FFFF): - info->flash_id += FLASH_28F320C3; - info->sector_count = 71; - info->size = 0x00400000; - break; /* => 4 MB */ + *sb = 0x0090; + id = base[0]; + switch (id & FLASH_VENDMASK) { + case (MT_MANUFACT & FLASH_VENDMASK): /* MT or => Intel */ + case (INTEL_ALT_MANU & FLASH_VENDMASK): + res = FLASH_MAN_INTEL; + break; default: - info->flash_id = FLASH_UNKNOWN; - return (0); /* => no or unknown flash */ - - } - - /* set up sector start address table */ - /*Should be done through the region codes.*/ - - for(i = 0; i < 8; i++) { - //first 8 sectors are 8KB - info->start[i] = base + (i * 0x00002000); - info->protect[i] = 0; - } - - for (; i < info->sector_count; i++) { - //Next 63 sectors - info->start[i] = base + (i * 0x00010000); - /* don't know how to check sector protection */ - info->protect[i] = 0; + res = FLASH_UNKNOWN; + break; } - /* - * Prevent writes to uninitialized FLASH. - */ - if (info->flash_id != FLASH_UNKNOWN) { - addr = (vu_long *)info->start[0]; - - *addr = 0xFFFFFFFF; /* reset bank to read array mode */ - } + *sb = 0xffff; - return (info->size); + return res; } /*-----------------------------------------------------------------------*/ @@ -255,7 +288,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) int flash_decode_status_bits(char status) { int err = 0; - + if(!(status & INTEL_FLASH_STATUS_WSMS)) { printf("Busy\n"); err = -1; @@ -308,7 +341,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_short *addr; int flag, prot, sect; - ulong start, now, last; + ulong start, now; int rcode = 0; if ((s_first < 0) || (s_first > s_last)) { @@ -320,7 +353,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) return 1; } - if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) { + if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); return 1; @@ -353,90 +386,64 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) flag = disable_interrupts(); /* Single Block Erase Command */ - *addr = 0x20; + *addr = 0x0020; /* Confirm */ - *addr = 0xD0; + *addr = 0x00D0; /* Resume Command, as per errata update */ - *addr = 0xD0; + *addr = 0x00D0; /* re-enable interrupts if necessary */ if (flag) enable_interrupts(); - tmp = (short)*addr & 0x00FF; + *addr = 0x0070; /*Read status register command*/ + tmp = (short)*addr & 0x00FF; /* Read the status */ while (!(tmp & INTEL_FLASH_STATUS_WSMS)) { if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + *addr = 0x0050; /* Reset the status register */ + *addr = 0xffff; printf ("Timeout\n"); - *addr = 0xFFFF; /* reset bank */ return 1; } /* show that we're waiting */ - if ((now - last) > 1000) { /* every second */ + if ((now - start) > 1000) { /* every second */ putc ('.'); - last = now; - } - udelay(80); - tmp = (short)*addr & 0x00FF; - if(flash_decode_status_bits(tmp|INTEL_FLASH_STATUS_WSMS)==-1 - && (tmp & INTEL_FLASH_STATUS_WSMS)) { - printf("Error erasing\n"); - rcode++; - break; } + udelay(100000); /* 100 ms */ + *addr = 0x0070; /*Read status register command*/ + tmp = (short)*addr & 0x00FF; /* Read status */ + start = get_timer(0); } + if( tmp & INTEL_FLASH_STATUS_ES ) + flash_decode_status_bits(tmp); + + *addr =0x0050; /*Clear status register*/ } } + *addr = 0x0050; /* Reset the status register */ /* reset to read mode */ - *addr = 0xFFFF; /* reset bank */ + *addr = 0xffff; printf (" done\n"); return rcode; } -void sector_protect (flash_info_t *info, int on, int s_first, int s_last) +static void flash_unprotect (flash_info_t *info) { - vu_short *addr; - int flag, sect; - char cmd; - - if ((s_first < 0) || (s_first > s_last)) { - return; - } + /*We can only unprotect the whole flash at once*/ + /*Therefore we must prevent the _flash_real_protect()*/ + /*from re-protecting sectors, that ware protected before */ + /*we called flash_real_protect();*/ - if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) { - printf ("Can't erase unknown flash type %08lx - aborted\n", - info->flash_id); - return; - } - - if(on == 0) { - //Unlock the sector - cmd = 0xD0; - } - else { - //Lock the sector - cmd = 0x01; - } - - for (sect = s_first; sect<=s_last; sect++) { - addr = (vu_short *)(info->start[sect]); - - /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts(); - - /* Unlock block*/ - *addr = 0x60; - /* Confirm */ - *addr = cmd; + int i; - /* re-enable interrupts if necessary */ - if (flag) - enable_interrupts(); - } + for(i = 0; i < info->sector_count; i++) + info->protect[i] = 0; - /* reset to read mode */ - *addr = 0xFF; /* reset bank */ +#ifdef CFG_FLASH_PROTECTION + _flash_real_protect(info, 0, 0); +#endif } /*----------------------------------------------------------------------- @@ -532,10 +539,9 @@ static int write_word (flash_info_t *info, ulong dest, ulong da) /* Disable interrupts which might cause a timeout here */ flag = disable_interrupts(); - for(i = 0; i < 2; i++) - { + for(i = 0; i < 2; i++) { /* Write Command */ - *addr = 0x10; + *addr = 0x0010; /* Write Data */ *addr = d[i]; @@ -547,11 +553,13 @@ static int write_word (flash_info_t *info, ulong dest, ulong da) /* data polling for D7 */ start = get_timer (0); flag = 0; - while (((csr = *addr) & INTEL_FLASH_STATUS_WSMS)!=INTEL_FLASH_STATUS_WSMS) { + *addr = 0x0070; /*Read statusregister command */ + while (((csr = *addr) & INTEL_FLASH_STATUS_WSMS) != INTEL_FLASH_STATUS_WSMS) { if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { flag = 1; break; } + *addr = 0x0070; /*Read statusregister command */ } if (csr & INTEL_FLASH_STATUS_PSS) { printf ("CSR indicates write error (%0x) at %08lx\n", @@ -560,14 +568,122 @@ static int write_word (flash_info_t *info, ulong dest, ulong da) } /* Clear Status Registers Command */ - *addr = 0x50; + *addr = 0x0050; /* Reset to read array mode */ - *addr = 0xFF; + *addr = 0xffff; addr++; } return (flag); } -/*----------------------------------------------------------------------- - */ +int flash_real_protect(flash_info_t *info, long idx, int prot) +{ + int i; + + if(prot == 0) { + /* Unprotect one sector, which means unprotect all flash + * and reprotect the other protected sectors. + */ + _flash_real_protect(info, 0, 0); /* Unprotects the whole flash*/ + info->protect[idx] = 0; + + for(i = 0; i < info->sector_count; i++) { + if(info->protect[i]) + _flash_real_protect(info, i, 1); + } + } else { + /* We can protect individual sectors */ + _flash_real_protect(info, idx, 1); + } + + for( i = 0; i < info->sector_count; i++) + info->protect[i] = flash_get_protect_status(info, i); + + return 0; +} + +static int _flash_real_protect(flash_info_t *info, long idx, int prot) +{ + vu_short *addr; + int flag; + ushort cmd; + ushort tmp; + ulong now, start; + + if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) { + printf ("Can't change protection for unknown flash type %08lx - aborted\n", + info->flash_id); + return -1; + } + + if(prot == 0) { + /* Unlock the sector */ + cmd = 0x00D0; + } else { + /* Lock the sector */ + cmd = 0x0001; + } + + addr = (vu_short *)(info->start[idx]); + + /* If chip is busy, wait for it */ + start = get_timer(0); + *addr = 0x0070; /*Read status register command*/ + tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/ + while(!(tmp & INTEL_FLASH_STATUS_WSMS)) { + /*Write State Machine Busy*/ + /*Wait untill done or timeout.*/ + if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) { + *addr = 0x0050; /* Reset the status register */ + *addr = 0xffff; /* Reset the chip */ + printf ("TTimeout\n"); + return 1; + } + *addr = 0x0070; + tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/ + start = get_timer(0); + } + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Unlock block*/ + *addr = 0x0060; + + *addr = cmd; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + start = get_timer(0); + *addr = 0x0070; /*Read status register command*/ + tmp = ((ushort)(*addr)) & 0x00FF; /* Read the status */ + while (!(tmp & INTEL_FLASH_STATUS_WSMS)) { + /* Write State Machine Busy */ + if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) { + *addr = 0x0050; /* Reset the status register */ + *addr = 0xffff; + printf ("Timeout\n"); + return 1; + } + /* show that we're waiting */ + if ((now - start) > 1000) { /* every second */ + putc ('.'); + } + udelay(100000); /* 100 ms */ + *addr = 0x70; /*Read status register command*/ + tmp = (short)*addr & 0x00FF; /* Read status */ + start = get_timer(0); + } + if( tmp & INTEL_FLASH_STATUS_PS ) + flash_decode_status_bits(tmp); + + *addr =0x0050; /*Clear status register*/ + + /* reset to read mode */ + *addr = 0xffff; + + return 0; +} diff --git a/board/flagadm/ppcboot.lds b/board/flagadm/ppcboot.lds index 8e390cc..6711f2b 100644 --- a/board/flagadm/ppcboot.lds +++ b/board/flagadm/ppcboot.lds @@ -53,18 +53,7 @@ SECTIONS .plt : { *(.plt) } .text : { - /* WARNING - the following is hand-optimized to fit within */ - /* the sector layout of our flash chips! XXX FIXME XXX */ - cpu/mpc8xx/start.o (.text) - common/dlmalloc.o (.text) - ppc/ppcstring.o (.text) - ppc/vsprintf.o (.text) - ppc/crc32.o (.text) - ppc/zlib.o (.text) - - . = env_offset; - common/environment.o(.text) *(.text) *(.fixup) diff --git a/board/icu862/flash.c b/board/icu862/flash.c index 7721653..70a4738 100644 --- a/board/icu862/flash.c +++ b/board/icu862/flash.c @@ -56,8 +56,7 @@ unsigned long flash_init (void) int i; /* Init: no FLASHes known */ - for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) - { + for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) { flash_info[i].flash_id = FLASH_UNKNOWN; } @@ -65,16 +64,20 @@ unsigned long flash_init (void) size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); - if (flash_info[0].flash_id == FLASH_UNKNOWN) - { - printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",size_b0, size_b0<<20); + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, + size_b0 >> 20); } if (FLASH_BASE1_PRELIM != 0x0) { size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]); if (size_b1 > size_b0) { - printf ("## ERROR: Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",size_b1, size_b1<<20,size_b0, size_b0<<20); + printf ("## ERROR: Bank 1 (0x%08lx = %ld MB)" + " > Bank 0 (0x%08lx = %ld MB)\n", + size_b1, size_b1 >> 20, + size_b0, size_b0 >> 20); flash_info[0].flash_id = FLASH_UNKNOWN; flash_info[1].flash_id = FLASH_UNKNOWN; @@ -146,67 +149,62 @@ void flash_print_info (flash_info_t *info) { int i; - if (info->flash_id == FLASH_UNKNOWN) - { - printf ("missing or unknown FLASH type\n"); + if (info->flash_id == FLASH_UNKNOWN) { + puts ("missing or unknown FLASH type\n"); return; } - switch (info->flash_id & FLASH_VENDMASK) - { - case FLASH_MAN_AMD: printf ("AMD "); break; - case FLASH_MAN_FUJ: printf ("FUJITSU "); break; - case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break; - default: printf ("Unknown Vendor "); break; + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: puts ("AMD "); break; + case FLASH_MAN_FUJ: puts ("FUJITSU "); break; + case FLASH_MAN_BM: puts ("BRIGHT MICRO "); break; + default: puts ("Unknown Vendor "); break; } - switch (info->flash_id & FLASH_TYPEMASK) - { - case FLASH_AM040: printf ("29F040 or 29LV040 (4 Mbit, uniform sectors)\n"); - break; - case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); - break; - case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n"); - break; - case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); - break; - case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n"); - break; - case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); - break; - case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n"); - break; - case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); - break; - case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n"); - break; - case FLASH_AM033C: printf ("AM29LV033C (32 Mbit)\n"); - break; - default: printf ("Unknown Chip Type\n"); - break; + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM040: puts ("29F040/29LV040 (4 Mbit, uniform sectors)\n"); + break; + case FLASH_AM400B: puts ("AM29LV400B (4 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM400T: puts ("AM29LV400T (4 Mbit, top boot sector)\n"); + break; + case FLASH_AM800B: puts ("AM29LV800B (8 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM800T: puts ("AM29LV800T (8 Mbit, top boot sector)\n"); + break; + case FLASH_AM160B: puts ("AM29LV160B (16 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM160T: puts ("AM29LV160T (16 Mbit, top boot sector)\n"); + break; + case FLASH_AM320B: puts ("AM29LV320B (32 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM320T: puts ("AM29LV320T (32 Mbit, top boot sector)\n"); + break; + case FLASH_AM033C: puts ("AM29LV033C (32 Mbit)\n"); + break; + default: puts ("Unknown Chip Type\n"); + break; } - printf (" Size: %ld MB in %d Sectors\n",info->size >> 20, info->sector_count); + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); - printf (" Sector Start Addresses:"); + puts (" Sector Start Addresses:"); - for (i=0; isector_count; ++i) - { - if ((i % 5) == 0) - { - printf ("\n "); + for (i=0; isector_count; ++i) { + if ((i % 5) == 0) { + puts ("\n "); } - printf (" %08lX%s", info->start[i],info->protect[i] ? " (RO)" : " " ); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); } - printf ("\n"); + puts ("\n"); } -/*----------------------------------------------------------------------- - */ - - /*----------------------------------------------------------------------- */ @@ -235,89 +233,87 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) value = addr[0]; - switch (value + (value << 16)) - { - case AMD_MANUFACT: - info->flash_id = FLASH_MAN_AMD; + switch (value + (value << 16)) { + case AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; break; - case FUJ_MANUFACT: - info->flash_id = FLASH_MAN_FUJ; + case FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; break; - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + break; } value = addr[1]; /* device ID */ - switch (value) - { - case AMD_ID_F040B: - info->flash_id += FLASH_AM040; - info->sector_count = 8; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV400T: - info->flash_id += FLASH_AM400T; - info->sector_count = 11; - info->size = 0x00100000; - break; /* => 1 MB */ - - case AMD_ID_LV400B: - info->flash_id += FLASH_AM400B; - info->sector_count = 11; - info->size = 0x00100000; - break; /* => 1 MB */ - - case AMD_ID_LV800T: - info->flash_id += FLASH_AM800T; - info->sector_count = 19; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV800B: - info->flash_id += FLASH_AM800B; - info->sector_count = 19; - info->size = 0x00200000; - break; /* => 2 MB */ - - case AMD_ID_LV160T: - info->flash_id += FLASH_AM160T; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 4 MB */ - - case AMD_ID_LV160B: - info->flash_id += FLASH_AM160B; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 4 MB */ + switch (value) { + case AMD_ID_F040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x00200000; + break; /* => 2 MB */ + + case AMD_ID_LV400T: + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case AMD_ID_LV400B: + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00100000; + break; /* => 1 MB */ + + case AMD_ID_LV800T: + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00200000; + break; /* => 2 MB */ + + case AMD_ID_LV800B: + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00200000; + break; /* => 2 MB */ + + case AMD_ID_LV160T: + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ + + case AMD_ID_LV160B: + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00400000; + break; /* => 4 MB */ #if 0 /* enable when device IDs are available */ - case AMD_ID_LV320T: - info->flash_id += FLASH_AM320T; - info->sector_count = 67; - info->size = 0x00800000; - break; /* => 8 MB */ - - case AMD_ID_LV320B: - info->flash_id += FLASH_AM320B; - info->sector_count = 67; - info->size = 0x00800000; - break; /* => 8 MB */ + case AMD_ID_LV320T: + info->flash_id += FLASH_AM320T; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ + + case AMD_ID_LV320B: + info->flash_id += FLASH_AM320B; + info->sector_count = 67; + info->size = 0x00800000; + break; /* => 8 MB */ #endif - case AMD_ID_LV033C: - info->flash_id += FLASH_AM033C; - info->sector_count = 64; - info->size = 0x01000000; - break; /* => 16Mb */ - default: - info->flash_id = FLASH_UNKNOWN; - return (0); /* => no or unknown flash */ + case AMD_ID_LV033C: + info->flash_id += FLASH_AM033C; + info->sector_count = 64; + info->size = 0x01000000; + break; /* => 16Mb */ + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ } @@ -347,8 +343,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) #endif /* check for protected sectors */ - for (i = 0; i < info->sector_count; i++) - { + for (i = 0; i < info->sector_count; i++) { /* read sector protection at sector address, (A7 .. A0) = 0x02 */ /* D0 = 1 if protected */ addr = (volatile unsigned long *)(info->start[i]); @@ -356,8 +351,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /* We don't know why it happens, but on ICU Board * * for AMD29033C flash we need to resend the command of * * reading flash protection for upper 8 Mb of flash */ - if ( i == 32 ) - { + if ( i == 32 ) { addr[0x0555] = 0xAAAAAAAA; addr[0x02AA] = 0x55555555; addr[0x0555] = 0x90909090; @@ -369,8 +363,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /* * Prevent writes to uninitialized FLASH. */ - if (info->flash_id != FLASH_UNKNOWN) - { + if (info->flash_id != FLASH_UNKNOWN) { addr = (volatile unsigned long *)info->start[0]; #if 0 *addr = 0x00F000F0; /* reset bank */ @@ -394,16 +387,16 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { - printf ("- missing\n"); + puts ("- missing\n"); } else { - printf ("- no sectors to erase\n"); + puts ("- no sectors to erase\n"); } return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { - printf ("Can't erase unknown flash type - aborted\n"); + puts ("Can't erase unknown flash type - aborted\n"); return 1; } @@ -418,7 +411,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) printf ("- Warning: %d protected sectors will not be erased!\n", prot); } else { - printf ("\n"); + puts ("\n"); } l_sect = -1; @@ -476,7 +469,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) #endif { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { - printf ("Timeout\n"); + puts ("Timeout\n"); return 1; } /* show that we're waiting */ @@ -495,7 +488,7 @@ DONE: addr[0] = 0xF0F0F0F0; /* reset bank */ #endif - printf (" done\n"); + puts (" done\n"); return 0; } diff --git a/board/westel/amx860/flash.c b/board/westel/amx860/flash.c index f6b486e..a973e06 100644 --- a/board/westel/amx860/flash.c +++ b/board/westel/amx860/flash.c @@ -142,6 +142,7 @@ unsigned long flash_init (void) &flash_info[0]); #endif +#ifndef CONFIG_AMX_RAM_EXT /* can't have RAM extension _and_ 2nd flash bank */ if (size_b1) { memctl->memc_or1 = (CFG_OR1_PRELIM & ~OR_AM_MSK) | (-size_b1 & OR_AM_MSK); @@ -159,22 +160,24 @@ unsigned long flash_init (void) flash_get_offsets (CFG_FLASH_BASE + size_b0, &flash_info[1]); -#if CFG_MONITOR_BASE >= CFG_FLASH_BASE +# if CFG_MONITOR_BASE >= CFG_FLASH_BASE /* monitor protection ON by default */ flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE, CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[1]); -#endif +# endif -#ifdef CFG_ENV_IS_IN_FLASH +# ifdef CFG_ENV_IS_IN_FLASH /* ENV protection ON by default */ flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR, CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1, &flash_info[1]); -#endif - } else { +# endif + } else +#endif /* CONFIG_AMX_RAM_EXT */ + { memctl->memc_br1 = 0; /* invalidate bank */ memctl->memc_or1 = 0; /* invalidate bank */ diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index ef614c6..4c45494 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -41,14 +41,13 @@ #if defined(CONFIG_8xx) #include #endif +#ifdef CFG_HUSH_PARSER +#include +#endif #if defined(CONFIG_AUTOSCRIPT) || \ (CONFIG_COMMANDS & CFG_CMD_AUTOSCRIPT) -#ifdef CFG_HUSH_PARSER -extern int parse_string_outer(char *s, int end); -#endif - extern image_header_t header; /* from cmd_bootm.c */ int autoscript(bd_t *bd, ulong addr) @@ -118,7 +117,8 @@ autoscript(bd_t *bd, ulong addr) #ifndef CFG_HUSH_PARSER rcode = run_command(cmd, bd, 0); #else - rcode = parse_string_outer(cmd, 1); + rcode = parse_string_outer(cmd, FLAG_PARSE_SEMICOLON + | FLAG_EXIT_FROM_LOOP); #endif free(cmd); return rcode; diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 058e18a..e82b66e 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -36,7 +36,7 @@ #endif #ifdef CFG_HUSH_PARSER -extern int parse_string_outer(char *s, int end); +#include #endif int gunzip (void *, int, unsigned char *, int *); @@ -603,7 +603,8 @@ int do_bootd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #ifndef CFG_HUSH_PARSER if (run_command (getenv ("bootcmd"), bd, flag) == -1) rcode = 1; #else - if (parse_string_outer(getenv("bootcmd"), 1) != 0 ) rcode = 1; + if (parse_string_outer(getenv("bootcmd"), + FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0 ) rcode = 1; #endif return rcode; } diff --git a/common/hush.c b/common/hush.c index f08911c..87c61a4 100644 --- a/common/hush.c +++ b/common/hush.c @@ -92,6 +92,7 @@ #include /* malloc, free, realloc*/ #include /* isalpha, isdigit */ #include /* readline */ +#include #include /* find_cmd */ #include /* do_bootd */ #endif @@ -127,6 +128,11 @@ #endif #endif #define SPECIAL_VAR_SYMBOL 03 +#ifndef __PPCBOOT__ +#define FLAG_EXIT_FROM_LOOP 1 +#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ +#define FLAG_NOT_PARSE_SEMICOLON (1 << 2) /* symbol ';' is common for parser */ +#endif #ifdef __PPCBOOT__ #define EXIT_SUCCESS 0 @@ -204,6 +210,7 @@ struct p_context { reserved_style w; int old_flag; /* for figuring out valid reserved words */ struct p_context *stack; + int type; /* define type of parser : ";" common or special symbol */ /* How about quoting status? */ }; @@ -389,6 +396,7 @@ static void *xrealloc(void *ptr, size_t size); /* function prototypes for builtins */ static int builtin_cd(struct child_prog *child); static int builtin_env(struct child_prog *child); +static int builtin_eval(struct child_prog *child); static int builtin_exec(struct child_prog *child); static int builtin_exit(struct child_prog *child); static int builtin_export(struct child_prog *child); @@ -464,20 +472,17 @@ static int process_command_subs(o_string *dest, struct p_context *ctx, struct in static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch); #endif static char *lookup_param(char *src); +static char *make_string(char **inp); static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input); #ifndef __PPCBOOT__ static int parse_string(o_string *dest, struct p_context *ctx, const char *src); #endif static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger); /* setup: */ -static int parse_stream_outer(struct in_str *inp, int end); +static int parse_stream_outer(struct in_str *inp, int flag); #ifndef __PPCBOOT__ -static int parse_string_outer(const char *s, int end); +static int parse_string_outer(const char *s, int flag); static int parse_file_outer(FILE *f); -#else -int ppcboot_hush_start(bd_t *bd); -int parse_string_outer(char *s, int end); -int parse_file_outer(void); #endif #ifndef __PPCBOOT__ /* job management: */ @@ -507,7 +512,7 @@ static struct built_in_command bltins[] = { {"cd", "Change working directory", builtin_cd}, {"continue", "Continue for, while or until loop", builtin_not_written}, {"env", "Print all environment variables", builtin_env}, - {"eval", "Construct and run shell command", builtin_not_written}, + {"eval", "Construct and run shell command", builtin_eval}, {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec}, {"exit", "Exit from shell()", builtin_exit}, @@ -538,6 +543,21 @@ static const char *set_cwd(void) return cwd; } +/* built-in 'eval' handler */ +static int builtin_eval(struct child_prog *child) +{ + char *str = NULL; + int rcode = EXIT_SUCCESS; + + if (child->argv[1]) { + str = make_string(child->argv + 1); + parse_string_outer(str, FLAG_EXIT_FROM_LOOP | + FLAG_PARSE_SEMICOLON); + free(str); + rcode = last_return_code; + } + return rcode; +} /* built-in 'cd ' handler */ static int builtin_cd(struct child_prog *child) @@ -1503,14 +1523,12 @@ static int run_pipe_real(struct pipe *pi) struct child_prog *child; struct built_in_command *x; char *p; - int n; #else int nextin; int flag = 0; struct child_prog *child; cmd_tbl_t *cmdtp; char *p; - int n; #endif nextin = 0; @@ -1584,34 +1602,12 @@ static int run_pipe_real(struct pipe *pi) } } if (child->sp) { - char *p1 = NULL, *p2; - int size = 0; - int len = 0; - /* Fake quotation marks surrounding the echo argument */ - if (!(strcmp(child->argv[i], "echo"))) { - size++; - if (!child->argv[i + 2]) size++; - } - for (n = i; child->argv[n]; n++) { - p2 = insert_var_value(child->argv[n]); - p1 = xrealloc(p1, (len + 1 + strlen(p2))); - if (len) { - strcat(p1, " "); - } else { - *p1 = '\0'; - } - if (n == i + 1 && size) strcat(p1, "\""); - strcat(p1, p2); - len = strlen(p1) + 2 + size; - if (p2 != child->argv[n]) free(p2); - } - if (size) strcat(p1, "\""); - while ((p2 = strchr(p1, '\n'))) { - *p2 = ' '; - } - strcat(p1, "\n"); - parse_string_outer(p1, 1); - free(p1); + char * str = NULL; + + str = make_string((child->argv + i)); + parse_string_outer(str, FLAG_EXIT_FROM_LOOP | + FLAG_NOT_PARSE_SEMICOLON); + free(str); return last_return_code; } #ifndef __PPCBOOT__ @@ -1631,6 +1627,14 @@ static int run_pipe_real(struct pipe *pi) * things seem to work with glibc. */ setup_redirects(child, squirrel); #else + /* check ";", because ,example , argv consist from + * "help;flinfo" must not execute + */ + if (strchr(child->argv[i], ';')) { + printf ("Unknown command '%s' - try 'help' or use 'run' command\n", + child->argv[i]); + return -1; + } /* Look up command in command table */ if ((cmdtp = find_cmd(child->argv[i])) == NULL) { printf ("Unknown command '%s' - try 'help'\n", child->argv[i]); @@ -2326,6 +2330,7 @@ static void initialize_context(struct p_context *ctx) #ifdef __PPCBOOT__ ctx->old_flag=0; #endif + ctx->type=0; done_command(ctx); /* creates the memory for working child */ } @@ -2381,7 +2386,7 @@ int reserved_word(o_string *dest, struct p_context *ctx) } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<code))) { syntax(); ctx->w = RES_SNTX; - b_reset (dest); + b_reset(dest); return 1; } ctx->w=r->code; @@ -2432,7 +2437,7 @@ static int done_word(o_string *dest, struct p_context *ctx) syntax(); return 1; /* syntax error, groups and arglists don't mix */ } - if (!child->argv) { + if (!child->argv && !(ctx->type & FLAG_NOT_PARSE_SEMICOLON)) { debug_printf("checking %s for reserved-ness\n",dest->data); if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX; } @@ -3041,7 +3046,7 @@ void update_ifs_map(void) /* most recursion does not come through here, the exeception is * from builtin_source() */ -int parse_stream_outer(struct in_str *inp, int end) +int parse_stream_outer(struct in_str *inp, int flag) { struct p_context ctx; @@ -3052,13 +3057,20 @@ int parse_stream_outer(struct in_str *inp, int end) #endif do { initialize_context(&ctx); + ctx.type = flag; update_ifs_map(); + if ((flag & FLAG_NOT_PARSE_SEMICOLON)) mapset(";", 0); inp->promptmode=1; rcode = parse_stream(&temp, &ctx, inp, '\n'); #ifdef __PPCBOOT__ if (rcode == 1) flag_repeat = 0; #endif - if (rcode != 1 && ctx.old_flag != 0) syntax(); + if (rcode != 1 && ctx.old_flag != 0) { + syntax(); +#ifdef __PPCBOOT__ + flag_repeat = 0; +#endif + } if (rcode != 1 && ctx.old_flag == 0) { done_word(&temp, &ctx); done_pipe(&ctx,PIPE_SEQ); @@ -3083,7 +3095,7 @@ int parse_stream_outer(struct in_str *inp, int end) free_pipe_list(ctx.list_head,0); } b_free(&temp); - } while (rcode != -1 && end != 1); /* loop on syntax errors, return on EOF */ + } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */ #ifndef __PPCBOOT__ return 0; #else @@ -3092,18 +3104,32 @@ int parse_stream_outer(struct in_str *inp, int end) } #ifndef __PPCBOOT__ -static int parse_string_outer(const char *s, int end) +static int parse_string_outer(const char *s, int flag) #else -int parse_string_outer(char *s, int end) +int parse_string_outer(char *s, int flag) #endif /* __PPCBOOT__ */ { struct in_str input; - setup_string_in_str(&input, s); #ifdef __PPCBOOT__ + char *p = NULL; + int rcode; if ( !s || !*s) return 1; + if (!(p = strchr(s, '\n')) || *++p) { + p = xmalloc(strlen(s) + 2); + strcpy(p, s); + strcat(p, "\n"); + setup_string_in_str(&input, p); + rcode = parse_stream_outer(&input, flag); + free(p); + return rcode; + } else { +#endif + setup_string_in_str(&input, s); + return parse_stream_outer(&input, flag); +#ifdef __PPCBOOT__ + } #endif - return parse_stream_outer(&input, end); } #ifndef __PPCBOOT__ @@ -3119,7 +3145,7 @@ int parse_file_outer(void) #else setup_file_in_str(&input); #endif - rcode = parse_stream_outer(&input, 0); + rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON); return rcode; } @@ -3248,7 +3274,8 @@ int hush_main(int argc, char **argv) { global_argv = argv+optind; global_argc = argc-optind; - opt = parse_string_outer(optarg, 0); + opt = parse_string_outer(optarg, + FLAG_PARSE_SEMICOLON); goto final_return; } break; @@ -3350,6 +3377,9 @@ static char *insert_var_value(char *inp) if (done) { res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp))); strcpy((res_str + res_str_len), inp); + while ((p = strchr(res_str, '\n'))) { + *p = ' '; + } } return (res_str == NULL) ? inp : res_str; } @@ -3394,5 +3424,31 @@ static char **make_list_in(char **inp, char *name) return list; } +/* Make new string for parser */ +static char * make_string(char ** inp) +{ + char *p; + char *str = NULL; + int n; + int len = 2; + + for (n = 0; inp[n]; n++) { + p = insert_var_value(inp[n]); + str = xrealloc(str, (len + strlen(p))); + if (n) { + strcat(str, " "); + } else { + *str = '\0'; + } + strcat(str, p); + len = strlen(str) + 3; + if (p != inp[n]) free(p); + } + len = strlen(str); + *(str + len) = '\n'; + *(str + len + 1) = '\0'; + return str; +} + #endif /* CFG_HUSH_PARSER */ /****************************************************************************/ diff --git a/common/main.c b/common/main.c index 43867ca..086753d 100644 --- a/common/main.c +++ b/common/main.c @@ -32,9 +32,7 @@ #endif #ifdef CFG_HUSH_PARSER -extern int ppcboot_hush_start(bd_t *bd); -extern int parse_file_outer(void); -extern int parse_string_outer(char *s, int end); +#include #endif static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); @@ -224,7 +222,8 @@ void main_loop(bd_t *bd) # ifndef CFG_HUSH_PARSER run_command (p, bd, 0); # else - parse_string_outer(p, 1); + parse_string_outer(p, FLAG_PARSE_SEMICOLON | + FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYED @@ -260,7 +259,8 @@ void main_loop(bd_t *bd) # ifndef CFG_HUSH_PARSER run_command (s, bd, 0); # else - parse_string_outer(s, 1); + parse_string_outer(s, FLAG_PARSE_SEMICOLON | + FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYED @@ -733,7 +733,8 @@ int do_run (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) #ifndef CFG_HUSH_PARSER if (run_command (getenv (argv[i]), bd, flag) != -1) ++rcode; #else - if (parse_string_outer(getenv (argv[i]), 1) == 0) ++rcode; + if (parse_string_outer(getenv (argv[i]), + FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) == 0) ++rcode; #endif } return ((rcode == i) ? 0 : 1); diff --git a/cpu/mpc8xx/speed.c b/cpu/mpc8xx/speed.c index d20481c..bf6f8bb 100644 --- a/cpu/mpc8xx/speed.c +++ b/cpu/mpc8xx/speed.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000 + * (C) Copyright 2000, 2001 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -24,21 +24,27 @@ #include #include #include -#include "speed.h" + +#define PITC_SHIFT 16 +#define PITR_SHIFT 16 +/* pitc values to time for 58/8192 seconds (about 70.8 milliseconds) */ +#define SPEED_PIT_COUNTS 58 +#define SPEED_PITC ((SPEED_PIT_COUNTS - 1) << PITC_SHIFT) +#define SPEED_PITC_INIT ((SPEED_PIT_COUNTS + 1) << PITC_SHIFT) #if !defined(CONFIG_8xx_GCLK_FREQ) /* Access functions for the Machine State Register */ static __inline__ unsigned long get_msr(void) { - unsigned long msr; + unsigned long msr; - asm volatile("mfmsr %0" : "=r" (msr) :); - return msr; + asm volatile("mfmsr %0" : "=r" (msr) :); + return msr; } static __inline__ void set_msr(unsigned long msr) { - asm volatile("mtmsr %0" : : "r" (msr)); + asm volatile("mtmsr %0" : : "r" (msr)); } #endif @@ -51,86 +57,132 @@ static __inline__ void set_msr(unsigned long msr) * * Initializes timer 2 and PIT, but disables them before return. * [Use timer 2, because MPC823 CPUs mask 0.x do not have timers 3 and 4] + * + * When measuring the CPU clock against the PIT, we count cpu clocks + * for 58/8192 seconds with a prescale divide by 177 for the cpu clock. + * These strange values for the timing interval and prescaling are used + * because the formula for the CPU clock is: + * + * CPU clock = count * (177 * (8192 / 58)) + * + * = count * 24999.7241 + * + * which is very close to + * + * = count * 25000 + * + * Since the count gives the CPU clock divided by 25000, we can get + * the CPU clock rounded to the nearest 0.1 MHz by + * + * CPU clock = ((count + 2) / 4) * 100000; + * + * The rounding is important since the measurement is sometimes going + * to be high or low by 0.025 MHz, depending on exactly how the clocks + * and counters interact. By rounding we get the exact answer for any + * CPU clock that is an even multiple of 0.1 MHz. */ ulong get_gclk_freq (void) { #ifndef CONFIG_8xx_GCLK_FREQ - volatile immap_t *immap = (immap_t *)CFG_IMMR; - volatile cpmtimer8xx_t *timerp = &immap->im_cpmtimer; - ulong timer2_val; - ulong msr_val; + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile cpmtimer8xx_t *timerp = &immap->im_cpmtimer; + ulong timer2_val; + ulong msr_val; - /* Reset + Stop Timer 2, no cascading - */ - timerp->cpmt_tgcr &= ~(TGCR_CAS2 | TGCR_RST2); + /* Reset + Stop Timer 2, no cascading + */ + timerp->cpmt_tgcr &= ~(TGCR_CAS2 | TGCR_RST2); + + /* Keep stopped, halt in debug mode + */ + timerp->cpmt_tgcr |= (TGCR_FRZ2 | TGCR_STP2); - /* Keep stopped, halt in debug mode - */ - timerp->cpmt_tgcr |= (TGCR_FRZ2 | TGCR_STP2); + /* Timer 2 setup: + * Output ref. interrupt disable, int. clock + * Prescale by 177. Note that prescaler divides by value + 1 + * so we must subtract 1 here. + */ + timerp->cpmt_tmr2 = ((177 - 1) << TMR_PS_SHIFT) | TMR_ICLK_IN_GEN; - /* Timer 2 setup: - * Output ref. interrupt disable, int. clock / 16 - */ - timerp->cpmt_tmr2 = (SPEED_TMR2_PS << TMR_PS_SHIFT) | TMR_ICLK_IN_GEN_DIV16; + timerp->cpmt_tcn2 = 0; /* reset state */ + timerp->cpmt_tgcr |= TGCR_RST2; /* enable timer 2 */ - timerp->cpmt_tcn2 = 0; /* reset state */ - timerp->cpmt_tgcr |= TGCR_RST2; /* enable timer 2 */ + /* + * PIT setup: + * + * We want to time for SPEED_PITC_COUNTS counts (of 8192 Hz), + * so the count value would be SPEED_PITC_COUNTS - 1. + * But there would be an uncertainty in the start time of 1/4 + * count since when we enable the PIT the count is not + * synchronized to the 32768 Hz oscillator. The trick here is + * to start the count higher and wait until the PIT count + * changes to the required value before starting timer 2. + * + * One count high should be enough, but occasionally the start + * is off by 1 or 2 counts of 32768 Hz. With the start value + * set two counts high it seems very reliable. + */ + + immap->im_sitk.sitk_pitck = KAPWR_KEY; /* PIT initialization */ + immap->im_sit.sit_pitc = SPEED_PITC_INIT; + + immap->im_sitk.sitk_piscrk = KAPWR_KEY; + immap->im_sit.sit_piscr = CFG_PISCR; - immap->im_sitk.sitk_pitck = KAPWR_KEY; /* PIT initialization */ - immap->im_sit.sit_pitc = SPEED_PITC; + /* + * Start measurement - disable interrupts, just in case + */ + msr_val = get_msr (); + set_msr (msr_val & ~MSR_EE); - immap->im_sitk.sitk_piscrk = KAPWR_KEY; - immap->im_sit.sit_piscr = CFG_PISCR; + immap->im_sit.sit_piscr |= PISCR_PTE; - /* - * Start measurement - disable interrupts, just in case - */ - msr_val = get_msr(); - set_msr (msr_val & ~MSR_EE); + /* spin until get exact count when we want to start */ + while (immap->im_sit.sit_pitr > SPEED_PITC); - immap->im_sit.sit_piscr |= PISCR_PTE; - timerp->cpmt_tgcr &= ~TGCR_STP2; /* Start Timer 2 */ - while ((immap->im_sit.sit_piscr & PISCR_PS) == 0) - ; - timerp->cpmt_tgcr |= TGCR_STP2; /* Stop Timer 2 */ + timerp->cpmt_tgcr &= ~TGCR_STP2; /* Start Timer 2 */ + while ((immap->im_sit.sit_piscr & PISCR_PS) == 0); + timerp->cpmt_tgcr |= TGCR_STP2; /* Stop Timer 2 */ - /* re-enable external interrupts if they were on */ - set_msr (msr_val); + /* re-enable external interrupts if they were on */ + set_msr (msr_val); - /* Disable timer and PIT - */ - timer2_val = timerp->cpmt_tcn2; /* save before restting */ + /* Disable timer and PIT + */ + timer2_val = timerp->cpmt_tcn2; /* save before reset timer */ - timerp->cpmt_tgcr &= ~(TGCR_RST2 | TGCR_FRZ2 | TGCR_STP2); - immap->im_sit.sit_piscr &= ~PISCR_PTE; + timerp->cpmt_tgcr &= ~(TGCR_RST2 | TGCR_FRZ2 | TGCR_STP2); + immap->im_sit.sit_piscr &= ~PISCR_PTE; - return (timer2_val * 400000L); /* convert to Hz */ + return (((timer2_val + 2) / 4) * 100000L); /* convert to Hz */ -#else /* CONFIG_8xx_GCLK_FREQ */ +#else /* CONFIG_8xx_GCLK_FREQ */ /* - * If for some reason measuring the gclk frequency won't work, - * we return the hardwired value. - * (For example, the cogent CMA286-60 CPU module has no - * separate oscillator for PITRTCLK) + * If for some reason measuring the gclk frequency won't + * work, we return the hardwired value. + * (For example, the cogent CMA286-60 CPU module has no + * separate oscillator for PITRTCLK) */ return (CONFIG_8xx_GCLK_FREQ); -#endif /* CONFIG_8xx_GCLK_FREQ */ +#endif /* CONFIG_8xx_GCLK_FREQ */ } /* ------------------------------------------------------------------------- */ ulong get_bus_freq (ulong gclk_freq) { - immap_t *immr = (immap_t *)CFG_IMMR; + immap_t *immr = (immap_t *) CFG_IMMR; - if ((immr->im_clkrst.car_sccr & SCCR_EBDF11) == 0) /* No Bus Divider active */ - return (gclk_freq); + if ((immr->im_clkrst.car_sccr & SCCR_EBDF11) == 0) { + /* No Bus Divider active */ + return (gclk_freq); + } - return (gclk_freq / 2); /* The MPC8xx has only one BDF: half clock speed */ + return (gclk_freq / 2); /* The MPC8xx has only one BDF: half clock speed */ } /* ------------------------------------------------------------------------- */ diff --git a/cpu/mpc8xx/speed.h b/cpu/mpc8xx/speed.h deleted file mode 100644 index b66393b..0000000 --- a/cpu/mpc8xx/speed.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/*----------------------------------------------------------------------- - * Timer value for timer 2, ICLK = 10 - * - * SPEED_FCOUNT2 = GCLK / (16 * (TIMER_TMR_PS + 1)) - * SPEED_TMR3_PS = (GCLK / (16 * SPEED_FCOUNT3)) - 1 - * - * SPEED_FCOUNT2 timer 2 counting frequency - * GCLK CPU clock - * SPEED_TMR2_PS prescaler - */ -#define SPEED_TMR2_PS (250 - 1) /* divide by 250 */ - -/*----------------------------------------------------------------------- - * Timer value for PIT - * - * PIT_TIME = SPEED_PITC / PITRTCLK - * PITRTCLK = 8192 - */ -#define SPEED_PITC (82 << 16) /* start counting from 82 */ - -/* - * The new value for PTA is calculated from - * - * PTA = (gclk * Trefresh) / (2 ^ (2 * DFBRG) * PTP * NCS) - * - * gclk CPU clock (not bus clock !) - * Trefresh Refresh cycle * 4 (four word bursts used) - * DFBRG For normal mode (no clock reduction) always 0 - * PTP Prescaler (already adjusted for no. of banks and 4K / 8K refresh) - * NCS Number of SDRAM banks (chip selects) on this UPM. - */ diff --git a/include/config_AMX860.h b/include/config_AMX860.h index 0cce616..2e6e82a 100644 --- a/include/config_AMX860.h +++ b/include/config_AMX860.h @@ -145,14 +145,40 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE #define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +/* + * PPCBoot for AMX board supports two types of memory extension + * modules: one that provides 4 MB flash memory, and another one with + * 16 MB EDO DRAM. + * + * The flash module swaps the CS0 and CS1 signals: if the module is + * installed, CS0 is connected to Flash on the module and CS1 is + * connected to the on-board Flash. This means that you must intall + * PPCBoot when the Flash module is plugged in, if you plan to use + * it. + * + * To enable support for the DRAM extension card, CONFIG_AMX_RAM_EXT + * must be defined. The DRAM module uses CS1. + * + * Only one of these modules may be installed at a time. If PPCBoot + * is compiled with the CONFIG_AMX_RAM_EXT option set, it will not + * work if the Flash extension module is installed instead of the + * DRAM module. + */ +#define CONFIG_AMX_RAM_EXT /* 16Mb Ext. DRAM module support */ + /* * For booting Linux, the board info and command line data * have to be in the first 8 MB of memory, since this is * the maximum mapped by the Linux kernel during initialization. * - * Use 4 MB for now since AMX very small memory. + * Use 4 MB for without and 8 MB with 16 MB DRAM extension module + * (CONFIG_AMX_RAM_EXT) */ -#define CFG_BOOTMAPSZ (4 << 20) /* Initial Memory map for Linux */ +#ifdef CONFIG_AMX_RAM_EXT +# define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#else +# define CFG_BOOTMAPSZ (4 << 20) /* Initial Memory map for Linux */ +#endif /*----------------------------------------------------------------------- * FLASH organization */ @@ -227,14 +253,6 @@ #define CFG_DER 0 -/* Because of the way the 860 starts up and assigns CS0 the -* entire address space, we have to set the memory controller -* differently. Normally, you write the option register -* first, and then enable the chip select by writing the -* base register. For CS0, you must write the base register -* first, followed by the option register. -*/ - /* * Init Memory Controller: * @@ -242,23 +260,27 @@ */ #define FLASH_BASE0_PRELIM 0x40000000 /* FLASH bank #0 */ +#if !defined(CONFIG_AMX_RAM_EXT) #define FLASH_BASE1_PRELIM 0x60000000 /* FLASH bank #1 */ +#endif #define CFG_REMAP_OR_AM 0x80000000 /* OR addr mask */ #define CFG_PRELIM_OR_AM 0xFFC00000 /* OR addr mask */ /* FLASH timing: ACS = 10, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 0 */ /* 0x00000800 0x00000400 0x00000100 0x00000030 0x00000004 */ -#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_3_CLK | OR_TRLX) +#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_5_CLK | OR_TRLX) #define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH) #define CFG_OR0_PRELIM 0xFFC00954 /* Real values for the board */ #define CFG_BR0_PRELIM 0x40000001 /* Real values for the board */ +#if !defined(CONFIG_AMX_RAM_EXT) #define CFG_OR1_REMAP CFG_OR0_REMAP #define CFG_OR1_PRELIM 0xFFC00954 /* Real values for the board */ #define CFG_BR1_PRELIM 0x60000001 /* Real values for the board */ +#endif /* * Internal Definitions diff --git a/include/config_FLAGADM.h b/include/config_FLAGADM.h index fc1bd71..7b502ff 100644 --- a/include/config_FLAGADM.h +++ b/include/config_FLAGADM.h @@ -33,33 +33,57 @@ * (easy to change) */ +#undef DEBUG + +#define CONFIG_DELAYCACHEENABLE 1 #define CONFIG_MPC823 1 /* This is a MPC823 CPU */ #define CONFIG_FLAGADM 1 /* ...on a FLAGA DM */ -#define CONFIG_8xx_GCLK_FREQ 0x2dc6c00 /*48MHz*/ +#define CONFIG_8xx_GCLK_FREQ 48000000 /*48MHz*/ +#if 0 #define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ #undef CONFIG_8xx_CONS_SMC2 #undef CONFIG_8xx_CONS_NONE +#else +#undef CONFIG_8xx_CONS_SMC1 /* Console is on SMC1 */ +#define CONFIG_8xx_CONS_SMC2 1 +#undef CONFIG_8xx_CONS_NONE +#endif #define CONFIG_BAUDRATE 115200 /* console baudrate = 115kbps */ -#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ +#define CONFIG_BOOTDELAY 3 /* autoboot after 5 seconds */ -#define CONFIG_CLOCKS_IN_MHZ 1 /* clocks passsed to Linux in MHz */ +#undef CONFIG_CLOCKS_IN_MHZ -#undef CONFIG_BOOTARGS +#define CONFIG_BOOTARGS "root=/dev/nfs rw ip=bootp" #define CONFIG_BOOTCOMMAND \ - "bootp; " \ - "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ - "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ - "bootm" + "setenv bootargs root=/dev/ram ip=off panic=1;" \ + "bootm 40040000 400e0000" + +/* Björgvin */ +/* #define CONFIG_ETHADDR 0:1:2:3:4:A */ +/* Stephan */ +/* #define CONFIG_ETHADDR 0:1:2:3:4:9 */ +/* Kári */ +/* #define CONFIG_ETHADDR 0:1:2:3:4:5 */ #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ #undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */ +/* #define CONFIG_WATCHDOG / * watchdog enabled */ #undef CONFIG_WATCHDOG /* watchdog disabled */ +/* #define CONFIG_I2C 1 */ +/* #define CFG_I2C_SPEED 50000 */ +/* #define CFG_SOFT_I2C 1 */ +/* #define CFG_I2C_UCODE_PATCH 1 */ +/* #define CFG_I2C_DPMEM_OFFSET 0x1fc0 */ + #define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE) -#define CONFIG_COMMANDS (CFG_CMD_BDI | CFG_CMD_IMI | CFG_CMD_CACHE | CFG_CMD_MEMORY | CFG_CMD_FLASH | CFG_CMD_LOADS | CFG_CMD_LOADB | CFG_CMD_ENV ) +#define CONFIG_COMMANDS (CFG_CMD_BDI | CFG_CMD_IMI | CFG_CMD_CACHE | \ + CFG_CMD_MEMORY | CFG_CMD_FLASH | CFG_CMD_LOADB | CFG_CMD_LOADS | \ + CFG_CMD_ENV) + /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include @@ -77,10 +101,10 @@ #define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ -#define CFG_MEMTEST_START 0x0400000 /* memtest works on */ -#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ +#define CFG_MEMTEST_START 0x0100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x0f00000 /* 1 ... 15 MB in DRAM */ -#define CFG_LOAD_ADDR 0x100000 /* default load address */ +#define CFG_LOAD_ADDR 0x40040000 /* default load address */ #define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ @@ -112,11 +136,7 @@ */ #define CFG_SDRAM_BASE 0x00000000 #define CFG_FLASH_BASE 0x40000000 -#if defined(DEBUG) || (CONFIG_COMMANDS & CFG_CMD_IDE) -#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ -#else #define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ -#endif #define CFG_MONITOR_BASE CFG_FLASH_BASE #define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ @@ -137,8 +157,12 @@ #define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ #define CFG_ENV_IS_IN_FLASH 1 -#define CFG_ENV_OFFSET 0x8000 /* Offset of Environment Sector */ -#define CFG_ENV_SIZE 0x8000 /* Total Size of Environment Sector */ +/* This is a litlebit wasteful, but one sector is 128kb and we have to + * assigne a whole sector for the environment, so that we can safely + * erase and write it without disturbing the boot sector + */ +#define CFG_ENV_OFFSET 0x20000 /* Offset of Environment Sector */ +#define CFG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */ /*----------------------------------------------------------------------- * Cache Configuration @@ -154,7 +178,11 @@ *----------------------------------------------------------------------- * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze */ +#ifdef CONFIG_WATCHDOG +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_SWF | SYPCR_SWE | SYPCR_SWRI | SYPCR_SWP) +#else #define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF) +#endif /*----------------------------------------------------------------------- * SIUMCR - SIU Module Configuration 11-6 @@ -213,66 +241,91 @@ /* * In the Flaga DM we have: - * Flash on BR0/OR0/CS0 - * Display on BR1/OR1/CS1 - * SDRAM on BR2/OR2/CS2 + * Flash on BR0/OR0/CS0a at 0x40000000 + * Display on BR1/OR1/CS1 at 0x20000000 + * SDRAM on BR2/OR2/CS2 at 0x00000000 * Free BR3/OR3/CS3 - * DSP1 on BR4/OR4/CS4 - * DSP2 on BR5/OR5/CS5 + * DSP1 on BR4/OR4/CS4 at 0x80000000 + * DSP2 on BR5/OR5/CS5 at 0xa0000000 * - * For now we just configure the flash and the SDRAM and leave the others + * For now we just configure the Flash and the SDRAM and leave the others * untouched. */ -#define FLASH_BASE0_PRELIM 0x40000000 /* FLASH bank #0 */ +#define CFG_FLASH_PROTECTION 1 +/* #undef CFG_FLASH_PROTECTION */ + +#define FLASH_BASE0 0x40000000 /* FLASH bank #0 */ /* used to re-map FLASH both when starting from SRAM or FLASH: * restrict access enough to keep SRAM working (if any) * but not too much to meddle with FLASH accesses */ /*#define CFG_REMAP_OR_AM 0x80000000 / * OR addr mask */ -#define CFG_PRELIM_OR_AM 0xff000000 /* OR addr mask */ -#define CFG_PRELIM_OR_ATM 0x00006000 +#define CFG_OR_AM 0xff000000 /* OR addr mask */ +#define CFG_OR_ATM 0x00006000 /* FLASH timing: ACS = 10, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 1 */ #define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | \ OR_SCY_3_CLK | OR_TRLX | OR_EHTR ) /*#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH) */ -#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_PRELIM_OR_ATM | \ - CFG_OR_TIMING_FLASH) -#define CFG_BR0_PRELIM ((FLASH_BASE0_PRELIM & BR_BA_MSK) | BR_PS_16 | BR_V ) +#define CFG_OR0_PRELIM (CFG_OR_AM | CFG_OR_ATM | CFG_OR_TIMING_FLASH) +#define CFG_BR0_PRELIM ((FLASH_BASE0 & BR_BA_MSK) | BR_PS_16 | BR_V ) /* * BR2 and OR2 (SDRAM) * */ -#define SDRAM_BASE2_PRELIM 0x00000000 /* SDRAM bank #0 */ +#define SDRAM_BASE2 0x00000000 /* SDRAM bank #0 */ #define SDRAM_MAX_SIZE 0x04000000 /* max 64 MB per bank */ /* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care) */ -#define CFG_OR_TIMING_SDRAM ( 0x00000A00 | OR_EHTR ) +#define CFG_OR_TIMING_SDRAM ( 0x00000800 ) + +#define CFG_BR2_PRELIM ((SDRAM_BASE2 & BR_BA_MSK) | BR_MS_UPMA | BR_V ) +#define CFG_OR2_PRELIM (CFG_OR_AM | CFG_OR_TIMING_SDRAM ) +/* #define CFG_BR2_PRELIM 0x00000081 */ +/* #define CFG_OR2_PRELIM (0xff000800 | OR_BI) */ +#define CFG_BR2 CFG_BR2_PRELIM +#define CFG_OR2 CFG_OR2_PRELIM -#define CFG_BR2_PRELIM ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V ) -#define CFG_OR2_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM ) +/* + * MAMR settings for SDRAM + */ +/* 0xd0802118 */ +#define CFG_MAMR_48_SDR (CFG_MAMR_PTA | MAMR_TLFA_4X | MAMR_WLFA_1X | \ + MAMR_G0CLA_A11) /* * Memory Periodic Timer Prescaler */ /* periodic timer for refresh */ -#define CFG_MAMR_PTA 0xd0000000 +/* #define CFG_MAMR_PTA 0xd0000000 */ +#define CFG_MAMR_PTA 0xBB000000 +/* #define CFG_MAMR_PTA 0x0b000000 */ +/* #define CFG_MAMR_PTA 0x11000000 */ + /* - * MAMR settings for SDRAM + * BR4 and OR4 (DSP1) + * + * We do not wan't preliminary setup of the DSP, anyway we need the + * UPMB setup correctly before we can access the DSP. + * +*/ +#define DSP_BASE 0x80000000 + +#define CFG_OR4 ( OR_AM_MSK | OR_CSNT_SAM | OR_BI ) +#define CFG_BR4 ( (DSP_BASE & BR_BA_MSK) | BR_PS_16 | BR_MS_UPMB | BR_V ) + +/* + * MBMR settings for DSP and DISPLAY + * */ -/* 0xd0802118 */ -#define CFG_MAMR_48_SDR_8 (CFG_MAMR_PTA | MAMR_TLFA_8X | MAMR_WLFA_1X | \ - MAMR_RLFA_1X | MAMR_G0CLA_A11) +/* #define CFG_MBMR_DSP ( MAMR_GPL_B4DIS ) */ -/*0xd0802114 */ -#define CFG_MAMR_48_SDR_4 (CFG_MAMR_PTA | MAMR_TLFA_4X | MAMR_WLFA_1X | \ - MAMR_RLFA_1X | MAMR_G0CLA_A11) /* * Internal Definitions * diff --git a/include/hush.h b/include/hush.h new file mode 100644 index 0000000..eddca25 --- /dev/null +++ b/include/hush.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _HUSH_H_ +#define _HUSH_H_ + +#define FLAG_EXIT_FROM_LOOP 1 +#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ +#define FLAG_NOT_PARSE_SEMICOLON (1 << 2) /* symbol ';' is common for parser */ + +extern int ppcboot_hush_start(bd_t *bd); +extern int parse_string_outer(char *s, int flag); +extern int parse_file_outer(void); + +#endif \ No newline at end of file