X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=inline;f=common%2Fcmd_fdc.c;h=03f4ce6d34c918d295091c8ac384161f0b42b234;hb=5725f94aace1ed75bbeb9f3c528f34d1ae4dbe69;hp=712c14b57c7837fe85786fb2f31b56265f868cd0;hpb=3863585bb1c1e8f89b4a2e90c4b83f8b81b8e029;p=oweals%2Fu-boot.git diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 712c14b57c..03f4ce6d34 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -47,11 +47,11 @@ #endif -#if (CONFIG_COMMANDS & CFG_CMD_DATE) -#include -#endif +/*#if (CONFIG_COMMANDS & CFG_CMD_DATE) */ +/*#include */ +/*#endif */ -#if (CONFIG_COMMANDS & CFG_CMD_FDC) +#if ((CONFIG_COMMANDS & CFG_CMD_FDC) || (CONFIG_COMMANDS & CFG_CMD_FDOS)) typedef struct { @@ -173,21 +173,68 @@ const static FD_GEO_STRUCT floppy_type[2] = { static FDC_COMMAND_STRUCT cmd; /* global command struct */ +/* If the boot drive number is undefined, we assume it's drive 0 */ +#ifndef CFG_FDC_DRIVE_NUMBER +#define CFG_FDC_DRIVE_NUMBER 0 +#endif + +/* Hardware access */ +#ifndef CFG_ISA_IO_STRIDE +#define CFG_ISA_IO_STRIDE 1 +#endif + +#ifndef CFG_ISA_IO_OFFSET +#define CFG_ISA_IO_OFFSET 0 +#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) { - volatile unsigned char *val = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS | addr); - return val[0]; + volatile unsigned char *val = + (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS + + (addr * CFG_ISA_IO_STRIDE) + + CFG_ISA_IO_OFFSET); + + return val [0]; } /* writes a Register of the FDC */ void write_fdc_reg(unsigned int addr, unsigned char val) { - volatile unsigned char *tmp = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS | addr); - tmp[0]=val; + volatile unsigned char *tmp = + (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS + + (addr * CFG_ISA_IO_STRIDE) + + CFG_ISA_IO_OFFSET); + tmp[0]=val; } +#ifndef CONFIG_AMIGAONEG3SE /* waits for an interrupt (polling) */ int wait_for_fdc_int(void) { @@ -202,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 */ @@ -263,7 +311,9 @@ int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) head = sect / pFG->sect; /* head nr */ sect = sect % pFG->sect; /* remaining blocks */ sect++; /* sectors are 1 based */ - PRINTF("Track %ld, Head %ld, Sector %ld, Drive %d (blnr %ld)\n",track,head,sect,pCMD->drive,pCMD->blnr); + PRINTF("Cmd 0x%02x Track %ld, Head %ld, Sector %ld, Drive %d (blnr %ld)\n", + pCMD->cmd[0],track,head,sect,pCMD->drive,pCMD->blnr); + if(head|=0) { /* max heads = 2 */ pCMD->cmd[DRIVE]=pCMD->drive | 0x04; /* head 1 */ pCMD->cmd[HEAD]=(unsigned char) head; /* head register */ @@ -392,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) @@ -406,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) @@ -526,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) { @@ -538,20 +614,20 @@ int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) select_fdc_drive(pCMD); pCMD->blnr=0; /* set to the 1st block */ if(fdc_recalibrate(pCMD,pFG)==FALSE) - break; + continue; if((pCMD->result[STATUS_0]&0x10)==0x10) - break; + continue; /* ok drive connected check for disk */ state|=(1<blnr=pFG->size; /* set to the last block */ if(fdc_seek(pCMD,pFG)==FALSE) - break; + continue; pCMD->blnr=0; /* set to the 1st block */ if(fdc_recalibrate(pCMD,pFG)==FALSE) - break; + continue; pCMD->cmd[COMMAND]=FDC_CMD_READ_ID; if(fdc_issue_cmd(pCMD,pFG)==FALSE) - break; + continue; state|=(0x10<drive=0; + pCMD->drive=drive; select_fdc_drive(pCMD); /* initialize the CCR */ write_fdc_reg(FDC_CCR,pFG->rate); @@ -600,9 +684,8 @@ int fdc_setup(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) PRINTF("Sense Interrupt for drive %d failed\n",i); } } - /* assuming drive 0 for rest of configuration - * issue the configure command */ - pCMD->drive=0; + /* issue the configure command */ + pCMD->drive=drive; select_fdc_drive(pCMD); pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE; if(fdc_issue_cmd(pCMD,pFG)==FALSE) { @@ -621,9 +704,77 @@ int fdc_setup(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))*/ + +#if (CONFIG_COMMANDS & CFG_CMD_FDOS) + +/* Low level functions for the Floppy-DOS layer */ + +/************************************************************************** +* int fdc_fdos_init +* initialize the FDC layer +* +*/ +int fdc_fdos_init (int drive) +{ + FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; + FDC_COMMAND_STRUCT *pCMD = &cmd; + + /* setup FDC and scan for drives */ + if(fdc_setup(drive,pCMD,pFG)==FALSE) { + printf("\n** Error in setup FDC **\n"); + return FALSE; + } + if(fdc_check_drive(pCMD,pFG)==FALSE) { + printf("\n** Error in check_drives **\n"); + return FALSE; + } + if((pCMD->flags&(1<flags&(0x10<drive=drive; + + /* read first block */ + pCMD->blnr=0; return TRUE; } +/************************************************************************** +* int fdc_fdos_seek +* parameter is a block number +*/ +int fdc_fdos_seek (int where) +{ + FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; + FDC_COMMAND_STRUCT *pCMD = &cmd; + pCMD -> blnr = where ; + return (fdc_seek (pCMD, pFG)); +} +/************************************************************************** +* int fdc_fdos_read +* the length is in block number +*/ +int fdc_fdos_read (void *buffer, int len) +{ + FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; + FDC_COMMAND_STRUCT *pCMD = &cmd; + + return (fdc_read_data (buffer, len, pCMD, pFG)); +} +#endif /* (CONFIG_COMMANDS & CFG_CMD_FDOS) */ + +#if (CONFIG_COMMANDS & CFG_CMD_FDC) /**************************************************************************** * main routine do_fdcboot */ @@ -631,7 +782,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; FDC_COMMAND_STRUCT *pCMD = &cmd; - unsigned long addr,imsize; + unsigned long addr,imsize; image_header_t *hdr; /* used for fdc boot */ unsigned char boot_drive; int i,nrofblk; @@ -641,11 +792,11 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (argc) { case 1: addr = CFG_LOAD_ADDR; - boot_drive=0; /* default boot from drive 0 */ + boot_drive=CFG_FDC_DRIVE_NUMBER; break; case 2: addr = simple_strtoul(argv[1], NULL, 16); - boot_drive=0; /* default boot from drive 0 */ + boot_drive=CFG_FDC_DRIVE_NUMBER; break; case 3: addr = simple_strtoul(argv[1], NULL, 16); @@ -656,7 +807,7 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } /* setup FDC and scan for drives */ - if(fdc_setup(pCMD,pFG)==FALSE) { + if(fdc_setup(boot_drive,pCMD,pFG)==FALSE) { printf("\n** Error in setup FDC **\n"); return 1; } @@ -685,13 +836,13 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } hdr = (image_header_t *)addr; - if (hdr->ih_magic != IH_MAGIC) { + if (ntohl(hdr->ih_magic) != IH_MAGIC) { printf ("Bad Magic Number\n"); return 1; } print_image_hdr(hdr); - imsize= hdr->ih_size+sizeof(image_header_t); + imsize= ntohl(hdr->ih_size)+sizeof(image_header_t); nrofblk=imsize/512; if((imsize%512)>0) nrofblk++; @@ -729,7 +880,17 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } - #endif /* CONFIG_COMMANDS & CFG_CMD_FDC */ +/***************************************************/ + + +#if (CONFIG_COMMANDS & CFG_CMD_FDC) + +U_BOOT_CMD( + fdcboot, 3, 1, do_fdcboot, + "fdcboot - boot from floppy device\n", + "loadAddr drive\n" +); +#endif