~ubuntu-branches/ubuntu/hardy/kvm/hardy-backports

« back to all changes in this revision

Viewing changes to bios/rombios.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2008-02-26 13:10:57 UTC
  • mfrom: (1.1.18 upstream)
  • Revision ID: james.westby@ubuntu.com-20080226131057-s67x6l89mtjw1x9b
Tags: 1:62+dfsg-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
169
169
#define EBDA_SIZE          1              // In KiB
170
170
#define BASE_MEM_IN_K   (640 - EBDA_SIZE)
171
171
 
172
 
  // Define the application NAME
173
 
#if defined(BX_QEMU)
174
 
#  define BX_APPNAME "QEMU"
175
 
#elif defined(PLEX86)
176
 
#  define BX_APPNAME "Plex86"
177
 
#else
178
 
#  define BX_APPNAME "Bochs"
179
 
#endif
 
172
/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
 
173
#define IPL_SEG              0x9ff0
 
174
#define IPL_TABLE_OFFSET     0x0000
 
175
#define IPL_TABLE_ENTRIES    8
 
176
#define IPL_COUNT_OFFSET     0x0080  /* u16: number of valid table entries */
 
177
#define IPL_SEQUENCE_OFFSET  0x0082  /* u16: next boot device */
 
178
#define IPL_SIZE             0xff
 
179
#define IPL_TYPE_FLOPPY      0x01
 
180
#define IPL_TYPE_HARDDISK    0x02
 
181
#define IPL_TYPE_CDROM       0x03
 
182
#define IPL_TYPE_BEV         0x80
180
183
 
181
184
  // Sanity Checks
182
185
#if BX_USE_ATADRV && BX_CPU<3
289
292
      push di
290
293
 
291
294
      mov  cx, 10[bp] ; count
292
 
      cmp  cx, #0x00
 
295
      test cx, cx
293
296
      je   memsetb_end
294
297
      mov  ax, 4[bp] ; segment
295
298
      mov  es, ax
331
334
      push si
332
335
 
333
336
      mov  cx, 12[bp] ; count
334
 
      cmp  cx, #0x0000
 
337
      test cx, cx
335
338
      je   memcpyb_end
336
339
      mov  ax, 4[bp] ; dsegment
337
340
      mov  es, ax
378
381
      push si
379
382
 
380
383
      mov  cx, 12[bp] ; count
381
 
      cmp  cx, #0x0000
 
384
      test cx, cx
382
385
      je   memcpyd_end
383
386
      mov  ax, 4[bp] ; dsegment
384
387
      mov  es, ax
423
426
      mov  ds, ax
424
427
      mov  bx, 6[bp] ; offset
425
428
      mov  ax, [bx]
426
 
      inc  bx
427
 
      inc  bx
 
429
      add  bx, #2
428
430
      mov  dx, [bx]
429
431
      ;; ax = return value (word)
430
432
      ;; dx = return value (word)
453
455
      mov  bx, 6[bp] ; offset
454
456
      mov  ax, 8[bp] ; data word
455
457
      mov  [bx], ax  ; write data word
456
 
      inc  bx
457
 
      inc  bx
 
458
      add  bx, #2
458
459
      mov  ax, 10[bp] ; data word
459
460
      mov  [bx], ax  ; write data word
460
461
      pop  ds
491
492
  lcmpul:
492
493
    and eax, #0x0000FFFF
493
494
    shl ebx, #16
494
 
    add eax, ebx
 
495
    or  eax, ebx
495
496
    shr ebx, #16
496
497
    SEG SS
497
498
      cmp eax, dword ptr [di]
511
512
  lmulul:
512
513
    and eax, #0x0000FFFF
513
514
    shl ebx, #16
514
 
    add eax, ebx
 
515
    or  eax, ebx
515
516
    SEG SS
516
517
    mul eax, dword ptr [di]
517
518
    mov ebx, eax
546
547
  ltstul:
547
548
    and eax, #0x0000FFFF
548
549
    shl ebx, #16
549
 
    add eax, ebx
 
550
    or  eax, ebx
550
551
    shr ebx, #16
551
552
    test eax, eax
552
553
    ret
557
558
    jcxz lsr_exit
558
559
    and  eax, #0x0000FFFF
559
560
    shl  ebx, #16
560
 
    add  eax, ebx
 
561
    or   eax, ebx
561
562
  lsr_loop:
562
563
    shr  eax, #1
563
564
    loop lsr_loop
573
574
    jcxz lsl_exit
574
575
    and  eax, #0x0000FFFF
575
576
    shl  ebx, #16
576
 
    add  eax, ebx
 
577
    or   eax, ebx
577
578
  lsl_loop:
578
579
    shl  eax, #1
579
580
    loop lsl_loop
595
596
  ldivul:
596
597
    and  eax, #0x0000FFFF
597
598
    shl  ebx, #16
598
 
    add  eax, ebx
 
599
    or   eax, ebx
599
600
    xor  edx, edx
600
601
    SEG SS
601
602
    mov  bx,  2[di]
657
658
    Bit8u  device;       // Detected type of attached devices (hd/cd/none)
658
659
    Bit8u  removable;    // Removable device flag
659
660
    Bit8u  lock;         // Locks for removable devices
660
 
    // Bit8u  lba_capable;  // LBA capable flag - always yes for bochs devices
661
 
    Bit8u  mode;         // transfert mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
 
661
    Bit8u  mode;         // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA
662
662
    Bit16u blksize;      // block size
663
663
 
664
664
    Bit8u  translation;  // type of translation
758
758
    Bit32u  sector_count1;
759
759
    Bit32u  sector_count2;
760
760
    Bit16u  blksize;
 
761
    Bit16u  dpte_offset;
761
762
    Bit16u  dpte_segment;
762
 
    Bit16u  dpte_offset;
763
763
    Bit16u  key;
764
764
    Bit8u   dpi_length;
765
765
    Bit8u   reserved1;
837
837
  flags_t flags;
838
838
  } iret_addr_t;
839
839
 
 
840
typedef struct {
 
841
  Bit16u type;
 
842
  Bit16u flags;
 
843
  Bit32u vector;
 
844
  Bit32u description;
 
845
  Bit32u reserved;
 
846
  } ipl_entry_t;
 
847
 
840
848
 
841
849
 
842
850
static Bit8u          inb();
1104
1112
      { 0x5300, 0x532e,   none,   none, 0x20 }, /* Del */
1105
1113
      {   none,   none,   none,   none, none },
1106
1114
      {   none,   none,   none,   none, none },
1107
 
      { 0x565c, 0x567c,   none,   none, none }, /* \| */    
 
1115
      { 0x565c, 0x567c,   none,   none, none }, /* \| */
1108
1116
      { 0x5700, 0x5700,   none,   none, none }, /* F11 */
1109
1117
      { 0x5800, 0x5800,   none,   none, none }  /* F12 */
1110
1118
      };
1523
1531
 
1524
1532
//--------------------------------------------------------------------------
1525
1533
// bios_printf()
1526
 
//   A compact variable argument printf function which prints its output via
1527
 
//   an I/O port so that it can be logged by Bochs/Plex.
1528
 
//   Currently, only %x is supported (or %02x, %04x, etc).
 
1534
//   A compact variable argument printf function.
1529
1535
//
1530
 
//   Supports %[format_width][format]
1531
 
//   where format can be d,x,c,s
 
1536
//   Supports %[format_width][length]format
 
1537
//   where format can be x,X,u,d,s,c
 
1538
//   and the optional length modifier is l (ell)
1532
1539
//--------------------------------------------------------------------------
1533
1540
  void
1534
1541
bios_printf(action, s)
1539
1546
  bx_bool  in_format;
1540
1547
  short i;
1541
1548
  Bit16u  *arg_ptr;
1542
 
  Bit16u   arg_seg, arg, nibble, hibyte, shift_count, format_width;
 
1549
  Bit16u   arg_seg, arg, nibble, hibyte, shift_count, format_width, hexadd;
1543
1550
 
1544
1551
  arg_ptr = &s;
1545
1552
  arg_seg = get_SS();
1566
1573
      else {
1567
1574
        arg_ptr++; // increment to next arg
1568
1575
        arg = read_word(arg_seg, arg_ptr);
1569
 
        if (c == 'x') {
 
1576
        if (c == 'x' || c == 'X') {
1570
1577
          if (format_width == 0)
1571
1578
            format_width = 4;
 
1579
          if (c == 'x')
 
1580
            hexadd = 'a';
 
1581
          else
 
1582
            hexadd = 'A';
1572
1583
          for (i=format_width-1; i>=0; i--) {
1573
1584
            nibble = (arg >> (4 * i)) & 0x000f;
1574
 
            send (action, (nibble<=9)? (nibble+'0') : (nibble-10+'A'));
 
1585
            send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
1575
1586
            }
1576
1587
          }
1577
1588
        else if (c == 'u') {
1579
1590
          }
1580
1591
        else if (c == 'l') {
1581
1592
          s++;
 
1593
          c = read_byte(get_CS(), s); /* is it ld,lx,lu? */
1582
1594
          arg_ptr++; /* increment to next arg */
1583
1595
          hibyte = read_word(arg_seg, arg_ptr);
1584
 
          put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
 
1596
          if (c == 'd') {
 
1597
            if (hibyte & 0x8000)
 
1598
              put_luint(action, 0L-(((Bit32u) hibyte << 16) | arg), format_width-1, 1);
 
1599
            else
 
1600
              put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
 
1601
           }
 
1602
          else if (c == 'u') {
 
1603
            put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0);
 
1604
           }
 
1605
          else if (c == 'x' || c == 'X')
 
1606
           {
 
1607
            if (format_width == 0)
 
1608
              format_width = 8;
 
1609
            if (c == 'x')
 
1610
              hexadd = 'a';
 
1611
            else
 
1612
              hexadd = 'A';
 
1613
            for (i=format_width-1; i>=0; i--) {
 
1614
              nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f;
 
1615
              send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd));
 
1616
              }
 
1617
           }
1585
1618
          }
1586
1619
        else if (c == 'd') {
1587
1620
          if (arg & 0x8000)
1836
1869
// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm
1837
1870
//--------------------------------------------------------------------------
1838
1871
 
1839
 
/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
1840
 
#define IPL_SEG              0x9ff0
1841
 
#define IPL_TABLE_OFFSET     0x0000
1842
 
#define IPL_TABLE_ENTRIES    8
1843
 
#define IPL_COUNT_OFFSET     0x0080  /* u16: number of valid table entries */
1844
 
#define IPL_SEQUENCE_OFFSET  0x0082  /* u16: next boot device */
1845
 
 
1846
 
struct ipl_entry {
1847
 
  Bit16u type;
1848
 
  Bit16u flags;
1849
 
  Bit32u vector;
1850
 
  Bit32u description;
1851
 
  Bit32u reserved;
1852
 
};
1853
1872
 
1854
1873
static void
1855
 
init_boot_vectors() 
 
1874
init_boot_vectors()
1856
1875
{
1857
 
  struct ipl_entry e;
 
1876
  ipl_entry_t e;
1858
1877
  Bit16u count = 0;
1859
1878
  Bit16u ss = get_SS();
1860
1879
 
1861
1880
  /* Clear out the IPL table. */
1862
 
  memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, 0xff);
 
1881
  memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE);
1863
1882
 
1864
1883
  /* Floppy drive */
1865
 
  e.type = 1; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
 
1884
  e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1866
1885
  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
1867
1886
  count++;
1868
1887
 
1869
1888
  /* First HDD */
1870
 
  e.type = 2; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
 
1889
  e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1871
1890
  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
1872
1891
  count++;
1873
1892
 
1874
1893
#if BX_ELTORITO_BOOT
1875
1894
  /* CDROM */
1876
 
  e.type = 3; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
 
1895
  e.type = IPL_TYPE_CDROM; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0;
1877
1896
  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
1878
1897
  count++;
1879
1898
#endif
1886
1905
 
1887
1906
static Bit8u
1888
1907
get_boot_vector(i, e)
1889
 
Bit16u i; struct ipl_entry *e;
 
1908
Bit16u i; ipl_entry_t *e;
1890
1909
{
1891
1910
  Bit16u count;
1892
1911
  Bit16u ss = get_SS();
1911
1930
  Bit16u type;
1912
1931
{
1913
1932
  /* NIC appears as type 0x80 */
1914
 
  if (type == 0x80 ) type = 0x4;
1915
 
  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n"); 
 
1933
  if (type == IPL_TYPE_BEV) type = 0x4;
 
1934
  if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n");
1916
1935
  printf("Booting from %s...\n", drivetypes[type]);
1917
1936
}
1918
1937
 
2050
2069
// bits 7-4 of the device/head (CB_DH) reg
2051
2070
#define ATA_CB_DH_DEV0 0xa0    // select device 0
2052
2071
#define ATA_CB_DH_DEV1 0xb0    // select device 1
 
2072
#define ATA_CB_DH_LBA 0x40    // use LBA
2053
2073
 
2054
2074
// status reg (CB_STAT and CB_ASTAT) bits
2055
2075
#define ATA_CB_STAT_BSY  0x80  // busy
2099
2119
#define ATA_CMD_READ_SECTORS                 0x20
2100
2120
#define ATA_CMD_READ_VERIFY_SECTORS          0x40
2101
2121
#define ATA_CMD_RECALIBRATE                  0x10
 
2122
#define ATA_CMD_REQUEST_SENSE                0x03
2102
2123
#define ATA_CMD_SEEK                         0x70
2103
2124
#define ATA_CMD_SET_FEATURES                 0xEF
2104
2125
#define ATA_CMD_SET_MULTIPLE_MODE            0xC6
2189
2210
  write_byte(ebda_seg,&EbdaData->ata.cdcount,0);
2190
2211
}
2191
2212
 
 
2213
#define TIMEOUT 0
 
2214
#define BSY 1
 
2215
#define NOT_BSY 2
 
2216
#define NOT_BSY_DRQ 3
 
2217
#define NOT_BSY_NOT_DRQ 4
 
2218
#define NOT_BSY_RDY 5
 
2219
 
 
2220
#define IDE_TIMEOUT 32000u //32 seconds max for IDE ops
 
2221
 
 
2222
int await_ide();
 
2223
static int await_ide(when_done,base,timeout)
 
2224
  Bit8u when_done;
 
2225
  Bit16u base;
 
2226
  Bit16u timeout;
 
2227
{
 
2228
  Bit32u time=0,last=0;
 
2229
  Bit16u status;
 
2230
  Bit8u result;
 
2231
  status = inb(base + ATA_CB_STAT); // for the times you're supposed to throw one away
 
2232
  for(;;) {
 
2233
    status = inb(base+ATA_CB_STAT);
 
2234
    time++;
 
2235
    if (when_done == BSY)
 
2236
      result = status & ATA_CB_STAT_BSY;
 
2237
    else if (when_done == NOT_BSY)
 
2238
      result = !(status & ATA_CB_STAT_BSY);
 
2239
    else if (when_done == NOT_BSY_DRQ)
 
2240
      result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ);
 
2241
    else if (when_done == NOT_BSY_NOT_DRQ)
 
2242
      result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ);
 
2243
    else if (when_done == NOT_BSY_RDY)
 
2244
      result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY);
 
2245
    else if (when_done == TIMEOUT)
 
2246
      result = 0;
 
2247
 
 
2248
    if (result) return 0;
 
2249
    if (time>>16 != last) // mod 2048 each 16 ms
 
2250
    {
 
2251
      last = time >>16;
 
2252
      BX_DEBUG_ATA("await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout);
 
2253
    }
 
2254
    if (status & ATA_CB_STAT_ERR)
 
2255
    {
 
2256
      BX_DEBUG_ATA("await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout);
 
2257
      return -1;
 
2258
    }
 
2259
    if ((timeout == 0) || ((time>>11) > timeout)) break;
 
2260
  }
 
2261
  BX_INFO("IDE time out\n");
 
2262
  return -1;
 
2263
}
 
2264
 
2192
2265
// ---------------------------------------------------------------------------
2193
2266
// ATA/ATAPI driver : device detection
2194
2267
// ---------------------------------------------------------------------------
2447
2520
        case ATA_TYPE_ATA:
2448
2521
          printf("ata%d %s: ",channel,slave?" slave":"master");
2449
2522
          i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c);
2450
 
          if (sizeinmb < 1UL<<16)
2451
 
            printf(" ATA-%d Hard-Disk (%04u MBytes)\n",version,(Bit16u)sizeinmb);
2452
 
          else
2453
 
            printf(" ATA-%d Hard-Disk (%04u GBytes)\n",version,(Bit16u)(sizeinmb>>10));
 
2523
          if (sizeinmb < (1UL<<16))
 
2524
            printf(" ATA-%d Hard-Disk (%4u MBytes)\n", version, (Bit16u)sizeinmb);
 
2525
          else
 
2526
            printf(" ATA-%d Hard-Disk (%4u GBytes)\n", version, (Bit16u)(sizeinmb>>10));
2454
2527
          break;
2455
2528
        case ATA_TYPE_ATAPI:
2456
2529
          printf("ata%d %s: ",channel,slave?" slave":"master");
2492
2565
  Bit16u ebda_seg=read_word(0x0040,0x000E);
2493
2566
  Bit16u iobase1, iobase2;
2494
2567
  Bit8u  channel, slave, sn, sc;
 
2568
  Bit8u  type;
2495
2569
  Bit16u max;
2496
2570
 
2497
2571
  channel = device / 2;
2506
2580
  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST);
2507
2581
 
2508
2582
// 8.2.1 (b) -- wait for BSY
2509
 
  max=0xff;
2510
 
  while(--max>0) {
2511
 
    Bit8u status = inb(iobase1+ATA_CB_STAT);
2512
 
    if ((status & ATA_CB_STAT_BSY) != 0) break;
2513
 
  }
 
2583
  await_ide(BSY, iobase1, 20);
2514
2584
 
2515
2585
// 8.2.1 (f) -- clear SRST
2516
2586
  outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
2517
2587
 
2518
 
  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_NONE) {
 
2588
  type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type);
 
2589
  if (type != ATA_TYPE_NONE) {
2519
2590
 
2520
2591
// 8.2.1 (g) -- check for sc==sn==0x01
2521
2592
    // select device
2524
2595
    sn = inb(iobase1+ATA_CB_SN);
2525
2596
 
2526
2597
    if ( (sc==0x01) && (sn==0x01) ) {
 
2598
      if (type == ATA_TYPE_ATA) //ATA
 
2599
        await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT);
 
2600
      else //ATAPI
 
2601
        await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
 
2602
    }
2527
2603
 
2528
2604
// 8.2.1 (h) -- wait for not BSY
2529
 
      max=0xff;
2530
 
      while(--max>0) {
2531
 
        Bit8u status = inb(iobase1+ATA_CB_STAT);
2532
 
        if ((status & ATA_CB_STAT_BSY) == 0) break;
2533
 
        }
2534
 
      }
2535
 
    }
2536
 
 
2537
 
// 8.2.1 (i) -- wait for DRDY
2538
 
  max=0xfff;
2539
 
  while(--max>0) {
2540
 
    Bit8u status = inb(iobase1+ATA_CB_STAT);
2541
 
      if ((status & ATA_CB_STAT_RDY) != 0) break;
 
2605
    await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2542
2606
  }
2543
2607
 
2544
2608
  // Enable interrupts
2606
2670
      lba &= (1UL << 24) - 1;
2607
2671
      }
2608
2672
    sector = (Bit16u) (lba & 0x000000ffL);
2609
 
    lba >>= 8;
2610
 
    cylinder = (Bit16u) (lba & 0x0000ffffL);
2611
 
    lba >>= 16;
2612
 
    head = ((Bit16u) (lba & 0x0000000fL)) | 0x40;
2613
 
    }
 
2673
    cylinder = (Bit16u) ((lba>>8) & 0x0000ffffL);
 
2674
    head = ((Bit16u) ((lba>>24) & 0x0000000fL)) | ATA_CB_DH_LBA;
 
2675
  }
2614
2676
 
2615
2677
  outb(iobase1 + ATA_CB_FR, 0x00);
2616
2678
  outb(iobase1 + ATA_CB_SC, count);
2620
2682
  outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head );
2621
2683
  outb(iobase1 + ATA_CB_CMD, command);
2622
2684
 
2623
 
  while (1) {
2624
 
    status = inb(iobase1 + ATA_CB_STAT);
2625
 
    if ( !(status & ATA_CB_STAT_BSY) ) break;
2626
 
    }
 
2685
  await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
 
2686
  status = inb(iobase1 + ATA_CB_STAT);
2627
2687
 
2628
2688
  if (status & ATA_CB_STAT_ERR) {
2629
2689
    BX_DEBUG_ATA("ata_cmd_data_in : read error\n");
2683
2743
    current++;
2684
2744
    write_word(ebda_seg, &EbdaData->ata.trsfsectors,current);
2685
2745
    count--;
 
2746
    await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2686
2747
    status = inb(iobase1 + ATA_CB_STAT);
2687
2748
    if (count == 0) {
2688
2749
      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
2760
2821
      lba &= (1UL << 24) - 1;
2761
2822
      }
2762
2823
    sector = (Bit16u) (lba & 0x000000ffL);
2763
 
    lba >>= 8;
2764
 
    cylinder = (Bit16u) (lba & 0x0000ffffL);
2765
 
    lba >>= 16;
2766
 
    head = ((Bit16u) (lba & 0x0000000fL)) | 0x40;
2767
 
    }
 
2824
    cylinder = (Bit16u) ((lba>>8) & 0x0000ffffL);
 
2825
    head = ((Bit16u) ((lba>>24) & 0x0000000fL)) | ATA_CB_DH_LBA;
 
2826
  }
2768
2827
 
2769
2828
  outb(iobase1 + ATA_CB_FR, 0x00);
2770
2829
  outb(iobase1 + ATA_CB_SC, count);
2774
2833
  outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head );
2775
2834
  outb(iobase1 + ATA_CB_CMD, command);
2776
2835
 
2777
 
  while (1) {
2778
 
    status = inb(iobase1 + ATA_CB_STAT);
2779
 
    if ( !(status & ATA_CB_STAT_BSY) ) break;
2780
 
    }
 
2836
  await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
 
2837
  status = inb(iobase1 + ATA_CB_STAT);
2781
2838
 
2782
2839
  if (status & ATA_CB_STAT_ERR) {
2783
2840
    BX_DEBUG_ATA("ata_cmd_data_out : read error\n");
2916
2973
  if (status & ATA_CB_STAT_BSY) return 2;
2917
2974
 
2918
2975
  outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
2919
 
  // outb(iobase1 + ATA_CB_FR, 0x00);
2920
 
  // outb(iobase1 + ATA_CB_SC, 0x00);
2921
 
  // outb(iobase1 + ATA_CB_SN, 0x00);
 
2976
  outb(iobase1 + ATA_CB_FR, 0x00);
 
2977
  outb(iobase1 + ATA_CB_SC, 0x00);
 
2978
  outb(iobase1 + ATA_CB_SN, 0x00);
2922
2979
  outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
2923
2980
  outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
2924
2981
  outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
2925
2982
  outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
2926
2983
 
2927
2984
  // Device should ok to receive command
2928
 
  while (1) {
2929
 
    status = inb(iobase1 + ATA_CB_STAT);
2930
 
    if ( !(status & ATA_CB_STAT_BSY) ) break;
2931
 
    }
 
2985
  await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
 
2986
  status = inb(iobase1 + ATA_CB_STAT);
2932
2987
 
2933
2988
  if (status & ATA_CB_STAT_ERR) {
2934
2989
    BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status);
2964
3019
ASM_END
2965
3020
 
2966
3021
  if (inout == ATA_DATA_NO) {
 
3022
    await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
2967
3023
    status = inb(iobase1 + ATA_CB_STAT);
2968
3024
    }
2969
3025
  else {
 
3026
        Bit16u loops = 0;
 
3027
        Bit8u sc;
2970
3028
  while (1) {
2971
3029
 
 
3030
      if (loops == 0) {//first time through
 
3031
        status = inb(iobase2 + ATA_CB_ASTAT);
 
3032
        await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
 
3033
      }
 
3034
      else
 
3035
        await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
 
3036
      loops++;
 
3037
 
2972
3038
      status = inb(iobase1 + ATA_CB_STAT);
 
3039
      sc = inb(iobase1 + ATA_CB_SC);
2973
3040
 
2974
3041
      // Check if command completed
2975
 
      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 ) break;
 
3042
      if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) &&
 
3043
         ((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY)) break;
2976
3044
 
2977
3045
      if (status & ATA_CB_STAT_ERR) {
2978
3046
        BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status);
2979
3047
        return 3;
2980
3048
      }
2981
3049
 
2982
 
      // Device must be ready to send data
2983
 
      if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
2984
 
            != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
2985
 
        BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", status);
2986
 
        return 4;
2987
 
        }
2988
 
 
2989
3050
      // Normalize address
2990
3051
      bufseg += (bufoff / 16);
2991
3052
      bufoff %= 16;
3144
3205
// ---------------------------------------------------------------------------
3145
3206
 
3146
3207
  Bit16u
3147
 
atapi_get_sense(device)
 
3208
atapi_get_sense(device, seg, asc, ascq)
3148
3209
  Bit16u device;
3149
3210
{
3150
3211
  Bit8u  atacmd[12];
3151
 
  Bit8u  buffer[16];
 
3212
  Bit8u  buffer[18];
3152
3213
  Bit8u i;
3153
3214
 
3154
3215
  memsetb(get_SS(),atacmd,0,12);
3155
3216
 
3156
3217
  // Request SENSE
3157
 
  atacmd[0]=0x03;
3158
 
  atacmd[4]=0x20;
3159
 
  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 16L, ATA_DATA_IN, get_SS(), buffer) != 0)
 
3218
  atacmd[0]=ATA_CMD_REQUEST_SENSE;
 
3219
  atacmd[4]=sizeof(buffer);
 
3220
  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 18L, ATA_DATA_IN, get_SS(), buffer) != 0)
3160
3221
    return 0x0002;
3161
3222
 
3162
 
  if ((buffer[0] & 0x7e) == 0x70) {
3163
 
    return (((Bit16u)buffer[2]&0x0f)*0x100)+buffer[12];
3164
 
    }
 
3223
  write_byte(seg,asc,buffer[12]);
 
3224
  write_byte(seg,ascq,buffer[13]);
3165
3225
 
3166
3226
  return 0;
3167
3227
}
3170
3230
atapi_is_ready(device)
3171
3231
  Bit16u device;
3172
3232
{
3173
 
  Bit8u  atacmd[12];
3174
 
  Bit8u  buffer[];
3175
 
 
3176
 
  memsetb(get_SS(),atacmd,0,12);
3177
 
 
3178
 
  // Test Unit Ready
3179
 
  if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
3180
 
    return 0x000f;
3181
 
 
3182
 
  if (atapi_get_sense(device) !=0 ) {
3183
 
    memsetb(get_SS(),atacmd,0,12);
3184
 
 
3185
 
    // try to send Test Unit Ready again
3186
 
    if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 0L, ATA_DATA_NO, get_SS(), buffer) != 0)
3187
 
      return 0x000f;
3188
 
 
3189
 
    return atapi_get_sense(device);
 
3233
  Bit8u packet[12];
 
3234
  Bit8u buf[8];
 
3235
  Bit32u block_len;
 
3236
  Bit32u sectors;
 
3237
  Bit32u timeout; //measured in ms
 
3238
  Bit32u time;
 
3239
  Bit8u asc, ascq;
 
3240
  Bit8u in_progress;
 
3241
  Bit16u ebda_seg = read_word(0x0040,0x000E);
 
3242
  if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) {
 
3243
    printf("not implemented for non-ATAPI device\n");
 
3244
    return -1;
 
3245
  }
 
3246
 
 
3247
  BX_DEBUG_ATA("ata_detect_medium: begin\n");
 
3248
  memsetb(get_SS(),packet, 0, sizeof packet);
 
3249
  packet[0] = 0x25; /* READ CAPACITY */
 
3250
 
 
3251
  /* Retry READ CAPACITY 50 times unless MEDIUM NOT PRESENT
 
3252
   * is reported by the device. If the device reports "IN PROGRESS",
 
3253
   * 30 seconds is added. */
 
3254
  timeout = 5000;
 
3255
  time = 0;
 
3256
  in_progress = 0;
 
3257
  while (time < timeout) {
 
3258
    if (ata_cmd_packet(device, sizeof(packet), get_SS(), packet, 0, 8L, ATA_DATA_IN, get_SS(), buf) == 0)
 
3259
      goto ok;
 
3260
 
 
3261
    if (atapi_get_sense(device, get_SS(), &asc, &ascq) == 0) {
 
3262
      if (asc == 0x3a) { /* MEDIUM NOT PRESENT */
 
3263
        BX_DEBUG_ATA("Device reports MEDIUM NOT PRESENT\n");
 
3264
        return -1;
 
3265
      }
 
3266
 
 
3267
      if (asc == 0x04 && ascq == 0x01 && !in_progress) {
 
3268
        /* IN PROGRESS OF BECOMING READY */
 
3269
        printf("Waiting for device to detect medium... ");
 
3270
        /* Allow 30 seconds more */
 
3271
        timeout = 30000;
 
3272
        in_progress = 1;
 
3273
      }
3190
3274
    }
 
3275
    time += 100;
 
3276
  }
 
3277
  BX_DEBUG_ATA("read capacity failed\n");
 
3278
  return -1;
 
3279
ok:
 
3280
 
 
3281
  block_len = (Bit32u) buf[4] << 24
 
3282
    | (Bit32u) buf[5] << 16
 
3283
    | (Bit32u) buf[6] << 8
 
3284
    | (Bit32u) buf[7] << 0;
 
3285
  BX_DEBUG_ATA("block_len=%u\n", block_len);
 
3286
 
 
3287
  if (block_len!= 2048 && block_len!= 512)
 
3288
  {
 
3289
    printf("Unsupported sector size %u\n", block_len);
 
3290
    return -1;
 
3291
  }
 
3292
  write_dword(ebda_seg,&EbdaData->ata.devices[device].blksize, block_len);
 
3293
 
 
3294
  sectors = (Bit32u) buf[0] << 24
 
3295
    | (Bit32u) buf[1] << 16
 
3296
    | (Bit32u) buf[2] << 8
 
3297
    | (Bit32u) buf[3] << 0;
 
3298
 
 
3299
  BX_DEBUG_ATA("sectors=%u\n", sectors);
 
3300
  if (block_len == 2048)
 
3301
    sectors <<= 2; /* # of sectors in 512-byte "soft" sector */
 
3302
  if (sectors != read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors))
 
3303
    printf("%dMB medium detected\n", sectors>>(20-9));
 
3304
  write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors, sectors);
3191
3305
  return 0;
3192
3306
}
3193
3307
 
4154
4268
      ;; Get the count in eax
4155
4269
      mov  bx, sp
4156
4270
      SEG SS
4157
 
        mov  ax, _int15_function.CX [bx]
 
4271
        mov  ax, _int15_function32.CX [bx]
4158
4272
      shl  eax, #16
4159
4273
      SEG SS
4160
 
        mov  ax, _int15_function.DX [bx]
 
4274
        mov  ax, _int15_function32.DX [bx]
4161
4275
 
4162
4276
      ;; convert to numbers of 15usec ticks
4163
4277
      mov ebx, #15
5039
5153
 
5040
5154
    case 0x15: /* read disk drive size */
5041
5155
 
5042
 
      // Get physical geometry from table
5043
 
      npc   = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.cylinders);
5044
 
      nph   = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.heads);
5045
 
      npspt = read_word(ebda_seg, &EbdaData->ata.devices[device].pchs.spt);
 
5156
      // Get logical geometry from table
 
5157
      nlc   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.cylinders);
 
5158
      nlh   = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.heads);
 
5159
      nlspt = read_word(ebda_seg, &EbdaData->ata.devices[device].lchs.spt);
5046
5160
 
5047
5161
      // Compute sector count seen by int13
5048
 
      lba = (Bit32u)(npc - 1) * (Bit32u)nph * (Bit32u)npspt;
 
5162
      lba = (Bit32u)(nlc - 1) * (Bit32u)nlh * (Bit32u)nlspt;
5049
5163
      CX = lba >> 16;
5050
5164
      DX = lba & 0xffff;
5051
5165
 
5133
5247
        blksize = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize);
5134
5248
 
5135
5249
        write_word(DS, SI+(Bit16u)&Int13DPT->size, 0x1a);
5136
 
        write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
5137
 
        write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
 
5250
        if ((lba/npspt)/nph > 0x3fff)
 
5251
        {
 
5252
          write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x00); // geometry is invalid
 
5253
          write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, 0x3fff);
 
5254
        }
 
5255
        else
 
5256
        {
 
5257
          write_word(DS, SI+(Bit16u)&Int13DPT->infos, 0x02); // geometry is valid
 
5258
          write_dword(DS, SI+(Bit16u)&Int13DPT->cylinders, (Bit32u)npc);
 
5259
        }
5138
5260
        write_dword(DS, SI+(Bit16u)&Int13DPT->heads, (Bit32u)nph);
5139
5261
        write_dword(DS, SI+(Bit16u)&Int13DPT->spt, (Bit32u)npspt);
5140
5262
        write_dword(DS, SI+(Bit16u)&Int13DPT->sector_count1, lba);  // FIXME should be Bit64
5160
5282
        mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode);
5161
5283
        translation = read_byte(ebda_seg, &EbdaData->ata.devices[device].translation);
5162
5284
 
5163
 
        options  = (translation==ATA_TRANSLATION_NONE?0:1<<3); // chs translation
 
5285
        options  = (translation==ATA_TRANSLATION_NONE?0:1)<<3; // chs translation
5164
5286
        options |= (1<<4); // lba translation
5165
 
        options |= (mode==ATA_MODE_PIO32?1:0<<7);
5166
 
        options |= (translation==ATA_TRANSLATION_LBA?1:0<<9);
5167
 
        options |= (translation==ATA_TRANSLATION_RECHS?3:0<<9);
 
5287
        options |= (mode==ATA_MODE_PIO32?1:0)<<7;
 
5288
        options |= (translation==ATA_TRANSLATION_LBA?1:0)<<9;
 
5289
        options |= (translation==ATA_TRANSLATION_RECHS?3:0)<<9;
5168
5290
 
5169
5291
        write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
5170
 
        write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2);
 
5292
        write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC);
5171
5293
        write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 );
5172
5294
        write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
5173
5295
        write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
5176
5298
        write_byte(ebda_seg, &EbdaData->ata.dpte.pio, 0 );
5177
5299
        write_word(ebda_seg, &EbdaData->ata.dpte.options, options);
5178
5300
        write_word(ebda_seg, &EbdaData->ata.dpte.reserved, 0);
5179
 
        write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
 
5301
        if (size >=0x42)
 
5302
          write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
 
5303
        else
 
5304
          write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x10);
5180
5305
 
5181
5306
        checksum=0;
5182
 
        for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
 
5307
        for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, ((Bit8u*)(&EbdaData->ata.dpte)) + i);
5183
5308
        checksum = ~checksum;
5184
5309
        write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
5185
5310
        }
5452
5577
        mov  bp, sp
5453
5578
 
5454
5579
        mov ah, #0x52
5455
 
        int 15
 
5580
        int #0x15
5456
5581
        mov _int13_cdrom.status + 2[bp], ah
5457
5582
        jnc int13_cdrom_rme_end
5458
5583
        mov _int13_cdrom.status, #1
5515
5640
        options |= (mode==ATA_MODE_PIO32?1:0<<7);
5516
5641
 
5517
5642
        write_word(ebda_seg, &EbdaData->ata.dpte.iobase1, iobase1);
5518
 
        write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2);
 
5643
        write_word(ebda_seg, &EbdaData->ata.dpte.iobase2, iobase2 + ATA_CB_DC);
5519
5644
        write_byte(ebda_seg, &EbdaData->ata.dpte.prefix, (0xe | (device % 2))<<4 );
5520
5645
        write_byte(ebda_seg, &EbdaData->ata.dpte.unused, 0xcb );
5521
5646
        write_byte(ebda_seg, &EbdaData->ata.dpte.irq, irq );
5527
5652
        write_byte(ebda_seg, &EbdaData->ata.dpte.revision, 0x11);
5528
5653
 
5529
5654
        checksum=0;
5530
 
        for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, (&EbdaData->ata.dpte) + i);
 
5655
        for (i=0; i<15; i++) checksum+=read_byte(ebda_seg, ((Bit8u*)(&EbdaData->ata.dpte)) + i);
5531
5656
        checksum = ~checksum;
5532
5657
        write_byte(ebda_seg, &EbdaData->ata.dpte.checksum, checksum);
5533
5658
        }
6521
6646
    hd_type = inb_cmos(0x12) & 0x0f;
6522
6647
    if (hd_type != 0x0f)
6523
6648
      BX_INFO(panic_msg_reg12h,1);
6524
 
    hd_type = inb_cmos(0x1a); // HD0: extended type
 
6649
    hd_type = inb_cmos(0x1a); // HD1: extended type
6525
6650
    if (hd_type != 47)
6526
6651
      BX_INFO(panic_msg_reg19h,0,0x1a);
6527
6652
    iobase = 0x24;
6540
6665
 
6541
6666
#endif //else BX_USE_ATADRV
6542
6667
 
 
6668
#if BX_SUPPORT_FLOPPY
6543
6669
 
6544
6670
//////////////////////
6545
6671
// FLOPPY functions //
6813
6939
    return(1);
6814
6940
}
6815
6941
 
6816
 
#if BX_SUPPORT_FLOPPY
6817
6942
  void
6818
6943
int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
6819
6944
  Bit16u DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS;
7655
7780
  Bit16u bootip;
7656
7781
  Bit16u status;
7657
7782
 
7658
 
  struct ipl_entry e;
 
7783
  ipl_entry_t e;
7659
7784
 
7660
7785
  // if BX_ELTORITO_BOOT is not defined, old behavior
7661
7786
  //   check bit 5 in CMOS reg 0x2d.  load either 0x00 or 0x80 into DL
7705
7830
  print_boot_device(e.type);
7706
7831
 
7707
7832
  switch(e.type) {
7708
 
  case 0x01: /* FDD */
7709
 
  case 0x02: /* HDD */
 
7833
  case IPL_TYPE_FLOPPY: /* FDD */
 
7834
  case IPL_TYPE_HARDDISK: /* HDD */
7710
7835
 
7711
 
    bootdrv = (e.type == 0x02) ? 0x80 : 0x00;
 
7836
    bootdrv = (e.type == IPL_TYPE_HARDDISK) ? 0x80 : 0x00;
7712
7837
    bootseg = 0x07c0;
7713
7838
    status = 0;
7714
7839
 
7749
7874
 
7750
7875
    /* Always check the signature on a HDD boot sector; on FDD, only do
7751
7876
     * the check if the CMOS doesn't tell us to skip it */
7752
 
    if ((e.type != 0x01) || !((inb_cmos(0x38) & 0x01))) {
 
7877
    if ((e.type != IPL_TYPE_FLOPPY) || !((inb_cmos(0x38) & 0x01))) {
7753
7878
      if (read_word(bootseg,0x1fe) != 0xaa55) {
7754
7879
        print_boot_failure(e.type, 0);
7755
7880
        return;
7762
7887
  break;
7763
7888
 
7764
7889
#if BX_ELTORITO_BOOT
7765
 
  case 0x03: /* CD-ROM */
 
7890
  case IPL_TYPE_CDROM: /* CD-ROM */
7766
7891
    status = cdrom_boot();
7767
7892
 
7768
7893
    // If failure
7780
7905
    break;
7781
7906
#endif
7782
7907
 
7783
 
  case 0x80: /* Expansion ROM with a Bootstrap Entry Vector (a far pointer) */
 
7908
  case IPL_TYPE_BEV: /* Expansion ROM with a Bootstrap Entry Vector (a far pointer) */
7784
7909
    bootseg = e.vector >> 16;
7785
7910
    bootip = e.vector & 0xffff;
7786
7911
    break;
8311
8436
 
8312
8437
  push bp
8313
8438
  mov  bp, sp
8314
 
  
 
8439
 
8315
8440
  ;; Reset SS and SP
8316
8441
  mov  ax, #0xfffe
8317
8442
  mov  sp, ax
9550
9675
  mov  dx, #0x0cfc
9551
9676
  mov  ax, #0x8080
9552
9677
  out  dx, ax ;; reset PIRQ route control
9553
 
  inc  dx
9554
 
  inc  dx
 
9678
  add  dx, #2
9555
9679
  out  dx, ax
9556
9680
  mov  ax, [si+6]
9557
9681
  sub  ax, #0x20
9685
9809
  mov eax, #0x00040000
9686
9810
  call eax
9687
9811
 
9688
 
  ;; reset the memory (some boot loaders such as syslinux suppose 
 
9812
  ;; reset the memory (some boot loaders such as syslinux suppose
9689
9813
  ;; that the memory is set to zero)
9690
9814
  mov edi, #0x00040000
9691
9815
  mov ecx, #0x40000 / 4
9693
9817
  rep
9694
9818
    stosd
9695
9819
 
9696
 
  ;; reset the memory (some boot loaders such as syslinux suppose 
9697
 
  ;; that the memory is set to zero)
9698
 
  mov edi, #0x00040000
9699
 
  mov ecx, #0x40000 / 4
9700
 
  xor eax, eax
9701
 
  rep 
9702
 
    stosd
9703
 
 
9704
9820
  ;; return to 16 bit protected mode first
9705
9821
  db 0xea
9706
9822
  dd rombios32_10
9829
9945
  ret
9830
9946
 
9831
9947
 
9832
 
;; We need a copy of this string, but we are not actually a PnP BIOS, 
 
9948
;; We need a copy of this string, but we are not actually a PnP BIOS,
9833
9949
;; so make sure it is *not* aligned, so OSes will not see it if they scan.
9834
9950
.align 16
9835
9951
  db 0
9850
9966
  ;;   2         ROM length in 512-byte blocks
9851
9967
  ;;   3         ROM initialization entry point (FAR CALL)
9852
9968
 
9853
 
  mov  cx, #0xc000
9854
9969
rom_scan_loop:
 
9970
  push ax       ;; Save AX
9855
9971
  mov  ds, cx
9856
9972
  mov  ax, #0x0004 ;; start with increment of 4 (512-byte) blocks = 2k
9857
9973
  cmp [0], #0xAA55 ;; look for signature
9876
9992
  push cx       ;; Push seg
9877
9993
  push #0x0003  ;; Push offset
9878
9994
 
9879
 
  ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.  
 
9995
  ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
9880
9996
  ;; That should stop it grabbing INT 19h; we will use its BEV instead.
9881
9997
  mov  ax, #0xf000
9882
9998
  mov  es, ax
9883
 
  lea  di, pnp_string 
 
9999
  lea  di, pnp_string
9884
10000
 
9885
10001
  mov  bp, sp   ;; Call ROM init routine using seg:off on stack
9886
10002
  db   0xff     ;; call_far ss:[bp+0]
9890
10006
  add  sp, #2   ;; Pop offset value
9891
10007
  pop  cx       ;; Pop seg value (restore CX)
9892
10008
 
9893
 
  ;; Look at the ROM's PnP Expansion header.  Properly, we're supposed 
9894
 
  ;; to init all the ROMs and then go back and build an IPL table of 
 
10009
  ;; Look at the ROM's PnP Expansion header.  Properly, we're supposed
 
10010
  ;; to init all the ROMs and then go back and build an IPL table of
9895
10011
  ;; all the bootable devices, but we can get away with one pass.
9896
10012
  mov  ds, cx       ;; ROM base
9897
10013
  mov  bx, 0x001a   ;; 0x1A is the offset into ROM header that contains...
9899
10015
  cmp  ax, #0x5024  ;; we look for signature "$PnP"
9900
10016
  jne  no_bev
9901
10017
  mov  ax, 2[bx]
9902
 
  cmp  ax, #0x506e 
 
10018
  cmp  ax, #0x506e
9903
10019
  jne  no_bev
9904
10020
  mov  ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
9905
10021
  cmp  ax, #0x0000  ;; the Bootstrap Entry Vector, or zero if there is none.
9906
10022
  je   no_bev
9907
10023
 
9908
 
  ;; Found a device that thinks it can boot the system.  Record its BEV.
9909
 
  mov  bx, #IPL_SEG            ;; Go to the segment where the IPL table lives 
 
10024
  ;; Found a device that thinks it can boot the system.  Record its BEV and product name string.
 
10025
  mov  di, 0x10[bx]            ;; Pointer to the product name string or zero if none
 
10026
  mov  bx, #IPL_SEG            ;; Go to the segment where the IPL table lives
9910
10027
  mov  ds, bx
9911
10028
  mov  bx, IPL_COUNT_OFFSET    ;; Read the number of entries so far
9912
10029
  cmp  bx, #IPL_TABLE_ENTRIES
9913
10030
  je   no_bev                  ;; Get out if the table is full
9914
10031
  shl  bx, #0x4                ;; Turn count into offset (entries are 16 bytes)
9915
 
  mov  0[bx], #0x80            ;; This entry is a BEV device
 
10032
  mov  0[bx], #IPL_TYPE_BEV    ;; This entry is a BEV device
9916
10033
  mov  6[bx], cx               ;; Build a far pointer from the segment...
9917
10034
  mov  4[bx], ax               ;; and the offset
 
10035
  cmp  di, #0x0000
 
10036
  je   no_prod_str
 
10037
  mov  0xA[bx], cx             ;; Build a far pointer from the segment...
 
10038
  mov  8[bx], di               ;; and the offset
 
10039
no_prod_str:
9918
10040
  shr  bx, #0x4                ;; Turn the offset back into a count
9919
10041
  inc  bx                      ;; We have one more entry now
9920
10042
  mov  IPL_COUNT_OFFSET, bx    ;; Remember that.
9926
10048
  shl  ax, #5   ;; convert 512-bytes blocks to 16-byte increments
9927
10049
                ;; because the segment selector is shifted left 4 bits.
9928
10050
  add  cx, ax
9929
 
  cmp  cx, #0xe000
 
10051
  pop  ax       ;; Restore AX
 
10052
  cmp  cx, ax
9930
10053
  jbe  rom_scan_loop
9931
10054
 
9932
10055
  xor  ax, ax   ;; Restore DS back to 0000:
9948
10071
;- POST -
9949
10072
;--------
9950
10073
.org 0xe05b ; POST Entry Point
9951
 
bios_table_area_end:
9952
10074
post:
 
10075
  ;; enable cache
 
10076
  mov eax, cr0
 
10077
  and eax, #0x9fffffff
 
10078
  mov cr0, eax
9953
10079
 
9954
10080
  xor ax, ax
9955
10081
 
10039
10165
 
10040
10166
post_default_ints:
10041
10167
  mov  [bx], ax
10042
 
  inc  bx
10043
 
  inc  bx
 
10168
  add  bx, #2
10044
10169
  mov  [bx], dx
10045
 
  inc  bx
10046
 
  inc  bx
 
10170
  add  bx, #2
10047
10171
  loop post_default_ints
10048
10172
 
10049
10173
  ;; set vector 0x79 to zero
10212
10336
#endif
10213
10337
  out  0xa1, AL ;slave  pic: unmask IRQ 12, 13, 14
10214
10338
 
 
10339
  mov  cx, #0xc000  ;; init vga bios
 
10340
  mov  ax, #0xc780
 
10341
  call rom_scan
 
10342
 
 
10343
  call _print_bios_banner
 
10344
 
10215
10345
#if BX_ROMBIOS32
10216
10346
  call rombios32_init
10217
10347
#else
 
10348
#if BX_PCIBIOS
10218
10349
  call pcibios_init_iomem_bases
10219
10350
  call pcibios_init_irqs
 
10351
#endif //BX_PCIBIOS
10220
10352
#endif
10221
10353
 
10222
 
  call _init_boot_vectors
10223
 
 
10224
 
  call rom_scan
10225
 
 
10226
 
  call _print_bios_banner
10227
 
 
10228
10354
  ;;
10229
10355
  ;; Floppy setup
10230
10356
  ;;
10260
10386
  ;;
10261
10387
#endif // BX_ELTORITO_BOOT
10262
10388
 
 
10389
  call _init_boot_vectors
 
10390
 
 
10391
  mov  cx, #0xc800  ;; init option roms
 
10392
  mov  ax, #0xe000
 
10393
  call rom_scan
 
10394
 
10263
10395
  sti        ;; enable interrupts
10264
10396
  int  #0x19
10265
10397
 
10266
 
 
10267
10398
.org 0xe2c3 ; NMI Handler Entry Point
10268
10399
nmi:
10269
10400
  ;; FIXME the NMI handler should not panic
11000
11131
 
11001
11132
ASM_START
11002
11133
.org 0xcc00
 
11134
bios_table_area_end:
11003
11135
// bcc-generated data will be placed here
11004
11136
ASM_END