Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Updated to include improved 8254
[palacios.git] / palacios / src / vmboot / rombios / rombios.c
index b8322d0..93654a2 100644 (file)
@@ -1,5 +1,6 @@
+//  -*- fundamental -*-
 /////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c,v 1.1 2007/11/29 20:26:38 pdinda Exp $
+// $Id: rombios.c,v 1.9 2008/07/02 17:58:44 pdinda Exp $
 /////////////////////////////////////////////////////////////////////////
 //
 //  Copyright (C) 2002  MandrakeSoft S.A.
@@ -58,7 +59,7 @@
 // $f859 ; INT 15h System Services Entry Point
 // $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters)
 // $fe6e ; INT 1Ah Time-of-day Service Entry Point
-// $fea5 ; INT 08h System Timer ISR Entry Point
+/// $fea5 ; INT 08h System Timer ISR Entry Point
 // $fef3 ; Initial Interrupt Vector Offsets Loaded by POST
 // $ff53 ; IRET Instruction for Dummy Interrupt Handler
 // $ff54 ; INT 05h Print Screen Service Entry Point
 //
 //   BCC Bug: find a generic way to handle the bug of #asm after an "if"  (fixed in 0.16.7)
 
-#define DEBUG_ROMBIOS      0
+#define DEBUG_ROMBIOS      1
 
 #define DEBUG_ATA          0
 #define DEBUG_INT13_HD     0
@@ -944,10 +945,10 @@ Bit16u cdrom_boot();
 
 #endif // BX_ELTORITO_BOOT
 
-static char bios_cvs_version_string[] = "$Revision: 1.1 $";
-static char bios_date_string[] = "$Date: 2007/11/29 20:26:38 $";
+static char bios_cvs_version_string[] = "$Revision: 1.9 $";
+static char bios_date_string[] = "$Date: 2008/07/02 17:58:44 $";
 
-static char CVSID[] = "$Id: rombios.c,v 1.1 2007/11/29 20:26:38 pdinda Exp $";
+static char CVSID[] = "$Id: rombios.c,v 1.9 2008/07/02 17:58:44 pdinda Exp $";
 
 /* Offset to skip the CVS $Id: prefix */ 
 #define bios_version_string  (CVSID + 4)
@@ -957,7 +958,7 @@ static char CVSID[] = "$Id: rombios.c,v 1.1 2007/11/29 20:26:38 pdinda Exp $";
 #define BIOS_PRINTF_INFO     4
 #define BIOS_PRINTF_DEBUG    8
 #define BIOS_PRINTF_ALL      (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO)
-#define BIOS_PRINTF_DEBHALT  (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT)
+#define BIOS_PRINTF_DEBHALT  (BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO | BIOS_PRINTF_HALT) 
 
 #define printf(format, p...)  bios_printf(BIOS_PRINTF_SCREEN, format, ##p)
 
@@ -965,7 +966,7 @@ static char CVSID[] = "$Id: rombios.c,v 1.1 2007/11/29 20:26:38 pdinda Exp $";
 // BX_DEBUG goes to INFO port until we can easily choose debug info on a 
 // per-device basis. Debug info are sent only in debug mode
 #if DEBUG_ROMBIOS
-#  define BX_DEBUG(format, p...)  bios_printf(BIOS_PRINTF_INFO, format, ##p)    
+#  define BX_DEBUG(format, p...)  bios_printf(BIOS_PRINTF_ALL, format, ##p)    
 #else
 #  define BX_DEBUG(format, p...) 
 #endif
@@ -1399,12 +1400,13 @@ ASM_END
 }
 
 //  Bit16u
-//get_DS()
-//{
-//ASM_START
-//  mov  ax, ds
-//ASM_END
-//}
+get_DS()
+{
+ASM_START
+  mov  ax, ds
+ASM_END
+}
+
 //
 //  void
 //set_DS(ds_selector)
@@ -1668,7 +1670,7 @@ keyboard_init()
     Bit16u max;
     int rc;
 
-    printf("rombios: keyboard_init\n");
+    BX_DEBUG("rombios: keyboard_init\n");
 
     /* printf("Assuming keyboard already inited and returning\n");
        return; */
@@ -1679,9 +1681,11 @@ keyboard_init()
     while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00); 
 
     /* flush incoming keys */
-    max=0x2000;
+    // temporarily chaged for debug -PAD
+    //    max=0x2000;  
+    max=10;
     while (--max > 0) {
-        outb(0x80, 0x00);
+        outb(0x80, 0x01);
         if (inb(0x64) & 0x01) {
             inb(0x60);
             max = 0x2000;
@@ -1699,12 +1703,12 @@ keyboard_init()
 
     /* Wait until buffer is empty */
     max=0xffff;
-    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00);
+    while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x02);
     if (max==0x0) keyboard_panic(00);
 
     /* Wait for data */
     max=0xffff;
-    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x01);
+    while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x03);
     if (max==0x0) keyboard_panic(01);
 
     /* read self-test result, 0x55 should be returned from 0x60 */
@@ -2127,7 +2131,7 @@ void ata_init( )
   Bit16u ebda_seg=read_word(0x0040,0x000E);
   Bit8u  channel, device;
 
-  printf("rom_bios: ata_init\n");
+  //BX_DEBUG("rombios: ata_init\n");
 
   // Channels info init. 
   for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) {
@@ -2176,6 +2180,8 @@ void ata_detect( )
   Bit8u  hdcount, cdcount, device, type;
   Bit8u  buffer[0x0200];
 
+  //BX_DEBUG("rombios: ata_detect\n");
+
 #if BX_MAX_ATA_INTERFACES > 0
   write_byte(ebda_seg,&EbdaData->ata.channels[0].iface,ATA_IFACE_ISA);
   write_word(ebda_seg,&EbdaData->ata.channels[0].iobase1,0x1f0);
@@ -2874,31 +2880,71 @@ Bit32u length;
   write_word(ebda_seg, &EbdaData->ata.trsfsectors,0);
   write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L);
 
+  // Device should not be busy yet 
+
+#define PDINDA 1
+
+#if PDINDA
+  // wait for device to be ready 
+  do {
+    status = inb(iobase1 + ATA_CB_STAT);
+    //    BX_DEBUG_ATA("ata_cmd_packet: wait (%2x)\n",status);
+  } while (status & ATA_CB_STAT_BSY);
+#else
   status = inb(iobase1 + ATA_CB_STAT);
   if (status & ATA_CB_STAT_BSY) return 2;
+#endif
+
 
+  // set "noninterruptable"
   outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
-  // outb(iobase1 + ATA_CB_FR, 0x00);
-  // outb(iobase1 + ATA_CB_SC, 0x00);
-  // outb(iobase1 + ATA_CB_SN, 0x00);
+
+  //outb(iobase1 + ATA_CB_FR, 0x00);
+  //outb(iobase1 + ATA_CB_SC, 0x00);
+  //outb(iobase1 + ATA_CB_SN, 0x00);
+
+  // Set cylinders ?? - Why?  And why not sector
+  // This is all embedded in cmd_packet, anyway...
   outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
   outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
+
+  // select master or slave
   outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
+
+  // Tell it we are sending a command packet
   outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
 
+#if 0
+  // Now wait for 400 ns
+  { 
+    int i;
+    for (i=0;i<0xffff; i++)
+      ;
+  }
+#endif
+
   // Device should ok to receive command
+  // wait until we get
   while (1) {
+
     status = inb(iobase1 + ATA_CB_STAT);
+
+#if PDINDA
+    if (!(status & ATA_CB_STAT_BSY))  break;
+#else       
+    // Shouldn't this be ATA_CB_STAT_RDY?  -PAD - NO, it's OK
     if ( !(status & ATA_CB_STAT_BSY) ) break;
-    }
+#endif
+
+  }
 
   if (status & ATA_CB_STAT_ERR) {
     BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status);
     return 3;
-    } else if ( !(status & ATA_CB_STAT_DRQ) ) {
+  } else if ( !(status & ATA_CB_STAT_DRQ) ) {
     BX_DEBUG_ATA("ata_cmd_packet : DRQ not set (status %02x)\n", (unsigned) status);
     return 4;
-    }
+  }
 
   // Normalize address
   cmdseg += (cmdoff / 16);
@@ -2925,61 +2971,74 @@ ASM_START
       pop  bp
 ASM_END
 
+  // issue read of alternative status - claimed to be in spec
+  //inb(iobase2+ATA_CB_ASTAT);
+
+
   if (inout == ATA_DATA_NO) {
     status = inb(iobase1 + ATA_CB_STAT);
     }
   else {
-  while (1) {
-
+    // Wait for completion
+    // PDINDA
+    do {
+      status=inb(iobase1+ATA_CB_STAT);
+      BX_DEBUG_ATA("ata_cmd_packet: wait (%2x)\n",status);
+    } while ((status & ATA_CB_STAT_BSY));
+    
+    while (1) {
+      
       status = inb(iobase1 + ATA_CB_STAT);
-
+      
       // Check if command completed
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 ) break;
-
+      
       if (status & ATA_CB_STAT_ERR) {
         BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
         return 3;
       }
-
+      
+      // If we get here, we are ready and should have DRQ
+      // and so data is available
       // Device must be ready to send data
       if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
-            != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
-        BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", status);
+          != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
+        BX_DEBUG_ATA("ata_cmd_packet 1: not ready (status %02x)\n", status);
         return 4;
-        }
-
+      }
+      
       // Normalize address
       bufseg += (bufoff / 16);
       bufoff %= 16;
-    
+      
       // Get the byte count
       lcount =  ((Bit16u)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
-
+      
       // adjust to read what we want
       if(header>lcount) {
-         lbefore=lcount;
-         header-=lcount;
-         lcount=0;
-         }
+       lbefore=lcount;
+       header-=lcount;
+       lcount=0;
+      }
       else {
         lbefore=header;
         header=0;
         lcount-=lbefore;
-        }
-
+      }
+      
       if(lcount>length) {
         lafter=lcount-length;
         lcount=length;
         length=0;
-        }
+      }
       else {
         lafter=0;
         length-=lcount;
-        }
-
+      }
+      
       // Save byte count
       count = lcount;
-
+      
       BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
       BX_DEBUG_ATA("to 0x%04x:0x%04x\n",bufseg,bufoff);
 
@@ -3088,7 +3147,7 @@ ASM_END
   // Final check, device must be ready
   if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 
          != ATA_CB_STAT_RDY ) {
-    BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", (unsigned) status);
+    BX_DEBUG_ATA("ata_cmd_packet 2 : not ready (status %02x)\n", (unsigned) status);
     return 4;
     }
 
@@ -3101,6 +3160,7 @@ ASM_END
 // End of ATA/ATAPI Driver
 // ---------------------------------------------------------------------------
 
+
 // ---------------------------------------------------------------------------
 // Start of ATA/ATAPI generic functions
 // ---------------------------------------------------------------------------
@@ -3188,7 +3248,7 @@ cdemu_init()
 {
   Bit16u ebda_seg=read_word(0x0040,0x000E);
 
-  printf("rombios: cdemu_init\n");
+  //BX_DEBUG("rombios: cdemu_init\n");
 
   // the only important data is this one for now
   write_byte(ebda_seg,&EbdaData->cdemu.active,0x00);
@@ -3224,6 +3284,7 @@ cdrom_boot()
   Bit16u boot_segment, nbsectors, i, error;
   Bit8u  device;
 
+
   // Find out the first cdrom
   for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
     if (atapi_is_cdrom(device)) break;
@@ -3244,6 +3305,7 @@ cdrom_boot()
   if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
     return 3;
 
+
   // Validity checks
   if(buffer[0]!=0)return 4;
   for(i=0;i<5;i++){
@@ -3266,6 +3328,8 @@ cdrom_boot()
   atacmd[5]=(lba & 0x000000ff);
   if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0)
     return 7;
+
+
  
   // Validation entry
   if(buffer[0x00]!=0x01)return 8;   // Header
@@ -3314,6 +3378,7 @@ cdrom_boot()
   if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0)
     return 12;
 
+
   // Remember the media type
   switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
     case 0x01:  // 1.2M floppy
@@ -4104,10 +4169,13 @@ ASM_END
          case 0x20: // coded by osmaker aka K.J.
             if(regs.u.r32.edx == 0x534D4150) /* SMAP */
             {
-#ifdef HVMASSIST
+#if defined(HVMASSIST) && 0
                if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
+
                    Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
 
+                    BX_DEBUG_INT15("OK bx=%x\n",regs.u.r16.bx);
+
                    if (regs.u.r16.bx + 0x14 <= e820_table_size) {
                        memcpyb(ES, regs.u.r16.di,
                                0xe000, 0x10 + regs.u.r16.bx, 0x14);
@@ -6681,6 +6749,9 @@ floppy_drive_exists(drive)
 {
   Bit8u  drive_type;
 
+  // just tell it both drives exist - PAD
+  return 1;
+
   // check CMOS to see if drive exists
   drive_type = inb_cmos(0x10);
   if (drive == 0)
@@ -6705,14 +6776,15 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
   Bit8u  drive_type, num_floppies, ah;
   Bit16u es, last_addr;
 
-  BX_DEBUG_INT13_FL("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
-  // BX_DEBUG_INT13_FL("int13_diskette: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(), get_DS(), ES, DI, SI);
+
+  //printf("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
+  BX_DEBUG_INT13_FL("int13_diskette: SS=%04x DS=%04x ES=%04x DI=%04x SI=%04x\n",get_SS(),get_DS(), ES, DI, SI);
 
   ah = GET_AH();
 
   switch ( ah ) {
     case 0x00: // diskette controller reset
-BX_DEBUG_INT13_FL("floppy f00\n");
+      BX_DEBUG_INT13_FL("floppy f00\n");
       drive = GET_ELDL();
       if (drive > 1) {
         SET_AH(1); // invalid param
@@ -7574,6 +7646,8 @@ Bit8u bseqnr;
   Bit16u bootseg;
   Bit16u status;
   Bit8u  lastdrive=0;
+  //  BX_DEBUG("rombios: int19 (%d)\n",bseqnr);
 
   // if BX_ELTORITO_BOOT is not defined, old behavior
   //   check bit 5 in CMOS reg 0x2d.  load either 0x00 or 0x80 into DL
@@ -7623,16 +7697,19 @@ Bit8u bseqnr;
   if (bootcd != 0) {
     status = cdrom_boot();
 
+    BX_DEBUG("CDBoot:%x\n",status);
+       
+
     // If failure
     if ( (status & 0x00ff) !=0 ) {
       print_cdromboot_failure(status);
       print_boot_failure(bootcd, bootdrv, 1, lastdrive);
       return 0x00000000;
-      }
-
+    }
+    
     bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
     bootdrv = (Bit8u)(status>>8);
-    }
+  }
 
 #endif // BX_ELTORITO_BOOT
 
@@ -7640,6 +7717,8 @@ Bit8u bseqnr;
   if (bootcd == 0) {
     bootseg=0x07c0;
 
+    
+
 ASM_START
     push bp
     mov  bp, sp
@@ -7664,6 +7743,7 @@ int19_load_done:
     pop  bp
 ASM_END
     
+
     if (status != 0) {
       print_boot_failure(bootcd, bootdrv, 1, lastdrive);
       return 0x00000000;
@@ -7691,11 +7771,14 @@ ASM_END
   
 #if BX_ELTORITO_BOOT
   // Print out the boot string
+  BX_DEBUG("cdrom_boot: %x\n",status);
   print_boot_device(bootcd, bootdrv);
 #else // BX_ELTORITO_BOOT
   print_boot_device(0, bootdrv);
 #endif // BX_ELTORITO_BOOT
 
+  BX_DEBUG("boot to %x\n", (((Bit32u)bootdrv) << 16) + bootseg);
+
   // return the boot segment
   return (((Bit32u)bootdrv) << 16) + bootseg;
 }
@@ -8223,7 +8306,9 @@ boot_setup:
   mov [bp],  ax      ;; set bp to zero
   mov ax,    #0xaa55 ;; set ok flag
 
+
   pop bp
+
   iret               ;; Beam me up Scotty
 
 ;----------
@@ -8760,7 +8845,7 @@ int76_handler:
   mov   ds, ax
   mov   0x008E, #0xff
   call  eoi_both_pics
-  pop   ds
+  pop   ds  
   pop   ax
   iret
 
@@ -9426,6 +9511,7 @@ rom_scan_loop:
   jne  rom_scan_increment
   call rom_checksum
   jnz  rom_scan_increment
+
   mov  al, [2]  ;; change increment to ROM length in 512-byte blocks
 
   ;; We want our increment in 512-byte quantities, rounded to
@@ -9753,6 +9839,8 @@ post_default_ints:
   ;; Video setup
   SET_INT_VECTOR(0x10, #0xF000, #int10_handler)
 
+
+
   ;; PIC
   mov al, #0x11 ; send initialisation commands
   out 0x20, al
@@ -9784,6 +9872,19 @@ post_default_ints:
 
   call rom_scan
 
+
+  ;; JRL CHANGE
+  ;;push ax
+  ;;push bx
+  ;;mov  ah, #0x0e
+  ;;mov  al, #0x41
+  ;;xor  bx,bx
+  ;;int  #0x10
+  ;;pop  bx
+  ;;pop ax
+
+
+
   call _print_bios_banner 
 
   ;;