From c7de829c796978e519984df2f1c8cfcf921a39a4 Mon Sep 17 00:00:00 2001 From: wdenk Date: Tue, 19 Nov 2002 11:04:11 +0000 Subject: * Patch by Thomas Frieden, 13 Nov 2002: Add code for AmigaOne board (preliminary merge to U-Boot, still WIP) * Patch by Jon Diekema, 12 Nov 2002: - Adding URL for IEEE OUI lookup - Making the autoboot #defines dependent on CONFIG_AUTOBOOT_KEYED being defined. - In the CONFIG_EXTRA_ENV_SETTINGS #define, the root-on-initrd and root-on-nfs macros are designed to switch how the default boot method gets defined. --- common/cmd_bootm.c | 11 +++ common/cmd_fdc.c | 62 ++++++++++++++++- common/cmd_ide.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++-- common/cmd_nvedit.c | 12 ++++ common/cmd_pci.c | 2 +- common/command.c | 11 +++ common/console.c | 4 ++ common/docecc.c | 2 - common/env_common.c | 13 ++++ common/hush.c | 5 -- common/main.c | 35 ++++++++++ 11 files changed, 336 insertions(+), 14 deletions(-) (limited to 'common') diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a0587d0..4c0d1f5 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -224,6 +224,17 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) iflag = disable_interrupts(); +#ifdef CONFIG_AMIGAONEG3SE + /* + * We've possible left the caches enabled during + * bios emulation, so turn them off again + */ + icache_disable(); + invalidate_l1_instruction_cache(); + flush_data_cache(); + dcache_disable(); +#endif + switch (hdr->ih_comp) { case IH_COMP_NONE: if(ntohl(hdr->ih_load) == addr) { diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index e45b336..3ee342f 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -188,6 +188,30 @@ static FDC_COMMAND_STRUCT cmd; /* global command struct */ #endif +#ifdef CONFIG_AMIGAONEG3SE +unsigned char INT6_Status; + +void fdc_interrupt(void) +{ + INT6_Status = 0x80; +} + +/* waits for an interrupt (polling) */ +int wait_for_fdc_int(void) +{ + unsigned long timeout; + timeout = FDC_TIME_OUT; + while(((volatile)INT6_Status & 0x80) == 0) { + timeout--; + udelay(10); + if(timeout == 0) /* timeout occured */ + return FALSE; + } + INT6_Status = 0; + return TRUE; +} +#endif + /* Supporting Functions */ /* reads a Register of the FDC */ unsigned char read_fdc_reg(unsigned int addr) @@ -210,6 +234,7 @@ void write_fdc_reg(unsigned int addr, unsigned char val) tmp[0]=val; } +#ifndef CONFIG_AMIGAONEG3SE /* waits for an interrupt (polling) */ int wait_for_fdc_int(void) { @@ -224,6 +249,7 @@ int wait_for_fdc_int(void) return TRUE; } +#endif /* reads a byte from the FIFO of the FDC and checks direction and RQM bit of the MSR. returns -1 if timeout, or byte if ok */ @@ -416,7 +442,7 @@ int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) return(fdc_issue_cmd(pCMD,pFG)); } - +#ifndef CONFIG_AMIGAONEG3SE /* terminates current command, by not servicing the FIFO * waits for interrupt and fills in the result bytes */ int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) @@ -430,6 +456,27 @@ int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) } return TRUE; } +#endif +#ifdef CONFIG_AMIGAONEG3SE +int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) +{ + int i; + for(i=0;i<100;i++) + udelay(500); /* wait 500usec for fifo overrun */ + while((INT6_Status&0x80)==0x00); /* wait as long as no int has occured */ + for(i=0;i<7;i++) { + pCMD->result[i]=(unsigned char)read_fdc_byte(); + } + INT6_Status = 0; + return TRUE; +} + +#endif + +#ifdef CONFIG_AMIGAONEG3SE +#define disable_interrupts() 0 +#define enable_interrupts() (void)0 +#endif /* reads data from FDC, seek commands are issued automatic */ int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) @@ -550,6 +597,11 @@ retrycal: return TRUE; } +#ifdef CONFIG_AMIGAONEG3SE +#undef disable_interrupts() +#undef enable_interrupts() +#endif + /* Scan all drives and check if drive is present and disk is inserted */ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) { @@ -590,6 +642,7 @@ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) } + /************************************************************************** * int fdc_setup * setup the fdc according the datasheet @@ -597,9 +650,13 @@ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) */ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) { - int i; +#ifdef CONFIG_AMIGAONEG3SE + irq_install_handler(6, (interrupt_handler_t *)fdc_interrupt, NULL); + i8259_unmask_irq(6); +#endif + #ifdef CFG_FDC_HW_INIT fdc_hw_init (); #endif @@ -648,6 +705,7 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) /* then, we clear the reset in the DOR */ /* fdc_check_drive(pCMD,pFG); */ /* write_fdc_reg(FDC_DOR,0x04); */ + return TRUE; } #endif /* ((CONFIG_COMMANDS & CFG_CMD_FDC)||(CONFIG_COMMANDS & CFG_CMD_FDOS))*/ diff --git a/common/cmd_ide.c b/common/cmd_ide.c index e514cf7..7b45508 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -58,6 +58,7 @@ #undef IDE_DEBUG + #ifdef IDE_DEBUG #define PRINTF(fmt,args...) printf (fmt ,##args) #else @@ -121,7 +122,11 @@ ulong ide_bus_offset[CFG_IDE_MAXBUS] = { #define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)]) #endif +#ifndef CONFIG_AMIGAONEG3SE static int ide_bus_ok[CFG_IDE_MAXBUS]; +#else +static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,}; +#endif static block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; /* ------------------------------------------------------------------------- */ @@ -129,7 +134,15 @@ static block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; #ifdef CONFIG_IDE_LED static void ide_led (uchar led, uchar status); #else +#ifndef CONFIG_AMIGAONEG3SE #define ide_led(a,b) /* dummy */ +#else +extern void ide_led(uchar led, uchar status); +#define LED_IDE1 1 +#define LED_IDE2 2 +#define CONFIG_IDE_LED 1 +#define DEVICE_LED(x) 1 +#endif #endif #ifdef CONFIG_IDE_RESET @@ -464,6 +477,11 @@ void ide_init (void) #endif unsigned char c; int i, bus; +#ifdef CONFIG_AMIGAONEG3SE + unsigned int max_bus_scan; + unsigned int ata_reset_time; + char *s; +#endif #ifdef CONFIG_IDE_8xx_PCCARD extern int pcmcia_on (void); @@ -514,8 +532,19 @@ void ide_init (void) * Wait for IDE to get ready. * According to spec, this can take up to 31 seconds! */ +#ifndef CONFIG_AMIGAONEG3SE for (bus=0; bus (ata_reset_time * 100)) { +#else if (i > (ATA_RESET_TIME * 100)) { +#endif puts ("** Timeout **\n"); ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ +#ifdef CONFIG_AMIGAONEG3SE + /* If this is the second bus, the first one was OK */ + if (bus != 0) + { + ide_bus_ok[bus] = 0; + goto skip_bus; + } +#endif return; } if ((i >= 100) && ((i%100)==0)) { @@ -557,6 +602,10 @@ void ide_init (void) } WATCHDOG_RESET(); } + +#ifdef CONFIG_AMIGAONEG3SE + skip_bus: +#endif putc ('\n'); ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ @@ -736,6 +785,26 @@ __inline__ unsigned ld_le16(const volatile unsigned short *addr) return val; } +#ifdef CONFIG_AMIGAONEG3SE +static void +output_data_short(int dev, ulong *sect_buf, int words) +{ + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + while (words--) { + __asm__ volatile ("eieio"); + *pbuf = *dbuf++; + __asm__ volatile ("eieio"); + } + + if (words&1) + *pbuf = 0; +} +#endif + static void input_swap_data(int dev, ulong *sect_buf, int words) { @@ -803,6 +872,29 @@ input_data(int dev, ulong *sect_buf, int words) #endif /* __PPC__ */ +#ifdef CONFIG_AMIGAONEG3SE +static void +input_data_short(int dev, ulong *sect_buf, int words) +{ + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + while (words--) { + __asm__ volatile ("eieio"); + *dbuf++ = *pbuf; + __asm__ volatile ("eieio"); + } + + if (words&1) + { + ushort dummy; + dummy = *pbuf; + } +} +#endif + /* ------------------------------------------------------------------------- */ static void ide_ident (block_dev_desc_t *dev_desc) @@ -811,6 +903,13 @@ static void ide_ident (block_dev_desc_t *dev_desc) unsigned char c; hd_driveid_t *iop = (hd_driveid_t *)iobuf; +#ifdef CONFIG_AMIGAONEG3SE + int max_bus_scan; + int retries = 0; + char *s; + int do_retry = 0; +#endif + #if 0 int mode, cycle_time; #endif @@ -818,12 +917,35 @@ static void ide_ident (block_dev_desc_t *dev_desc) device=dev_desc->dev; printf (" Device %d: ", device); +#ifdef CONFIG_AMIGAONEG3SE + s = getenv("ide_maxbus"); + if (s) { + max_bus_scan = simple_strtol(s, NULL, 10); + } else { + max_bus_scan = CFG_IDE_MAXBUS; + } + if (device >= max_bus_scan*2) { + dev_desc->type=DEV_TYPE_UNKNOWN; + return; + } +#endif + ide_led (DEVICE_LED(device), 1); /* LED on */ /* Select device */ ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); dev_desc->if_type=IF_TYPE_IDE; #ifdef CONFIG_ATAPI + +#ifdef CONFIG_AMIGAONEG3SE + do_retry = 0; + retries = 0; + + /* Warning: This will be tricky to read */ + while (retries <= 1) + { +#endif /* CONFIG_AMIGAONEG3SE */ + /* check signature */ if ((ide_inb(device,ATA_SECT_CNT) == 0x01) && (ide_inb(device,ATA_SECT_NUM) == 0x01) && @@ -855,9 +977,34 @@ static void ide_ident (block_dev_desc_t *dev_desc) if (((c & ATA_STAT_DRQ) == 0) || ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) { +#ifdef CONFIG_AMIGAONEG3SE + if (retries == 0) { + do_retry = 1; + } else { + dev_desc->type=DEV_TYPE_UNKNOWN; + return; + } +#else dev_desc->type=DEV_TYPE_UNKNOWN; return; +#endif /* CONFIG_AMIGAONEG3SE */ + } + +#ifdef CONFIG_AMIGAONEG3SE + s = getenv("ide_doreset"); + if (s && strcmp(s, "on") == 0 && 1 == do_retry) { + /* Need to soft reset the device in case it's an ATAPI... */ + PRINTF("Retrying...\n"); + ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + udelay(100000); + ide_outb (device, ATA_COMMAND, 0x08); + udelay (100000); /* 100 ms */ + retries++; + } else { + retries = 100; } + } /* see above - ugly to read */ +#endif /* CONFIG_AMIGAONEG3SE */ input_swap_data (device, iobuf, ATA_SECTORWORDS); @@ -1200,7 +1347,7 @@ static void ide_reset (void) /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_IDE_LED +#if defined(CONFIG_IDE_LED) && !defined(CONFIG_AMIGAONEG3SE) static uchar led_buffer = 0; /* Buffer for current LED status */ @@ -1320,6 +1467,9 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha */ mask = ATA_STAT_BUSY|ATA_STAT_DRQ; res = 0; +#ifdef CONFIG_AMIGAONEG3SE +# warning THF: Removed LBA mode ??? +#endif ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); if ((c & mask) != res) { @@ -1329,8 +1479,13 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha } /* write taskfile */ ide_outb (device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */ + ide_outb (device, ATA_SECT_CNT, 0); + ide_outb (device, ATA_SECT_NUM, 0); ide_outb (device, ATA_CYL_LOW, (unsigned char)(buflen & 0xFF)); - ide_outb (device, ATA_CYL_HIGH, (unsigned char)((buflen<<8) & 0xFF)); + ide_outb (device, ATA_CYL_HIGH, (unsigned char)((buflen>>8) & 0xFF)); +#ifdef CONFIG_AMIGAONEG3SE +# warning THF: Removed LBA mode ??? +#endif ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); ide_outb (device, ATA_COMMAND, ATAPI_CMD_PACKET); @@ -1429,6 +1584,16 @@ unsigned char atapi_issue_autoreq (int device, unsigned char res,key,asc,ascq; int notready,unitattn; +#ifdef CONFIG_AMIGAONEG3SE + char *s; + unsigned int timeout, retrycnt; + + s = getenv("ide_cd_timeout"); + timeout = s ? (simple_strtol(s, NULL, 10)*1000000)/5 : 0; + + retrycnt = 0; +#endif + unitattn=ATAPI_UNIT_ATTN; notready=ATAPI_DRIVE_NOT_READY; @@ -1445,7 +1610,7 @@ retry: memset(sense_ccb,0,sizeof(sense_ccb)); memset(sense_data,0,sizeof(sense_data)); sense_ccb[0]=ATAPI_CMD_REQ_SENSE; - sense_ccb[4]=18; /* allocation Legnth */ + sense_ccb[4]=18; /* allocation Length */ res=atapi_issue(device,sense_ccb,12,sense_data,18); key=(sense_data[2]&0xF); @@ -1482,6 +1647,26 @@ retry: AT_PRINTF("Media not present\n"); goto error; } + +#ifdef CONFIG_AMIGAONEG3SE + if ((sense_data[2]&0xF)==0x0B) { + AT_PRINTF("ABORTED COMMAND...retry\n"); + if (retrycnt++ < 4) + goto retry; + return (0xFF); + } + + if ((sense_data[2]&0xf) == 0x02 && + sense_data[12] == 0x04 && + sense_data[13] == 0x01 ) { + AT_PRINTF("Waiting for unit to become active\n"); + udelay(timeout); + if (retrycnt++ < 4) + goto retry; + return 0xFF; + } +#endif /* CONFIG_AMIGAONEG3SE */ + printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); error: AT_PRINTF ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 0a19ce4..9b6d14f 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -353,6 +353,18 @@ int _do_setenv (int flag, int argc, char *argv[]) return 0; } #endif /* CFG_CMD_NET */ + +#ifdef CONFIG_AMIGAONEG3SE + if (strcmp(argv[1], "vga_fg_color") == 0 || + strcmp(argv[1], "vga_bg_color") == 0 ) { + extern void video_set_color(unsigned char attr); + extern unsigned char video_get_attr(void); + + video_set_color(video_get_attr()); + return 0; + } +#endif /* CONFIG_AMIGAONEG3SE */ + return 0; } diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 22e4b9a..300ac02 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -96,7 +96,7 @@ void pciinfo(int BusNum, int ShortPCIListing) if ((VendorID == 0xFFFF) || (VendorID == 0x0000)) continue; - pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType); + if (!Function) pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType); if (ShortPCIListing) { diff --git a/common/command.c b/common/command.c index cab68ab..2304d7a 100644 --- a/common/command.c +++ b/common/command.c @@ -72,6 +72,11 @@ #include #include +#ifdef CONFIG_AMIGAONEG3SE +#include +#include +#endif + /* * HELP command */ @@ -225,6 +230,9 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_AUTOSCRIPT CMD_TBL_BASE CMD_TBL_BDINFO +#ifdef CONFIG_AMIGAONEG3SE + CMD_TBL_BOOTA +#endif CMD_TBL_BOOTELF CMD_TBL_BOOTM CMD_TBL_BOOTP @@ -291,6 +299,9 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_MCCINFO CMD_TBL_MD CMD_TBL_MEMCINFO +#ifdef CONFIG_AMIGAONEG3SE + CMD_TBL_MENU +#endif CMD_TBL_MII CMD_TBL_MM CMD_TBL_MTEST diff --git a/common/console.c b/common/console.c index f99dfcc..d888d1d 100644 --- a/common/console.c +++ b/common/console.c @@ -29,6 +29,10 @@ void **syscall_tbl; +#ifdef CONFIG_AMIGAONEG3SE +int console_changed = 0; +#endif + #ifdef CFG_CONSOLE_IS_IN_ENV /* * if overwrite_console returns 1, the stdin, stderr and stdout diff --git a/common/docecc.c b/common/docecc.c index 09e8233..74ac741 100644 --- a/common/docecc.c +++ b/common/docecc.c @@ -35,8 +35,6 @@ #if (CONFIG_COMMANDS & CFG_CMD_DOC) -#define min(x,y) ((x)<(y)?(x):(y)) - /* need to undef it (from asm/termbits.h) */ #undef B0 diff --git a/common/env_common.c b/common/env_common.c index f7f268e..bd22e15 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -38,6 +38,11 @@ # define SHOW_BOOT_PROGRESS(arg) #endif +#ifdef CONFIG_AMIGAONEG3SE + extern void enable_nvram(void); + extern void disable_nvram(void); +#endif + #undef DEBUG_ENV #ifdef DEBUG_ENV #define DEBUGF(fmt,args...) printf(fmt ,##args) @@ -180,6 +185,10 @@ void env_relocate (void) DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, gd->reloc_off); +#ifdef CONFIG_AMIGAONEG3SE + enable_nvram(); +#endif + #ifdef ENV_IS_EMBEDDED /* * The environment buffer is embedded with the text segment, @@ -228,4 +237,8 @@ void env_relocate (void) env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); + +#ifdef CONFIG_AMIGAONEG3SE + disable_nvram(); +#endif } diff --git a/common/hush.c b/common/hush.c index 3cb6fc3..92547433 100644 --- a/common/hush.c +++ b/common/hush.c @@ -356,11 +356,6 @@ struct built_in_command { }; #endif -/* belongs in busybox.h */ -static inline int max(int a, int b) { - return (a>b)?a:b; -} - /* This should be in utility.c */ #ifdef DEBUG_SHELL #ifndef __U_BOOT__ diff --git a/common/main.c b/common/main.c index 014804b..08d54c5 100644 --- a/common/main.c +++ b/common/main.c @@ -179,11 +179,19 @@ static __inline__ int abortboot(int bootdelay) # else /* !defined(CONFIG_AUTOBOOT_KEYED) */ +#ifdef CONFIG_MENUKEY +static int menukey = 0; +#endif + static __inline__ int abortboot(int bootdelay) { int abort = 0; +#ifdef CONFIG_MENUPROMPT + printf(CONFIG_MENUPROMPT, bootdelay); +#else printf("Hit any key to stop autoboot: %2d ", bootdelay); +#endif #if defined CONFIG_ZERO_BOOTDELAY_CHECK /* @@ -208,7 +216,11 @@ static __inline__ int abortboot(int bootdelay) if (tstc()) { /* we got a key press */ abort = 1; /* don't auto boot */ bootdelay = 0; /* no more delay */ +# ifdef CONFIG_MENUKEY + menukey = getc(); +# else (void) getc(); /* consume input */ +# endif break; } udelay (10000); @@ -323,8 +335,31 @@ void main_loop (void) disable_ctrlc(prev); /* restore Control C checking */ # endif } + +# ifdef CONFIG_MENUKEY + if (menukey == CONFIG_MENUKEY) + { + s = getenv("menucmd"); + if (s) + { +# ifndef CFG_HUSH_PARSER + run_command (s, bd, 0); +# else + parse_string_outer(s, FLAG_PARSE_SEMICOLON | + FLAG_EXIT_FROM_LOOP); +# endif + } + } +#endif /* CONFIG_MENUKEY */ #endif /* CONFIG_BOOTDELAY */ +#ifdef CONFIG_AMIGAONEG3SE + { + extern void video_banner(void); + video_banner(); + } +#endif + /* * Main Loop for Monitor Command Processing */ -- cgit v1.1