#endif
-#if (CONFIG_COMMANDS & CFG_CMD_DATE)
-#include <rtc.h>
-#endif
+/*#if defined(CONFIG_CMD_DATE) */
+/*#include <rtc.h> */
+/*#endif */
-#if (CONFIG_COMMANDS & CFG_CMD_FDC)
+#if defined(CONFIG_CMD_FDC) || defined(CONFIG_CMD_FDOS)
typedef struct {
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)
{
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 */
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 */
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)
}
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)
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)
{
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<<drives);
pCMD->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<<drives);
}
stop_fdc_drive(pCMD);
* setup the fdc according the datasheet
* assuming in PS2 Mode
*/
-int fdc_setup(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
/* first, we reset the FDC via the DOR */
write_fdc_reg(FDC_DOR,0x00);
for(i=0; i<255; i++) /* then we wait some time */
udelay(500);
/* then, we clear the reset in the DOR */
- pCMD->drive=0;
+ pCMD->drive=drive;
select_fdc_drive(pCMD);
/* initialize the CCR */
write_fdc_reg(FDC_CCR,pFG->rate);
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) {
/* then, we clear the reset in the DOR */
/* fdc_check_drive(pCMD,pFG); */
/* write_fdc_reg(FDC_DOR,0x04); */
+
return TRUE;
}
+#endif
+
+#if defined(CONFIG_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<<drive))==0) {
+ /* drive not available */
+ printf("\n** Drive %d not available **\n",drive);
+ return FALSE;
+ }
+ if((pCMD->flags&(0x10<<drive))==0) {
+ /* no disk inserted */
+ printf("\n** No disk inserted in drive %d **\n",drive);
+ return FALSE;
+ }
+ /* ok, we have a valid source */
+ pCMD->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
+
+#if defined(CONFIG_CMD_FDC)
/****************************************************************************
* main routine do_fdcboot
*/
{
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;
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);
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;
}
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++;
}
+#endif
+
+
+/***************************************************/
-#endif /* CONFIG_COMMANDS & CFG_CMD_FDC */
+#if defined(CONFIG_CMD_FDC)
+U_BOOT_CMD(
+ fdcboot, 3, 1, do_fdcboot,
+ "fdcboot - boot from floppy device\n",
+ "loadAddr drive\n"
+);
+#endif