WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [Patch][RFC] Update rombios.c

To: xen-devel@xxxxxxxxxxxxxxxxxxx, Tim.Deegan@xxxxxxxxxxxxx, samuel.thibault@xxxxxxxxxx, Yu Ke <ke.yu@xxxxxxxxx>, Stefan Berger <stefanb@xxxxxxxxxx>, Ke Liping <liping.ke@xxxxxxxxx>, Juergen Keil <jk@xxxxxxxx>, Keir Fraser <keir.fraser@xxxxxxxxxx>, "Daniel P. Berrange" <berrange@xxxxxxxxxx>, Seiji Munetoh <seiji.munetoh@xxxxxxxxx>, Ben Guthro <bguthro@xxxxxxxxxxxxxx>, Steve Ofsthun <sofsthun@xxxxxxxxxxxxxxx>, Travis Betak <travis.betak@xxxxxxx>, Bruce Rogers <brogers@xxxxxxxxxx>
Subject: Re: [Xen-devel] [Patch][RFC] Update rombios.c
From: Akio Takebe <takebe_akio@xxxxxxxxxxxxxx>
Date: Thu, 18 Dec 2008 08:52:34 +0900
Cc:
Delivery-date: Wed, 17 Dec 2008 15:53:23 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <494911BB.8040506@xxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <494911BB.8040506@xxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.18 (X11/20081119)
Akio Takebe wrote:
> Hi, all
> 
> This patch update rombios to the latest Bochs's.
> I'd like to corabolate bochs community to enhance the guest bios.
> I'm not familiar around TCGBIOS.
> So could you review the patch?
> 
> I tested boot/shutdown, S3 suspend/resume with linux guest.
> Any comments are welcome :-)
This attached file is diffs from the latest rombios of bochs.
I hope it helps you at reviewing my patch.

Best Regards,

Akio Takebe
--- rombios.bochs.c     2008-12-18 08:44:57.000000000 +0900
+++ rombios.c   2008-12-17 23:33:37.000000000 +0900
@@ -26,6 +26,18 @@
 
 // ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
 
+#define uint8_t unsigned char
+#define uint16_t unsigned short
+#define uint32_t unsigned long
+#include "../hvmloader/config.h"
+
+#define HVMASSIST
+#undef HVMTEST
+
+// Xen full virtualization does not handle unaligned IO with page crossing.
+// Disable 32-bit PIO as a workaround.
+#undef NO_PIO32
+
 
 // ROM BIOS compatability entry points:
 // ===================================
@@ -147,6 +159,8 @@
 #define BX_USE_ATADRV    1
 #define BX_ELTORITO_BOOT 1
 
+#define BX_TCGBIOS       0   /* main switch for TCG BIOS ext. */
+
 #define BX_MAX_ATA_INTERFACES   4
 #define BX_MAX_ATA_DEVICES      (BX_MAX_ATA_INTERFACES*2)
 
@@ -170,18 +184,18 @@
 #define BASE_MEM_IN_K   (640 - EBDA_SIZE)
 
 /* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */
-#define IPL_SEG              0x9ff0
-#define IPL_TABLE_OFFSET     0x0000
+#define IPL_TABLE_OFFSET     0x0300  /* offset from EBDA */
 #define IPL_TABLE_ENTRIES    8
-#define IPL_COUNT_OFFSET     0x0080  /* u16: number of valid table entries */
-#define IPL_SEQUENCE_OFFSET  0x0082  /* u16: next boot device */
-#define IPL_BOOTFIRST_OFFSET 0x0084  /* u16: user selected device */
+#define IPL_COUNT_OFFSET     0x0380  /* u16: number of valid table entries */
+#define IPL_SEQUENCE_OFFSET  0x0382  /* u16: next boot device */
+#define IPL_BOOTFIRST_OFFSET 0x0384  /* u16: user selected device */
 #define IPL_SIZE             0xff
 #define IPL_TYPE_FLOPPY      0x01
 #define IPL_TYPE_HARDDISK    0x02
 #define IPL_TYPE_CDROM       0x03
 #define IPL_TYPE_BEV         0x80
 
+
   // Sanity Checks
 #if BX_USE_ATADRV && BX_CPU<3
 #    error The ATA/ATAPI Driver can only to be used with a 386+ cpu
@@ -710,14 +724,18 @@ typedef struct {
     } cdemu_t;
 #endif // BX_ELTORITO_BOOT
 
+#include "32bitgateway.h"
+
   // for access to EBDA area
   //     The EBDA structure should conform to
   //     http://www.frontiernet.net/~fys/rombios.htm document
   //     I made the ata and cdemu structs begin at 0x121 in the EBDA seg
   // EBDA must be at most 768 bytes; it lives at EBDA_SEG, and the boot
-  // device tables are at IPL_SEG
+  // device tables are at EBDA_SEG:IPL_TABLE_OFFSET
   typedef struct {
-    unsigned char filler1[0x3D];
+    unsigned char ebda_size;
+    unsigned char cmos_shutdown_status;
+    unsigned char filler1[0x3B];
 
     // FDPT - Can be splitted in data members if needed
     unsigned char fdpt0[0x10];
@@ -733,8 +751,10 @@ typedef struct {
     cdemu_t cdemu;
 #endif // BX_ELTORITO_BOOT
 
+    upcall_t upcall;
     } ebda_data_t;
 
+  #define EBDA_CMOS_SHUTDOWN_STATUS_OFFSET 1
   #define EbdaData ((ebda_data_t *) 0)
 
   // for access to the int13ext structure
@@ -863,6 +883,7 @@ static Bit16u         read_word();
 static void           write_byte();
 static void           write_word();
 static void           bios_printf();
+static void           copy_e820_table();
 
 static Bit8u          inhibit_mouse_int_and_events();
 static void           enable_mouse_int_and_events();
@@ -880,7 +901,7 @@ static void           int14_function();
 static void           int15_function();
 static void           int16_function();
 static void           int17_function();
-static void           int19_function();
+static void           int18_function();
 static void           int1a_function();
 static void           int70_function();
 static void           int74_function();
@@ -1382,6 +1403,53 @@ ASM_START
 ASM_END
 }
 
+#ifdef HVMASSIST
+void
+copy_e820_table()
+{
+  Bit8u nr_entries = read_byte(0x9000, 0x1e8);
+  Bit32u base_mem;
+  if (nr_entries > 32)
+       nr_entries = 32;
+  write_word(0xe000, 0x8, nr_entries);
+  memcpyb(0xe000, 0x10, 0x9000, 0x2d0, nr_entries * 0x14);
+  /* Report the proper base memory size at address 0x0413: otherwise
+   * non-e820 code will clobber things if BASE_MEM_IN_K is bigger than
+   * the first e820 entry.  Get the size by reading the second 64bit 
+   * field of the first e820 slot. */ 
+  base_mem = read_dword(0x9000, 0x2d0 + 8);
+  write_word(0x40, 0x13, base_mem >> 10);
+}
+
+void
+set_rom_write_access(action)
+  Bit16u action;
+{
+    Bit16u off = (Bit16u)&((struct bios_info *)0)->xen_pfiob;
+ASM_START
+    mov si,.set_rom_write_access.off[bp]
+    push ds
+    mov ax,#(ACPI_PHYSICAL_ADDRESS >> 4)
+    mov ds,ax
+    mov dx,[si]
+    pop ds
+    mov ax,.set_rom_write_access.action[bp]
+    out dx,al
+ASM_END
+}
+
+void enable_rom_write_access()
+{
+    set_rom_write_access(0);
+}
+
+void disable_rom_write_access()
+{
+    set_rom_write_access(PFFLAG_ROM_LOCK);
+}
+    
+#endif /* HVMASSIST */
+
 #if BX_DEBUG_SERIAL
 /* serial debug port*/
 #define BX_DEBUG_PORT 0x03f8
@@ -1460,6 +1528,9 @@ send(action, c)
   if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r');
   uart_tx_byte(BX_DEBUG_PORT, c);
 #endif
+#ifdef HVMASSIST
+  outb(0xE9, c);
+#endif
 #if BX_VIRTUAL_PORTS
   if (action & BIOS_PRINTF_DEBUG) outb(DEBUG_PORT, c);
   if (action & BIOS_PRINTF_INFO) outb(INFO_PORT, c);
@@ -1906,6 +1977,49 @@ keyboard_panic(status)
   BX_PANIC("Keyboard error:%u\n",status);
 }
 
+#define CMOS_SHUTDOWN_S3 0xFE
+//--------------------------------------------------------------------------
+// machine_reset
+//--------------------------------------------------------------------------
+  void
+machine_reset()
+{
+ASM_START
+;we must check whether CMOS_SHUTDOWN_S3 is set or not
+;if it is s3 resume, just jmp back to normal Post Entry
+;below port io will prevent s3 resume
+  mov al, #0x0f
+  out 0x70, al
+  in al, 0x71
+  cmp al, #0xFE
+  jz post
+ASM_END
+  /* Frob the keyboard reset line to reset the processor */
+  outb(0x64, 0x60); /* Map the flags register at data port (0x60) */
+  outb(0x60, 0x14); /* Set the flags to system|disable */
+  outb(0x64, 0xfe); /* Pulse output 0 (system reset) low */
+  BX_PANIC("Couldn't reset the machine\n");
+}
+
+//--------------------------------------------------------------------------
+// clobber_entry_point
+//    Because PV drivers in HVM guests detach some of the emulated devices, 
+//    it is not safe to do a soft reboot by just dropping to real mode and
+//    jumping at ffff:0000. -- the boot drives might have disappeared!
+//    This rather foul function overwrites(!) the BIOS entry point 
+//    to point at machine-reset, which will cause the Xen tools to
+//    rebuild the whole machine from scratch.
+//--------------------------------------------------------------------------
+  void 
+clobber_entry_point() 
+{
+    /* The instruction at the entry point is one byte (0xea) for the
+     * jump opcode, then two bytes of address, then two of segment. 
+     * Overwrite the address bytes.*/
+    write_word(0xffff, 0x0001, machine_reset); 
+}
+
+
 //--------------------------------------------------------------------------
 // shutdown_status_panic
 //   called when the shutdown statsu is not implemented, displays the status
@@ -1944,6 +2058,9 @@ print_bios_banner()
 #if BX_ROMBIOS32
   "rombios32 "
 #endif
+#if BX_TCGBIOS
+  "TCG-enabled"
+#endif
   "\n\n");
 }
 
@@ -1970,34 +2087,35 @@ init_boot_vectors()
   ipl_entry_t e;
   Bit16u count = 0;
   Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
 
   /* Clear out the IPL table. */
-  memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE);
+  memsetb(ebda_seg, IPL_TABLE_OFFSET, 0, IPL_SIZE);
 
   /* User selected device not set */
-  write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF);
+  write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, 0xFFFF);
 
   /* Floppy drive */
   e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; 
e.reserved = 0;
-  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
+  memcpyb(ebda_seg, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
   count++;
 
   /* First HDD */
   e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; 
e.reserved = 0;
-  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
+  memcpyb(ebda_seg, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
   count++;
 
 #if BX_ELTORITO_BOOT
   /* CDROM */
   e.type = IPL_TYPE_CDROM; e.flags = 0; e.vector = 0; e.description = 0; 
e.reserved = 0;
-  memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
+  memcpyb(ebda_seg, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e));
   count++;
 #endif
 
   /* Remember how many devices we have */
-  write_word(IPL_SEG, IPL_COUNT_OFFSET, count);
+  write_word(ebda_seg, IPL_COUNT_OFFSET, count);
   /* Not tried booting anything yet */
-  write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff);
+  write_word(ebda_seg, IPL_SEQUENCE_OFFSET, 0xffff);
 }
 
 static Bit8u
@@ -2006,11 +2124,12 @@ Bit16u i; ipl_entry_t *e;
 {
   Bit16u count;
   Bit16u ss = get_SS();
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
   /* Get the count of boot devices, and refuse to overrun the array */
-  count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
+  count = read_word(ebda_seg, IPL_COUNT_OFFSET);
   if (i >= count) return 0;
   /* OK to read this device */
-  memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
+  memcpyb(ss, e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e));
   return 1;
 }
 
@@ -2025,11 +2144,12 @@ interactive_bootkey()
   Bit8u i;
   Bit16u ss = get_SS();
   Bit16u valid_choice = 0;
+  Bit16u ebda_seg = read_word(0x0040, 0x000E);
 
   while (check_for_keystroke())
     get_keystroke();
 
-  printf("Press F12 for boot menu.\n\n");
+  printf("\nPress F12 for boot menu.\n\n");
 
   delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */
   if (check_for_keystroke())
@@ -2042,10 +2162,10 @@ interactive_bootkey()
 
       printf("Select boot device:\n\n");
 
-      count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
+      count = read_word(ebda_seg, IPL_COUNT_OFFSET);
       for (i = 0; i < count; i++)
       {
-        memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof 
(e));
+        memcpyb(ss, &e, ebda_seg, IPL_TABLE_OFFSET + i * sizeof (e), sizeof 
(e));
         printf("%d. ", i+1);
         switch(e.type)
         {
@@ -2079,7 +2199,7 @@ interactive_bootkey()
           valid_choice = 1;
           scan_code -= 1;
           /* Set user selected device */
-          write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code);
+          write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, scan_code);
         }
       }
     printf("\n");
@@ -2126,7 +2246,7 @@ print_boot_failure(type, reason)
 {
   if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n");
 
-  printf("Boot failed");
+  printf("Boot from %s failed", drivetypes[type]);
   if (type < 4) {
     /* Report the reason too */
     if (reason==0)
@@ -2210,10 +2330,14 @@ s3_resume()
     Bit8u s3_resume_flag;
 
     s3_resume_flag = read_byte(0x40, 0xb0);
+#ifdef HVMASSIST
+    s3_wakeup_vector = get_s3_waking_vector();
+#else
     s3_wakeup_vector = read_dword(0x40, 0xb2);
+#endif
 
     BX_INFO("S3 resume called %x 0x%lx\n", s3_resume_flag, s3_wakeup_vector);
-    if (s3_resume_flag != 0xFE || !s3_wakeup_vector)
+    if (s3_resume_flag != CMOS_SHUTDOWN_S3 || !s3_wakeup_vector)
            return 0;
 
     write_byte(0x40, 0xb0, 0);
@@ -2572,6 +2696,9 @@ void ata_detect( )
       Bit16u cylinders, heads, spt, blksize;
       Bit8u  translation, removable, mode;
 
+      // default mode to PIO16
+      mode = ATA_MODE_PIO16;
+
       //Temporary values to do the transfer
       write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD);
       write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16);
@@ -2580,7 +2707,9 @@ void ata_detect( )
         BX_PANIC("ata-detect: Failed to detect ATA device\n");
 
       removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0;
+#ifndef        NO_PIO32
       mode      = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : 
ATA_MODE_PIO16;
+#endif
       blksize   = read_word(get_SS(),buffer+10);
 
       cylinders = read_word(get_SS(),buffer+(1*2)); // word 1
@@ -2677,6 +2806,9 @@ void ata_detect( )
       Bit8u  type, removable, mode;
       Bit16u blksize;
 
+      // default mode to PIO16
+      mode = ATA_MODE_PIO16;
+
       //Temporary values to do the transfer
       
write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_CDROM);
       write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16);
@@ -2686,7 +2818,9 @@ void ata_detect( )
 
       type      = read_byte(get_SS(),buffer+1) & 0x1f;
       removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0;
+#ifndef        NO_PIO32
       mode      = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : 
ATA_MODE_PIO16;
+#endif
       blksize   = 2048;
 
       write_byte(ebda_seg,&EbdaData->ata.devices[device].device, type);
@@ -3651,6 +3785,13 @@ cdrom_boot()
   // Initial/Default Entry
   if(buffer[0x20]!=0x88)return 11; // Bootable
 
+#if BX_TCGBIOS
+  /* specs: 8.2.3 step 5 and 8.2.5.6, measure El Torito boot catalog */
+  /* measure 2048 bytes (one sector) */
+  tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L); /* bootcd = 1 */
+  tcpa_ipl((Bit32u)2L,(Bit32u)get_SS(),(Bit32u)buffer,(Bit32u)2048L);
+#endif
+
   write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]);
   if(buffer[0x21]==0){
     // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0.
@@ -3689,6 +3830,12 @@ cdrom_boot()
   if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, 
ATA_DATA_IN, boot_segment,0)) != 0)
     return 12;
 
+#if BX_TCGBIOS
+  /* specs: 8.2.3 step 4 and 8.2.5.6, measure El Torito boot image */
+  /* measure 1st 512 bytes  */
+  tcpa_ipl((Bit32u)1L,(Bit32u)boot_segment,(Bit32u)0L,(Bit32u)512L);
+#endif
+
   // Remember the media type
   switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
     case 0x01:  // 1.2M floppy
@@ -4487,11 +4634,9 @@ ASM_START
 
       ;; Get the count in eax
       mov  bx, sp
-      SEG SS
-        mov  ax, _int15_function32.CX [bx]
+      mov  ax, _int15_function32.CX [bx]
       shl  eax, #16
-      SEG SS
-        mov  ax, _int15_function32.DX [bx]
+      mov  ax, _int15_function32.DX [bx]
 
       ;; convert to numbers of 15usec ticks
       mov ebx, #15
@@ -4522,6 +4667,97 @@ ASM_END
     case 0xe8:
         switch(regs.u.r8.al)
         {
+#ifdef HVMASSIST
+       case 0x20: {
+            Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
+
+            if (regs.u.r32.edx != 0x534D4150) /* SMAP */
+                goto int15_unimplemented;
+
+            if ((regs.u.r16.bx / 0x14) * 0x14 == 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);
+                regs.u.r32.ebx += 0x14;
+                if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
+                    regs.u.r32.ebx = 0;
+            } else if (regs.u.r16.bx == 1) {
+                Bit32u base, type;
+                Bit16u off;
+                for (off = 0; off < e820_table_size; off += 0x14) {
+                    base = read_dword(0xe000, 0x10 + off);
+                    type = read_dword(0xe000, 0x20 + off);
+                    if ((base >= 0x100000) && (type == 1))
+                        break;
+                }
+                if (off == e820_table_size) {
+                    SET_CF();
+                    break;
+                }
+                memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14);
+                regs.u.r32.ebx = 0;
+            } else { /* AX=E820, DX=534D4150, BX unrecognized */
+                goto int15_unimplemented;
+            }
+
+            regs.u.r32.eax = 0x534D4150;
+            regs.u.r32.ecx = 0x14;
+            CLEAR_CF();
+            break;
+        }
+
+        case 0x01: {
+            Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14;
+            Bit32u base, type, size;
+
+            // do we have any reason to fail here ?
+            CLEAR_CF();
+
+            // Get the amount of extended memory (above 1M)
+            regs.u.r8.cl = inb_cmos(0x30);
+            regs.u.r8.ch = inb_cmos(0x31);
+
+            // limit to 15M
+            if (regs.u.r16.cx > (15*1024))
+                regs.u.r16.cx = 15*1024;
+
+            // Find first RAM E820 entry >= 1MB.
+            for (off = 0; off < e820_table_size; off += 0x14) {
+                base = read_dword(0xe000, 0x10 + off);
+                type = read_dword(0xe000, 0x20 + off);
+                if ((base >= 0x100000) && (type == 1))
+                    break;
+            }
+
+            // If there is RAM above 16MB, return amount in 64kB chunks.
+            regs.u.r16.dx = 0;
+            if (off != e820_table_size) {
+                size = base + read_dword(0xe000, 0x18 + off);
+                if (size > 0x1000000) {
+                    size -= 0x1000000;
+                    regs.u.r16.dx = (Bit16u)(size >> 16);
+                }
+            }
+
+            // Set configured memory equal to extended memory
+            regs.u.r16.ax = regs.u.r16.cx;
+            regs.u.r16.bx = regs.u.r16.dx;
+            break;
+        }
+        default:  /* AH=0xE8?? but not implemented */
+            goto int15_unimplemented;
+        }
+        break;
+    int15_unimplemented:
+       // fall into the default
+    default:
+      BX_INFO("*** int 15h function AX=%04x, BX=%04x not yet supported!\n",
+        (unsigned) regs.u.r16.ax, (unsigned) regs.u.r16.bx);
+      SET_CF();
+      regs.u.r8.ah = UNSUPPORTED_FUNCTION;
+      break;
+    }
+#else
          case 0x20: // coded by osmaker aka K.J.
             if(regs.u.r32.edx == 0x534D4150)
             {
@@ -4661,6 +4897,7 @@ ASM_END
       regs.u.r8.ah = UNSUPPORTED_FUNCTION;
       break;
     }
+#endif /* HVMASSIST */
 }
 
   void
@@ -5071,6 +5308,10 @@ int09_function(DI, SI, BP, SP, BX, DX, C
       write_byte(0x0040, 0x18, mf2_flags);
       break;
 
+    case 0x53: /* Del */
+        if ((shift_flags & 0x0c) == 0x0c) /* Ctrl + Alt */
+            machine_reset();
+        /* Fall through */
     default:
       if (scancode & 0x80) {
         break; /* toss key releases ... */
@@ -7971,7 +8212,7 @@ int17_function(regs, ds, iret_addr)
 }
 
 void
-int19_function(seq_nr)
+int18_function(seq_nr)
 Bit16u seq_nr;
 {
   Bit16u ebda_seg=read_word(0x0040,0x000E);
@@ -8011,13 +8252,13 @@ Bit16u seq_nr;
   bootdev &= 0xf;
 
   /* Read user selected device */
-  bootfirst = read_word(IPL_SEG, IPL_BOOTFIRST_OFFSET);
+  bootfirst = read_word(ebda_seg, IPL_BOOTFIRST_OFFSET);
   if (bootfirst != 0xFFFF) {
     bootdev = bootfirst;
     /* User selected device not set */
-    write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF);
+    write_word(ebda_seg, IPL_BOOTFIRST_OFFSET, 0xFFFF);
     /* Reset boot sequence */
-    write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xFFFF);
+    write_word(ebda_seg, IPL_SEQUENCE_OFFSET, 0xFFFF);
   } else if (bootdev == 0) BX_PANIC("No bootable device.\n");
 
   /* Translate from CMOS runes to an IPL table offset by subtracting 1 */
@@ -8057,8 +8298,8 @@ ASM_START
     push cx
     push dx
 
-    mov  dl, _int19_function.bootdrv + 2[bp]
-    mov  ax, _int19_function.bootseg + 2[bp]
+    mov  dl, _int18_function.bootdrv + 2[bp]
+    mov  ax, _int18_function.bootseg + 2[bp]
     mov  es, ax         ;; segment
     xor  bx, bx         ;; offset
     mov  ah, #0x02      ;; function 2, read diskette sector
@@ -8069,7 +8310,7 @@ ASM_START
     int  #0x13          ;; read sector
     jnc  int19_load_done
     mov  ax, #0x0001
-    mov  _int19_function.status + 2[bp], ax
+    mov  _int18_function.status + 2[bp], ax
 
 int19_load_done:
     pop  dx
@@ -8093,6 +8334,11 @@ ASM_END
       }
     }
 
+#if BX_TCGBIOS
+    tcpa_add_bootdevice((Bit32u)0L, (Bit32u)bootdrv);
+    tcpa_ipl((Bit32u)0L,(Bit32u)bootseg,(Bit32u)0L,(Bit32u)512L); /* specs: 
8.2.3 steps 4 and 5 */
+#endif
+
     /* Canonicalize bootseg:bootip */
     bootip = (bootseg & 0x0fff) << 4;
     bootseg &= 0xf000;
@@ -8111,7 +8357,10 @@ ASM_END
 
     bootdrv = (Bit8u)(status>>8);
     bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
-    bootip = 0;
+
+    /* Canonicalize bootseg:bootip */
+    bootip = (bootseg & 0x0fff) << 4;
+    bootseg &= 0xf000;
     break;
 #endif
 
@@ -8129,18 +8378,18 @@ ASM_END
   /* Jump to the boot vector */
 ASM_START
     mov  bp, sp
-    push cs
-    push #int18_handler
+//    push cs
+//    push #int18_handler
     ;; Build an iret stack frame that will take us to the boot vector.
     ;; iret pops ip, then cs, then flags, so push them in the opposite order.
     pushf
-    mov  ax, _int19_function.bootseg + 0[bp]
+    mov  ax, _int18_function.bootseg + 0[bp]
     push ax
-    mov  ax, _int19_function.bootip + 0[bp]
+    mov  ax, _int18_function.bootip + 0[bp]
     push ax
     ;; Set the magic number in ax and the boot drive in dl.
     mov  ax, #0xaa55
-    mov  dl, _int19_function.bootdrv + 0[bp]
+    mov  dl, _int18_function.bootdrv + 0[bp]
     ;; Zero some of the other registers.
     xor  bx, bx
     mov  ds, bx
@@ -8625,51 +8874,47 @@ int18_handler: ;; Boot Failure recovery:
   xor  ax, ax
   mov  ss, ax
 
-  ;; Get the boot sequence number out of the IPL memory
-  mov  bx, #IPL_SEG
+  ;; The first time we do this it will have been set to -1 so 
+  ;; we will start from device 0.
+  mov  ds, ax
+  mov  bx, word ptr [0x40E]       ;; EBDA segment
   mov  ds, bx                     ;; Set segment
   mov  bx, IPL_SEQUENCE_OFFSET    ;; BX is now the sequence number
   inc  bx                         ;; ++
   mov  IPL_SEQUENCE_OFFSET, bx    ;; Write it back
   mov  ds, ax                     ;; and reset the segment to zero.
 
-  ;; Carry on in the INT 19h handler, using the new sequence number
+  ;; Call the C code for the next boot device
   push bx
 
-  jmp  int19_next_boot
+  call _int18_function
+
+  ;; Boot failed: invoke the boot recovery function...
+  int  #0x18
 
 ;----------
 ;- INT19h -
 ;----------
 int19_relocated: ;; Boot function, relocated
 
-  ;; int19 was beginning to be really complex, so now it
-  ;; just calls a C function that does the work
-
-  push bp
-  mov  bp, sp
+  ;;
+  ;; *** Warning: INT 19h resets the whole machine *** 
+  ;;
+  ;; Because PV drivers in HVM guests detach some of the emulated devices, 
+  ;; it is not safe to do a soft reboot by just dropping to real mode and
+  ;; invoking INT 19h -- the boot drives might have disappeared!
+  ;; If the user asks for a soft reboot, the only thing we can do is 
+  ;; reset the whole machine.  When it comes back up, the normal BIOS 
+  ;; boot sequence will start, which is more or less the required behaviour.
+  ;; 
+  ;; Reset SP and SS
 
-  ;; Reset SS and SP
   mov  ax, #0xfffe
   mov  sp, ax
   xor  ax, ax
   mov  ss, ax
 
-  ;; Start from the first boot device (0, in AX)
-  mov  bx, #IPL_SEG
-  mov  ds, bx                     ;; Set segment to write to the IPL memory
-  mov  IPL_SEQUENCE_OFFSET, ax    ;; Save the sequence number
-  mov  ds, ax                     ;; and reset the segment.
-
-  push ax
-
-int19_next_boot:
-
-  ;; Call the C code for the next boot device
-  call _int19_function
-
-  ;; Boot failed: invoke the boot recovery function
-  int  #0x18
+  call _machine_reset
 
 ;----------
 ;- INT1Ch -
@@ -8779,8 +9024,8 @@ hard_drive_post:
   SET_INT_VECTOR(0x76, #0xF000, #int76_handler)
   ;; INT 41h: hard disk 0 configuration pointer
   ;; INT 46h: hard disk 1 configuration pointer
-  SET_INT_VECTOR(0x41, #EBDA_SEG, #0x003D)
-  SET_INT_VECTOR(0x46, #EBDA_SEG, #0x004D)
+  SET_INT_VECTOR(0x41, word ptr [0x40E], #0x003D) /* EBDA:003D */
+  SET_INT_VECTOR(0x46, word ptr [0x40E], #0x004D) /* EBDA:004D */
 
   ;; move disk geometry data from CMOS to EBDA disk parameter table(s)
   mov  al, #0x12
@@ -8809,7 +9054,9 @@ post_d0_type47:
   ;; 22    landing zone high        D
   ;; 23    sectors/track            E
 
-  mov  ax, #EBDA_SEG
+  xor  ax, ax
+  mov  ds, ax
+  mov  ax, word ptr [0x40E] ;; EBDA segment
   mov  ds, ax
 
   ;;; Filling EBDA table for hard disk 0.
@@ -8955,7 +9202,9 @@ post_d1_type47:
   ;; 0x2b    landing zone high        D
   ;; 0x2c    sectors/track            E
 ;;; Fill EBDA table for hard disk 1.
-  mov  ax, #EBDA_SEG
+  xor  ax, ax
+  mov  ds, ax
+  mov  ax, word ptr [0x40E] ;; EBDA segment
   mov  ds, ax
   mov  al, #0x28
   out  #0x70, al
@@ -9255,6 +9504,10 @@ use16 386
 
 #endif
 
+ASM_END
+#include "32bitgateway.c"
+ASM_START
+
 ;--------------------
 #if BX_PCIBIOS
 use32 386
@@ -9696,79 +9949,79 @@ pci_routing_table_structure_start:
   ;; first slot entry PCI-to-ISA (embedded)
   db 0 ;; pci bus number
   db 0x08 ;; pci device number (bit 7-3)
-  db 0x60 ;; link value INTA#: pointer into PCI2ISA config space
-  dw 0xdef8 ;; IRQ bitmap INTA#
-  db 0x61 ;; link value INTB#
-  dw 0xdef8 ;; IRQ bitmap INTB#
-  db 0x62 ;; link value INTC#
-  dw 0xdef8 ;; IRQ bitmap INTC#
-  db 0x63 ;; link value INTD#
-  dw 0xdef8 ;; IRQ bitmap INTD#
-  db 0 ;; physical slot (0 = embedded)
-  db 0 ;; reserved
-  ;; second slot entry: 1st PCI slot
-  db 0 ;; pci bus number
-  db 0x10 ;; pci device number (bit 7-3)
-  db 0x61 ;; link value INTA#
-  dw 0xdef8 ;; IRQ bitmap INTA#
+  db 0x61 ;; link value INTA#: pointer into PCI2ISA config space
+  dw 0x0c20 ;; IRQ bitmap INTA#
   db 0x62 ;; link value INTB#
-  dw 0xdef8 ;; IRQ bitmap INTB#
+  dw 0x0c20 ;; IRQ bitmap INTB#
   db 0x63 ;; link value INTC#
-  dw 0xdef8 ;; IRQ bitmap INTC#
+  dw 0x0c20 ;; IRQ bitmap INTC#
   db 0x60 ;; link value INTD#
-  dw 0xdef8 ;; IRQ bitmap INTD#
-  db 1 ;; physical slot (0 = embedded)
+  dw 0x0c20 ;; IRQ bitmap INTD#
+  db 0 ;; physical slot (0 = embedded)
   db 0 ;; reserved
-  ;; third slot entry: 2nd PCI slot
+  ;; second slot entry: 1st PCI slot
   db 0 ;; pci bus number
-  db 0x18 ;; pci device number (bit 7-3)
+  db 0x10 ;; pci device number (bit 7-3)
   db 0x62 ;; link value INTA#
-  dw 0xdef8 ;; IRQ bitmap INTA#
+  dw 0x0c20 ;; IRQ bitmap INTA#
   db 0x63 ;; link value INTB#
-  dw 0xdef8 ;; IRQ bitmap INTB#
+  dw 0x0c20 ;; IRQ bitmap INTB#
   db 0x60 ;; link value INTC#
-  dw 0xdef8 ;; IRQ bitmap INTC#
+  dw 0x0c20 ;; IRQ bitmap INTC#
   db 0x61 ;; link value INTD#
-  dw 0xdef8 ;; IRQ bitmap INTD#
-  db 2 ;; physical slot (0 = embedded)
+  dw 0x0c20 ;; IRQ bitmap INTD#
+  db 1 ;; physical slot (0 = embedded)
   db 0 ;; reserved
-  ;; 4th slot entry: 3rd PCI slot
+  ;; third slot entry: 2nd PCI slot
   db 0 ;; pci bus number
-  db 0x20 ;; pci device number (bit 7-3)
+  db 0x18 ;; pci device number (bit 7-3)
   db 0x63 ;; link value INTA#
-  dw 0xdef8 ;; IRQ bitmap INTA#
+  dw 0x0c20 ;; IRQ bitmap INTA#
   db 0x60 ;; link value INTB#
-  dw 0xdef8 ;; IRQ bitmap INTB#
+  dw 0x0c20 ;; IRQ bitmap INTB#
   db 0x61 ;; link value INTC#
-  dw 0xdef8 ;; IRQ bitmap INTC#
+  dw 0x0c20 ;; IRQ bitmap INTC#
   db 0x62 ;; link value INTD#
-  dw 0xdef8 ;; IRQ bitmap INTD#
-  db 3 ;; physical slot (0 = embedded)
+  dw 0x0c20 ;; IRQ bitmap INTD#
+  db 2 ;; physical slot (0 = embedded)
   db 0 ;; reserved
-  ;; 5th slot entry: 4rd PCI slot
+  ;; 4th slot entry: 3rd PCI slot
   db 0 ;; pci bus number
-  db 0x28 ;; pci device number (bit 7-3)
+  db 0x20 ;; pci device number (bit 7-3)
   db 0x60 ;; link value INTA#
-  dw 0xdef8 ;; IRQ bitmap INTA#
+  dw 0x0c20 ;; IRQ bitmap INTA#
   db 0x61 ;; link value INTB#
-  dw 0xdef8 ;; IRQ bitmap INTB#
+  dw 0x0c20 ;; IRQ bitmap INTB#
   db 0x62 ;; link value INTC#
-  dw 0xdef8 ;; IRQ bitmap INTC#
+  dw 0x0c20 ;; IRQ bitmap INTC#
   db 0x63 ;; link value INTD#
-  dw 0xdef8 ;; IRQ bitmap INTD#
-  db 4 ;; physical slot (0 = embedded)
+  dw 0x0c20 ;; IRQ bitmap INTD#
+  db 3 ;; physical slot (0 = embedded)
   db 0 ;; reserved
-  ;; 6th slot entry: 5rd PCI slot
+  ;; 5th slot entry: 4rd PCI slot
   db 0 ;; pci bus number
-  db 0x30 ;; pci device number (bit 7-3)
+  db 0x28 ;; pci device number (bit 7-3)
   db 0x61 ;; link value INTA#
-  dw 0xdef8 ;; IRQ bitmap INTA#
+  dw 0x0c20 ;; IRQ bitmap INTA#
   db 0x62 ;; link value INTB#
-  dw 0xdef8 ;; IRQ bitmap INTB#
+  dw 0x0c20 ;; IRQ bitmap INTB#
   db 0x63 ;; link value INTC#
-  dw 0xdef8 ;; IRQ bitmap INTC#
+  dw 0x0c20 ;; IRQ bitmap INTC#
   db 0x60 ;; link value INTD#
-  dw 0xdef8 ;; IRQ bitmap INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
+  db 4 ;; physical slot (0 = embedded)
+  db 0 ;; reserved
+  ;; 6th slot entry: 5rd PCI slot
+  db 0 ;; pci bus number
+  db 0x30 ;; pci device number (bit 7-3)
+  db 0x62 ;; link value INTA#
+  dw 0x0c20 ;; IRQ bitmap INTA#
+  db 0x63 ;; link value INTB#
+  dw 0x0c20 ;; IRQ bitmap INTB#
+  db 0x60 ;; link value INTC#
+  dw 0x0c20 ;; IRQ bitmap INTC#
+  db 0x61 ;; link value INTD#
+  dw 0x0c20 ;; IRQ bitmap INTD#
   db 5 ;; physical slot (0 = embedded)
   db 0 ;; reserved
 pci_routing_table_structure_end:
@@ -10185,7 +10438,6 @@ checksum_loop:
 pnp_string:
   .ascii "$PnP"
 
-
 rom_scan:
   ;; Scan for existence of valid expansion ROMS.
   ;;   Video ROM:   from 0xC0000..0xC7FFF in 2k increments
@@ -10199,6 +10451,10 @@ rom_scan:
   ;;   2         ROM length in 512-byte blocks
   ;;   3         ROM initialization entry point (FAR CALL)
 
+#if BX_TCGBIOS
+  call _tcpa_start_option_rom_scan    /* specs: 3.2.3.3 + 10.4.3 */
+#endif
+
 rom_scan_loop:
   push ax       ;; Save AX
   mov  ds, cx
@@ -10219,18 +10475,49 @@ block_count_rounded:
 
   xor  bx, bx   ;; Restore DS back to 0000:
   mov  ds, bx
+#if BX_TCGBIOS
+  push ax
+  push ds
+  push ecx
+  xor ax, ax
+  mov ds, ax
+  and ecx, #0xffff
+  push ecx       ;; segment where option rom is located at
+  call _tcpa_option_rom                   /* specs: 3.2.3.3 */
+  add sp, #4    ;; pop segment
+  pop ecx      ;; original ecx
+  pop ds
+  pop ax
+#endif
   push ax       ;; Save AX
   push di       ;; Save DI
   ;; Push addr of ROM entry point
   push cx       ;; Push seg
   push #0x0003  ;; Push offset
 
+  ;; Get the BDF into ax before invoking the option ROM
+  mov  bl, [2]
+  mov  al, bl
+  shr  al, #7
+  cmp  al, #1
+  jne  fetch_bdf
+  mov  ax, ds ;; Increment the DS since rom size larger than an segment
+  add  ax, #0x1000
+  mov  ds, ax
+fetch_bdf:
+  shl  bx, #9
+  xor  ax, ax
+  mov  al, [bx]
+
   ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
   ;; That should stop it grabbing INT 19h; we will use its BEV instead.
-  mov  ax, #0xf000
-  mov  es, ax
+  mov  bx, #0xf000
+  mov  es, bx
   lea  di, pnp_string
 
+  xor  bx, bx   ;; Restore DS back to 0000:
+  mov  ds, bx
+
   mov  bp, sp   ;; Call ROM init routine using seg:off on stack
   db   0xff     ;; call_far ss:[bp+0]
   db   0x5e
@@ -10250,21 +10537,47 @@ block_count_rounded:
   mov  ax, 2[bx]
   cmp  ax, #0x506e
   jne  no_bev
+
+  mov  ax, 0x16[bx] ;; 0x16 is the offset of Boot Connection Vector
+  cmp  ax, #0x0000
+  je   no_bcv
+
+  ;; Option ROM has BCV. Run it now.
+  push cx       ;; Push seg
+  push ax       ;; Push offset
+
+  ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
+  mov  bx, #0xf000
+  mov  es, bx
+  lea  di, pnp_string
+  /* jump to BCV function entry pointer */
+  mov  bp, sp   ;; Call ROM BCV routine using seg:off on stack
+  db   0xff     ;; call_far ss:[bp+0]
+  db   0x5e
+  db   0
+  cli           ;; In case expansion ROM BIOS turns IF on
+  add  sp, #2   ;; Pop offset value
+  pop  cx       ;; Pop seg value (restore CX)
+  jmp   no_bev
+
+no_bcv:
   mov  ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of...
   cmp  ax, #0x0000  ;; the Bootstrap Entry Vector, or zero if there is none.
   je   no_bev
 
   ;; Found a device that thinks it can boot the system.  Record its BEV and 
product name string.
   mov  di, 0x10[bx]            ;; Pointer to the product name string or zero 
if none
-  mov  bx, #IPL_SEG            ;; Go to the segment where the IPL table lives
+  xor  bx, bx
   mov  ds, bx
+  mov  bx, word ptr [0x40E]    ;; EBDA segment
+  mov  ds, bx                  ;; Go to the segment where the IPL table lives
   mov  bx, IPL_COUNT_OFFSET    ;; Read the number of entries so far
   cmp  bx, #IPL_TABLE_ENTRIES
   je   no_bev                  ;; Get out if the table is full
   shl  bx, #0x4                ;; Turn count into offset (entries are 16 bytes)
-  mov  0[bx], #IPL_TYPE_BEV    ;; This entry is a BEV device
-  mov  6[bx], cx               ;; Build a far pointer from the segment...
-  mov  4[bx], ax               ;; and the offset
+  mov  IPL_TABLE_OFFSET+0[bx], #IPL_TYPE_BEV ;; This entry is a BEV device
+  mov  IPL_TABLE_OFFSET+6[bx], cx            ;; Build a far pointer from the 
segment...
+  mov  IPL_TABLE_OFFSET+4[bx], ax            ;; and the offset
   cmp  di, #0x0000
   je   no_prod_str
   mov  0xA[bx], cx             ;; Build a far pointer from the segment...
@@ -10289,6 +10602,64 @@ rom_scan_increment:
   mov  ds, ax
   ret
 
+#ifdef HVMASSIST
+
+; Copy the SMBIOS entry point from where hvmloader left it.
+; The entry point must be somewhere in 0xf0000-0xfffff on a 16-byte boundary,
+; but the tables themselves can be elsewhere.
+smbios_init:
+  push ax
+  push cx
+  push es
+  push ds
+  push di
+  push si
+
+  mov cx, #0x001f ; 0x1f bytes to copy
+  mov ax, #0xf000
+  mov es, ax      ; destination segment is 0xf0000
+  mov di, #smbios_entry_point ; destination offset
+  mov ax, #(SMBIOS_PHYSICAL_ADDRESS>>4)
+  mov ds, ax
+  mov si, #(SMBIOS_PHYSICAL_ADDRESS&15)
+  cld
+  rep
+    movsb
+
+  pop si
+  pop di
+  pop ds
+  pop es
+  pop cx
+  pop ax
+
+  ret
+
+#endif
+
+#if BX_TCGBIOS
+; The section between the POST entry and the NMI entry is filling up
+; and causes crashes if this code was directly there
+tcpa_post_part1:
+  call _tcpa_acpi_init
+
+  push dword #0
+  call _tcpa_initialize_tpm
+  add sp, #4
+
+  call _tcpa_do_measure_POSTs
+  call _tcpa_wake_event     /* specs: 3.2.3.7 */
+  ret
+
+tcpa_post_part2:
+  call _tcpa_calling_int19h          /* specs: 8.2.3 step 1 */
+  call _tcpa_add_event_separators    /* specs: 8.2.3 step 2 */
+  /* we do not call int 19h handler but keep following eventlog */
+  call _tcpa_returned_int19h         /* specs: 8.2.3 step 3/7 */
+  ret
+#endif
+
+
 post_init_pic:
   mov al, #0x11 ; send initialisation commands
   out 0x20, al
@@ -10483,9 +10854,16 @@ post_default_ints:
   ;; int 1C already points at dummy_iret_handler (above)
   mov al, #0x34 ; timer0: binary count, 16bit count, mode 2
   out 0x43, al
+#ifdef HVMASSIST
+  mov al, #0x0b ; #0xe90b = 20 Hz (temporary, until we fix xen/vmx support)
+  out 0x40, al ; lsb
+  mov al, #0xe9
+  out 0x40, al ; msb
+#else
   mov al, #0x00 ; maximum count of 0000H = 18.2Hz
   out 0x40, al
   out 0x40, al
+#endif
 
   ;; Keyboard
   SET_INT_VECTOR(0x09, #0xF000, #int09_handler)
@@ -10527,6 +10905,9 @@ post_default_ints:
   in   al, 0x71
   mov  0x0410, ax
 
+#if BX_TCGBIOS
+  call tcpa_post_part1
+#endif
 
   ;; Parallel setup
   SET_INT_VECTOR(0x0F, #0xF000, #dummy_iret_handler)
@@ -10626,6 +11007,14 @@ post_default_ints:
   ;;
 #endif // BX_ELTORITO_BOOT
 
+#ifdef HVMASSIST
+  call _enable_rom_write_access
+  call _clobber_entry_point
+  call _copy_e820_table
+  call smbios_init
+  call _disable_rom_write_access
+#endif
+
   call _init_boot_vectors
 
   mov  cx, #0xc800  ;; init option roms
@@ -10636,8 +11025,14 @@ post_default_ints:
   call _interactive_bootkey
 #endif // BX_ELTORITO_BOOT
 
+#if BX_TCGBIOS
+  call tcpa_post_part2
+#endif
+
   sti        ;; enable interrupts
-  int  #0x19
+  ;; Start the boot sequence.   See the comments in int19_relocated 
+  ;; for why we use INT 18h instead of INT 19h here.
+  int  #0x18
 
 .org 0xe2c3 ; NMI Handler Entry Point
 nmi:
@@ -11118,6 +11513,21 @@ db 0x00    ;; base  23:16
 ;----------
 .org 0xfe6e ; INT 1Ah Time-of-day Service Entry Point
 int1a_handler:
+#if BX_TCGBIOS
+  cmp  ah, #0xbb
+  jne  no_tcg
+  pushf
+  push ds
+  push es
+  pushad
+  call _int1a_function32
+  popad
+  pop es
+  pop ds
+  popf
+  iret
+no_tcg:
+#endif
 #if BX_PCIBIOS
   cmp  ah, #0xb1
   jne  int1a_normal
@@ -11224,8 +11634,17 @@ dummy_iret_handler:
   HALT(__LINE__)
   iret
 
+#ifdef HVMTEST
+.org 0xffe0
+  jmp 0xf000:post;
+#endif
+
 .org 0xfff0 ; Power-up Entry Point
-  jmp 0xf000:post
+#ifdef HVMTEST
+  jmp 0xd000:0x0003;
+#else
+   jmp 0xf000:post
+#endif
 
 .org 0xfff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY
 .ascii BIOS_BUILD_DATE
@@ -11373,8 +11792,53 @@ static Bit8u vgafont8[128*8]=
  0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
 };
 
+#ifdef HVMASSIST
 ASM_START
+
+// space for addresses in 32bit BIOS area; currently 256/4 entries
+// are allocated
+.org 0xcb00
+jmptable:
+db 0x5F, 0x5F, 0x5F, 0x4A, 0x4D, 0x50, 0x54 ;; ___JMPT
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;;  64 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 128 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 192 bytes
+
+//
+// MP Tables
+// just carve out some blank space for HVMLOADER to write the MP tables to
+//
+// NOTE: There should be enough space for a 32 processor entry MP table
+//
 .org 0xcc00
+db 0x5F, 0x5F, 0x5F, 0x48, 0x56, 0x4D, 0x4D, 0x50 ;; ___HVMMP
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;;  64 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 128 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 192 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 256 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 320 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 384 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 448 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 512 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 576 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 640 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 704 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 768 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 832 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 896 bytes
+
+.align 16
+smbios_entry_point:
+db 0,0,0,0,0,0,0,0 ; 8 bytes
+db 0,0,0,0,0,0,0,0 ; 16 bytes
+db 0,0,0,0,0,0,0,0 ; 24 bytes
+db 0,0,0,0,0,0,0   ; 31 bytes
+ASM_END
+
+#endif // HVMASSIST
+ASM_START
+.org 0xcff0
 bios_table_area_end:
 // bcc-generated data will be placed here
 ASM_END
+
--- rombios.bochs.h     2008-12-18 08:46:18.000000000 +0900
+++ rombios.h   2008-12-17 23:33:44.000000000 +0900
@@ -20,13 +20,14 @@
 
 /* define it to include QEMU specific code */
 //#define BX_QEMU
+#define LEGACY
 
 #ifndef LEGACY
 #  define BX_ROMBIOS32     1
 #else
 #  define BX_ROMBIOS32     0
 #endif
-#define DEBUG_ROMBIOS    0
+#define DEBUG_ROMBIOS    1
 
 #define PANIC_PORT  0x400
 #define PANIC_PORT2 0x401
@@ -58,7 +59,9 @@
 #define SMB_IO_BASE       0xb100
 
   // Define the application NAME
-#if defined(BX_QEMU)
+#if define HVMASSIST
+#  define BX_APPNAME "HVMAssist"
+#elif defined(BX_QEMU)
 #  define BX_APPNAME "QEMU"
 #elif defined(PLEX86)
 #  define BX_APPNAME "Plex86"
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel