]> xenbits.xensource.com Git - seabios.git/commitdiff
Move code cenetered around firmware initialization to src/fw/
authorKevin O'Connor <kevin@koconnor.net>
Tue, 3 Sep 2013 01:25:21 +0000 (21:25 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 3 Sep 2013 01:25:21 +0000 (21:25 -0400)
Move many C files from the src/ directory to the new src/fw/ directory.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
78 files changed:
Makefile
src/LegacyBios.h [deleted file]
src/acpi-dsdt-cpu-hotplug.dsl [deleted file]
src/acpi-dsdt-dbug.dsl [deleted file]
src/acpi-dsdt-hpet.dsl [deleted file]
src/acpi-dsdt-isa.dsl [deleted file]
src/acpi-dsdt-pci-crs.dsl [deleted file]
src/acpi-dsdt.dsl [deleted file]
src/acpi.c [deleted file]
src/acpi.h [deleted file]
src/apm.c
src/biostables.c [deleted file]
src/boot.c
src/bootsplash.c
src/coreboot.c [deleted file]
src/csm.c [deleted file]
src/csm.h [deleted file]
src/dev-q35.h [deleted file]
src/fw/LegacyBios.h [new file with mode: 0644]
src/fw/acpi-dsdt-cpu-hotplug.dsl [new file with mode: 0644]
src/fw/acpi-dsdt-dbug.dsl [new file with mode: 0644]
src/fw/acpi-dsdt-hpet.dsl [new file with mode: 0644]
src/fw/acpi-dsdt-isa.dsl [new file with mode: 0644]
src/fw/acpi-dsdt-pci-crs.dsl [new file with mode: 0644]
src/fw/acpi-dsdt.dsl [new file with mode: 0644]
src/fw/acpi.c [new file with mode: 0644]
src/fw/acpi.h [new file with mode: 0644]
src/fw/biostables.c [new file with mode: 0644]
src/fw/coreboot.c [new file with mode: 0644]
src/fw/csm.c [new file with mode: 0644]
src/fw/csm.h [new file with mode: 0644]
src/fw/dev-q35.h [new file with mode: 0644]
src/fw/lzmadecode.c [new file with mode: 0644]
src/fw/lzmadecode.h [new file with mode: 0644]
src/fw/mptable.c [new file with mode: 0644]
src/fw/mptable.h [new file with mode: 0644]
src/fw/mtrr.c [new file with mode: 0644]
src/fw/paravirt.c [new file with mode: 0644]
src/fw/paravirt.h [new file with mode: 0644]
src/fw/pciinit.c [new file with mode: 0644]
src/fw/pirtable.c [new file with mode: 0644]
src/fw/q35-acpi-dsdt.dsl [new file with mode: 0644]
src/fw/shadow.c [new file with mode: 0644]
src/fw/smbios.c [new file with mode: 0644]
src/fw/smbios.h [new file with mode: 0644]
src/fw/smm.c [new file with mode: 0644]
src/fw/smp.c [new file with mode: 0644]
src/fw/ssdt-misc.dsl [new file with mode: 0644]
src/fw/ssdt-pcihp.dsl [new file with mode: 0644]
src/fw/ssdt-proc.dsl [new file with mode: 0644]
src/fw/xen.c [new file with mode: 0644]
src/fw/xen.h [new file with mode: 0644]
src/hw/esp-scsi.c
src/hw/lsi-scsi.c
src/lzmadecode.c [deleted file]
src/lzmadecode.h [deleted file]
src/mptable.c [deleted file]
src/mptable.h [deleted file]
src/mtrr.c [deleted file]
src/output.c
src/paravirt.c [deleted file]
src/paravirt.h [deleted file]
src/pciinit.c [deleted file]
src/pirtable.c [deleted file]
src/post.c
src/q35-acpi-dsdt.dsl [deleted file]
src/resume.c
src/shadow.c [deleted file]
src/smbios.c [deleted file]
src/smbios.h [deleted file]
src/smm.c [deleted file]
src/smp.c [deleted file]
src/ssdt-misc.dsl [deleted file]
src/ssdt-pcihp.dsl [deleted file]
src/ssdt-proc.dsl [deleted file]
src/util.h
src/xen.c [deleted file]
src/xen.h [deleted file]

index a43fa14998ed0562a0f8d58be13e2e2c1a4a5308..ae6253c9857276472131bfec34510ac053c656bc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,18 +9,18 @@ OUT=out/
 
 # Source files
 SRCBOTH=misc.c stacks.c output.c util.c block.c hw/floppy.c hw/ata.c mouse.c \
-    kbd.c hw/pci.c serial.c hw/timer.c clock.c hw/pic.c cdrom.c hw/ps2port.c smp.c resume.c \
+    kbd.c hw/pci.c serial.c hw/timer.c clock.c hw/pic.c cdrom.c hw/ps2port.c fw/smp.c resume.c \
     pnpbios.c vgahooks.c hw/ramdisk.c pcibios.c hw/blockcmd.c \
     hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c hw/usb-hid.c hw/usb-msc.c \
     hw/virtio-ring.c hw/virtio-pci.c hw/virtio-blk.c hw/virtio-scsi.c apm.c hw/ahci.c \
     hw/usb-uas.c hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c
 SRC16=$(SRCBOTH) system.c disk.c font.c
-SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c pmm.c coreboot.c boot.c \
-    acpi.c smm.c mptable.c pirtable.c smbios.c pciinit.c optionroms.c mtrr.c \
-    lzmadecode.c bootsplash.c jpeg.c hw/usb-hub.c paravirt.c \
-    biostables.c xen.c bmp.c romfile.c csm.c
+SRC32FLAT=$(SRCBOTH) post.c fw/shadow.c memmap.c pmm.c fw/coreboot.c boot.c \
+    fw/acpi.c fw/smm.c fw/mptable.c fw/pirtable.c fw/smbios.c fw/pciinit.c optionroms.c fw/mtrr.c \
+    fw/lzmadecode.c bootsplash.c jpeg.c hw/usb-hub.c fw/paravirt.c \
+    fw/biostables.c fw/xen.c bmp.c romfile.c fw/csm.c
 SRC32SEG=util.c output.c hw/pci.c pcibios.c apm.c stacks.c
-DIRS=src src/hw vgasrc
+DIRS=src src/hw src/fw vgasrc
 
 # Default compiler flags
 cc-option=$(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`" \
@@ -213,7 +213,7 @@ $(OUT)vgabios.bin: $(OUT)vgabios.bin.raw scripts/buildrom.py
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
     ; then echo "$(2)"; else echo "$(3)"; fi ;)
 
-$(OUT)%.hex: src/%.dsl ./scripts/acpi_extract_preprocess.py ./scripts/acpi_extract.py
+$(OUT)%.hex: %.dsl ./scripts/acpi_extract_preprocess.py ./scripts/acpi_extract.py
        @echo "  Compiling IASL $@"
        $(Q)$(CPP) $(CPPFLAGS) $< -o $(OUT)$*.dsl.i.orig
        $(Q)$(PYTHON) ./scripts/acpi_extract_preprocess.py $(OUT)$*.dsl.i.orig > $(OUT)$*.dsl.i
@@ -221,7 +221,7 @@ $(OUT)%.hex: src/%.dsl ./scripts/acpi_extract_preprocess.py ./scripts/acpi_extra
        $(Q)$(PYTHON) ./scripts/acpi_extract.py $(OUT)$*.lst > $(OUT)$*.off
        $(Q)cat $(OUT)$*.off > $@
 
-$(OUT)src/acpi.o: $(OUT)acpi-dsdt.hex $(OUT)ssdt-proc.hex $(OUT)ssdt-pcihp.hex $(OUT)ssdt-misc.hex $(OUT)q35-acpi-dsdt.hex
+$(OUT)src/fw/acpi.o: $(OUT)src/fw/acpi-dsdt.hex $(OUT)src/fw/ssdt-proc.hex $(OUT)src/fw/ssdt-pcihp.hex $(OUT)src/fw/ssdt-misc.hex $(OUT)src/fw/q35-acpi-dsdt.hex
 
 ################ Kconfig rules
 
diff --git a/src/LegacyBios.h b/src/LegacyBios.h
deleted file mode 100644 (file)
index cf0c3c5..0000000
+++ /dev/null
@@ -1,965 +0,0 @@
-/** @file
-  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage
-  under EFI and Legacy OS boot.  This file also includes all the related
-  COMPATIBILIY16 structures and defintions.
-
-  Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow
-  well known naming conventions.
-
-  Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode
-       environment. Reverse thunk is the code that does the opposite.
-
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available under 
-the terms and conditions of the BSD License that accompanies this distribution.  
-The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php.                                          
-    
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-  @par Revision Reference:
-  This protocol is defined in Framework for EFI Compatibility Support Module spec
-  Version 0.97.
-
-**/
-
-#ifndef _EFI_LEGACY_BIOS_H_
-#define _EFI_LEGACY_BIOS_H_
-
-///
-/// 
-///
-#pragma pack(1)
-
-typedef UINT8                       SERIAL_MODE;
-typedef UINT8                       PARALLEL_MODE;
-
-#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$')
-
-///
-/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx
-/// physical address range. It is located on a 16-byte boundary and provides the physical address of the
-/// entry point for the Compatibility16 functions. These functions provide the platform-specific
-/// information that is required by the generic EfiCompatibility code. The functions are invoked via
-/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical
-/// entry point.
-///
-typedef struct {
-  ///
-  /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte
-  /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32.
-  ///
-  UINT32                            Signature;
-  
-  ///
-  /// The value required such that byte checksum of TableLength equals zero.
-  ///
-  UINT8                             TableChecksum;
-  
-  ///
-  /// The length of this table.
-  ///
-  UINT8                             TableLength;
-  
-  ///
-  /// The major EFI revision for which this table was generated.
-  /// 
-  UINT8                             EfiMajorRevision;
-  
-  ///
-  /// The minor EFI revision for which this table was generated.
-  ///
-  UINT8                             EfiMinorRevision;
-  
-  ///
-  /// The major revision of this table.
-  ///
-  UINT8                             TableMajorRevision;
-  
-  ///
-  /// The minor revision of this table.
-  ///
-  UINT8                             TableMinorRevision;
-  
-  ///
-  /// Reserved for future usage.
-  ///
-  UINT16                            Reserved;
-  
-  ///
-  /// The segment of the entry point within the traditional BIOS for Compatibility16 functions.
-  ///
-  UINT16                            Compatibility16CallSegment;
-  
-  ///
-  /// The offset of the entry point within the traditional BIOS for Compatibility16 functions.
-  ///
-  UINT16                            Compatibility16CallOffset;
-  
-  ///
-  /// The segment of the entry point within the traditional BIOS for EfiCompatibility 
-  /// to invoke the PnP installation check.
-  ///
-  UINT16                            PnPInstallationCheckSegment;
-  
-  ///
-  /// The Offset of the entry point within the traditional BIOS for EfiCompatibility 
-  /// to invoke the PnP installation check.
-  ///
-  UINT16                            PnPInstallationCheckOffset;
-  
-  ///
-  /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform 
-  ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS).
-  ///
-  UINT32                            EfiSystemTable; 
-  
-  ///
-  /// The address of an OEM-provided identifier string. The string is null terminated.
-  ///
-  UINT32                            OemIdStringPointer;
-  
-  ///
-  /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional
-  /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size
-  /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI
-  /// RSD PTR with either the ACPI 1.0b or 2.0 values.
-  ///
-  UINT32                            AcpiRsdPtrPointer;
-  
-  ///
-  /// The OEM revision number. Usage is undefined but provided for OEM module usage.
-  ///
-  UINT16                            OemRevision;
-  
-  ///
-  /// The 32-bit physical address where INT15 E820 data is stored within the traditional
-  /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the
-  /// data to the indicated area.
-  ///
-  UINT32                            E820Pointer;
-  
-  ///
-  /// The length of the E820 data and is filled in by the EfiCompatibility code.
-  ///
-  UINT32                            E820Length;
-  
-  ///
-  /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS.
-  /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and
-  /// copy the data to the indicated area.
-  ///
-  UINT32                            IrqRoutingTablePointer;
-  
-  ///
-  /// The length of the $PIR table and is filled in by the EfiCompatibility code.
-  ///
-  UINT32                            IrqRoutingTableLength;
-  
-  ///
-  /// The 32-bit physical address where the MP table is stored in the traditional BIOS.
-  /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data 
-  /// to the indicated area.
-  ///
-  UINT32                            MpTablePtr;
-  
-  ///
-  /// The length of the MP table and is filled in by the EfiCompatibility code.
-  ///
-  UINT32                            MpTableLength;
-  
-  ///
-  /// The segment of the OEM-specific INT table/code.
-  /// 
-  UINT16                            OemIntSegment;
-  
-  ///
-  /// The offset of the OEM-specific INT table/code.
-  ///
-  UINT16                            OemIntOffset;
-  
-  ///
-  /// The segment of the OEM-specific 32-bit table/code.
-  ///
-  UINT16                            Oem32Segment;
-  
-  ///
-  /// The offset of the OEM-specific 32-bit table/code.
-  ///
-  UINT16                            Oem32Offset;
-  
-  ///
-  /// The segment of the OEM-specific 16-bit table/code.
-  ///
-  UINT16                            Oem16Segment;
-  
-  ///
-  /// The offset of the OEM-specific 16-bit table/code.
-  ///
-  UINT16                            Oem16Offset;
-  
-  ///
-  /// The segment of the TPM binary passed to 16-bit CSM.
-  ///
-  UINT16                            TpmSegment;
-  
-  ///
-  /// The offset of the TPM binary passed to 16-bit CSM.
-  ///
-  UINT16                            TpmOffset;
-  
-  ///
-  /// A pointer to a string identifying the independent BIOS vendor.
-  ///
-  UINT32                            IbvPointer;
-  
-  ///
-  /// This field is NULL for all systems not supporting PCI Express. This field is the base
-  /// value of the start of the PCI Express memory-mapped configuration registers and
-  /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function
-  /// Compatibility16InitializeYourself().
-  /// Compatibility16InitializeYourself() is defined in Compatability16
-  /// Functions.
-  ///
-  UINT32                            PciExpressBase;
-  
-  ///
-  /// Maximum PCI bus number assigned.
-  ///
-  UINT8                             LastPciBus;
-} EFI_COMPATIBILITY16_TABLE;
-
-///
-/// Functions provided by the CSM binary which communicate between the EfiCompatibility 
-/// and Compatability16 code.
-///
-/// Inconsistent with the specification here: 
-/// The member's name started with "Compatibility16" [defined in Intel Framework 
-/// Compatibility Support Module Specification / 0.97 version] 
-/// has been changed to "Legacy16" since keeping backward compatible.
-///
-typedef enum {
-  ///
-  /// Causes the Compatibility16 code to do any internal initialization required.
-  /// Input:
-  ///   AX = Compatibility16InitializeYourself
-  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE
-  /// Return:
-  ///   AX = Return Status codes
-  ///
-  Legacy16InitializeYourself    = 0x0000,
-  
-  ///
-  /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence.
-  /// Input:
-  ///   AX = Compatibility16UpdateBbs
-  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
-  /// Return:
-  ///   AX = Returned status codes
-  ///
-  Legacy16UpdateBbs             = 0x0001,
-  
-  ///
-  /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16
-  /// code is read/write.
-  /// Input:
-  ///   AX = Compatibility16PrepareToBoot
-  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure  
-  /// Return:
-  ///   AX = Returned status codes
-  ///
-  Legacy16PrepareToBoot         = 0x0002,
-  
-  ///
-  /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only.
-  /// Input:
-  ///   AX = Compatibility16Boot
-  /// Output:
-  ///   AX = Returned status codes
-  ///
-  Legacy16Boot                  = 0x0003,
-  
-  ///
-  /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is
-  /// stored in CMOS and is the priority number of the last attempted boot device.
-  /// Input:
-  ///   AX = Compatibility16RetrieveLastBootDevice
-  /// Output:
-  ///   AX = Returned status codes
-  ///   BX = Priority number of the boot device.
-  ///
-  Legacy16RetrieveLastBootDevice = 0x0004,
-  
-  ///
-  /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM.
-  /// Input:
-  ///   AX = Compatibility16DispatchOprom
-  ///   ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE
-  /// Output:
-  ///   AX = Returned status codes
-  ///   BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant.
-  ///
-  Legacy16DispatchOprom         = 0x0005,
-  
-  ///
-  /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address
-  /// of that region.
-  /// Input:
-  ///   AX = Compatibility16GetTableAddress
-  ///   BX = Allocation region
-  ///       00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.
-  ///       Bit 0 = 1 Allocate from 0xF0000 64 KB block
-  ///       Bit 1 = 1 Allocate from 0xE0000 64 KB block
-  ///   CX = Requested length in bytes.
-  ///   DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment.
-  /// Output:
-  ///   AX = Returned status codes
-  ///   DS:BX = Address of the region
-  ///
-  Legacy16GetTableAddress       = 0x0006,
-  
-  ///
-  /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state.
-  /// Input:
-  ///   AX = Compatibility16SetKeyboardLeds
-  ///   CL = LED status.
-  ///     Bit 0  Scroll Lock 0 = Off
-  ///     Bit 1  NumLock
-  ///     Bit 2  Caps Lock
-  /// Output:
-  ///     AX = Returned status codes
-  ///
-  Legacy16SetKeyboardLeds       = 0x0007,
-  
-  ///
-  /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that
-  /// do not have an OpROM associated with them. An example is SATA.
-  /// Input:
-  ///   AX = Compatibility16InstallPciHandler
-  ///   ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure
-  /// Output:
-  ///   AX = Returned status codes
-  ///
-  Legacy16InstallPciHandler     = 0x0008
-} EFI_COMPATIBILITY_FUNCTIONS;
-
-
-///
-/// EFI_DISPATCH_OPROM_TABLE
-///
-typedef struct {
-  UINT16  PnPInstallationCheckSegment;  ///< A pointer to the PnpInstallationCheck data structure.
-  UINT16  PnPInstallationCheckOffset;   ///< A pointer to the PnpInstallationCheck data structure.
-  UINT16  OpromSegment;                 ///< The segment where the OpROM was placed. Offset is assumed to be 3.
-  UINT8   PciBus;                       ///< The PCI bus.
-  UINT8   PciDeviceFunction;            ///< The PCI device * 0x08 | PCI function.
-  UINT8   NumberBbsEntries;             ///< The number of valid BBS table entries upon entry and exit. The IBV code may
-                                        ///< increase this number, if BBS-compliant devices also hook INTs in order to force the
-                                        ///< OpROM BIOS Setup to be executed.
-  UINT32  BbsTablePointer;              ///< A pointer to the BBS table.
-  UINT16  RuntimeSegment;               ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this
-                                        ///< means that the relocation of this run time code is not supported.
-                                        ///< Inconsistent with specification here: 
-                                        ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version] 
-                                        ///< has been changed to "RuntimeSegment" since keeping backward compatible.
-
-} EFI_DISPATCH_OPROM_TABLE;
-
-///
-/// EFI_TO_COMPATIBILITY16_INIT_TABLE
-///
-typedef struct {
-  ///
-  /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF.
-  ///
-  UINT32                            BiosLessThan1MB;
-  
-  ///
-  /// The starting address of the high memory block.
-  ///
-  UINT32                            HiPmmMemory;
-  
-  ///
-  /// The length of high memory block.
-  ///
-  UINT32                            HiPmmMemorySizeInBytes;
-  
-  ///
-  /// The segment of the reverse thunk call code.
-  ///
-  UINT16                            ReverseThunkCallSegment;
-  
-  ///
-  /// The offset of the reverse thunk call code.
-  ///
-  UINT16                            ReverseThunkCallOffset;
-  
-  ///
-  /// The number of E820 entries copied to the Compatibility16 BIOS.
-  ///
-  UINT32                            NumberE820Entries;
-  
-  ///
-  /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory.
-  ///
-  UINT32                            OsMemoryAbove1Mb;
-  
-  ///
-  /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM.
-  ///
-  UINT32                            ThunkStart;
-  
-  ///
-  /// The size of the thunk code.
-  ///
-  UINT32                            ThunkSizeInBytes;
-  
-  ///
-  /// Starting address of memory under 1 MB.
-  ///
-  UINT32                            LowPmmMemory;
-  
-  ///
-  /// The length of low Memory block.
-  ///
-  UINT32                            LowPmmMemorySizeInBytes;
-} EFI_TO_COMPATIBILITY16_INIT_TABLE;
-
-///
-/// DEVICE_PRODUCER_SERIAL.
-///
-typedef struct {
-  UINT16                            Address;    ///< I/O address assigned to the serial port.
-  UINT8                             Irq;        ///< IRQ assigned to the serial port.
-  SERIAL_MODE                       Mode;       ///< Mode of serial port. Values are defined below.
-} DEVICE_PRODUCER_SERIAL;
-
-///
-/// DEVICE_PRODUCER_SERIAL's modes.
-///@{
-#define DEVICE_SERIAL_MODE_NORMAL               0x00
-#define DEVICE_SERIAL_MODE_IRDA                 0x01
-#define DEVICE_SERIAL_MODE_ASK_IR               0x02
-#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00
-#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10
-///@)
-
-///
-/// DEVICE_PRODUCER_PARALLEL.
-///
-typedef struct {
-  UINT16                            Address;  ///< I/O address assigned to the parallel port.
-  UINT8                             Irq;      ///< IRQ assigned to the parallel port.
-  UINT8                             Dma;      ///< DMA assigned to the parallel port.
-  PARALLEL_MODE                     Mode;     ///< Mode of the parallel port. Values are defined below.
-} DEVICE_PRODUCER_PARALLEL;
-
-///
-/// DEVICE_PRODUCER_PARALLEL's modes.
-///@{
-#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00
-#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01
-#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02
-#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03
-///@}
-
-///
-/// DEVICE_PRODUCER_FLOPPY
-///
-typedef struct {
-  UINT16                            Address;          ///< I/O address assigned to the floppy.
-  UINT8                             Irq;              ///< IRQ assigned to the floppy.
-  UINT8                             Dma;              ///< DMA assigned to the floppy.
-  UINT8                             NumberOfFloppy;   ///< Number of floppies in the system.
-} DEVICE_PRODUCER_FLOPPY;
-
-///
-/// LEGACY_DEVICE_FLAGS
-///
-typedef struct {
-  UINT32                            A20Kybd : 1;      ///< A20 controller by keyboard controller.
-  UINT32                            A20Port90 : 1;    ///< A20 controlled by port 0x92.
-  UINT32                            Reserved : 30;    ///< Reserved for future usage.
-} LEGACY_DEVICE_FLAGS;
-
-///
-/// DEVICE_PRODUCER_DATA_HEADER
-///
-typedef struct {
-  DEVICE_PRODUCER_SERIAL            Serial[4];      ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below.
-  DEVICE_PRODUCER_PARALLEL          Parallel[3];    ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below.
-  DEVICE_PRODUCER_FLOPPY            Floppy;         ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below.
-  UINT8                             MousePresent;   ///< Flag to indicate if mouse is present.
-  LEGACY_DEVICE_FLAGS               Flags;          ///< Miscellaneous Boolean state information passed to CSM.
-} DEVICE_PRODUCER_DATA_HEADER;
-
-///
-/// ATAPI_IDENTIFY
-///
-typedef struct {
-  UINT16                            Raw[256];     ///< Raw data from the IDE IdentifyDrive command.
-} ATAPI_IDENTIFY;
-
-///
-/// HDD_INFO
-///
-typedef struct {
-  ///
-  /// Status of IDE device. Values are defined below. There is one HDD_INFO structure
-  /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index
-  /// 1 is slave.
-  ///
-  UINT16                            Status;   
-  
-  ///
-  /// PCI bus of IDE controller.
-  ///
-  UINT32                            Bus;
-  
-  ///
-  /// PCI device of IDE controller.
-  ///
-  UINT32                            Device;
-  
-  ///
-  /// PCI function of IDE controller.
-  ///
-  UINT32                            Function;
-  
-  ///
-  /// Command ports base address.
-  ///
-  UINT16                            CommandBaseAddress;
-  
-  ///
-  /// Control ports base address.
-  ///
-  UINT16                            ControlBaseAddress;
-  
-  ///
-  /// Bus master address.
-  ///
-  UINT16                            BusMasterAddress;
-  
-  UINT8                             HddIrq;
-  
-  ///
-  /// Data that identifies the drive data; one per possible attached drive.
-  ///
-  ATAPI_IDENTIFY                    IdentifyDrive[2];
-} HDD_INFO;
-
-///
-/// HDD_INFO status bits
-///
-#define HDD_PRIMARY               0x01
-#define HDD_SECONDARY             0x02
-#define HDD_MASTER_ATAPI_CDROM    0x04
-#define HDD_SLAVE_ATAPI_CDROM     0x08
-#define HDD_MASTER_IDE            0x20
-#define HDD_SLAVE_IDE             0x40
-#define HDD_MASTER_ATAPI_ZIPDISK  0x10
-#define HDD_SLAVE_ATAPI_ZIPDISK   0x80
-
-///
-/// BBS_STATUS_FLAGS;\.
-///
-typedef struct {
-  UINT16                            OldPosition : 4;    ///< Prior priority.
-  UINT16                            Reserved1 : 4;      ///< Reserved for future use.
-  UINT16                            Enabled : 1;        ///< If 0, ignore this entry.
-  UINT16                            Failed : 1;         ///< 0 = Not known if boot failure occurred.
-                                                        ///< 1 = Boot attempted failed.
-  
-  ///
-  /// State of media present.
-  ///   00 = No bootable media is present in the device.
-  ///   01 = Unknown if a bootable media present.
-  ///   10 = Media is present and appears bootable.
-  ///   11 = Reserved.
-  ///
-  UINT16                            MediaPresent : 2;
-  UINT16                            Reserved2 : 4;      ///< Reserved for future use.
-} BBS_STATUS_FLAGS;
-
-///
-/// BBS_TABLE, device type values & boot priority values.
-///
-typedef struct {
-  ///
-  /// The boot priority for this boot device. Values are defined below.
-  ///
-  UINT16                            BootPriority;
-  
-  ///
-  /// The PCI bus for this boot device.
-  ///
-  UINT32                            Bus;
-  
-  ///
-  /// The PCI device for this boot device.
-  ///
-  UINT32                            Device;
-  
-  ///
-  /// The PCI function for the boot device.
-  ///
-  UINT32                            Function;
-  
-  ///
-  /// The PCI class for this boot device.
-  ///
-  UINT8                             Class;
-  
-  ///
-  /// The PCI Subclass for this boot device.
-  ///
-  UINT8                             SubClass;
-  
-  ///
-  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
-  ///
-  UINT16                            MfgStringOffset;
-  
-  ///
-  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
-  ///  
-  UINT16                            MfgStringSegment;
-  
-  ///
-  /// BBS device type. BBS device types are defined below.
-  ///
-  UINT16                            DeviceType;
-  
-  ///
-  /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below.
-  ///
-  BBS_STATUS_FLAGS                  StatusFlags;
-  
-  ///
-  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
-  /// BCV devices.
-  ///
-  UINT16                            BootHandlerOffset;
-  
-  ///
-  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
-  /// BCV devices.
-  ///  
-  UINT16                            BootHandlerSegment;
-  
-  ///
-  /// Segment:offset address of an ASCIIZ description string describing this device.
-  ///
-  UINT16                            DescStringOffset;
-
-  ///
-  /// Segment:offset address of an ASCIIZ description string describing this device.
-  ///
-  UINT16                            DescStringSegment;
-  
-  ///
-  /// Reserved.
-  ///
-  UINT32                            InitPerReserved;
-  
-  ///
-  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
-  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
-  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
-  ///
-  UINT32                            AdditionalIrq13Handler;
-  
-  ///
-  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
-  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
-  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
-  ///  
-  UINT32                            AdditionalIrq18Handler;
-  
-  ///
-  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
-  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
-  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
-  ///  
-  UINT32                            AdditionalIrq19Handler;
-  
-  ///
-  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
-  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
-  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
-  ///  
-  UINT32                            AdditionalIrq40Handler;
-  UINT8                             AssignedDriveNumber;
-  UINT32                            AdditionalIrq41Handler;
-  UINT32                            AdditionalIrq46Handler;
-  UINT32                            IBV1;
-  UINT32                            IBV2;
-} BBS_TABLE;
-
-///
-/// BBS device type values
-///@{
-#define BBS_FLOPPY              0x01
-#define BBS_HARDDISK            0x02
-#define BBS_CDROM               0x03
-#define BBS_PCMCIA              0x04
-#define BBS_USB                 0x05
-#define BBS_EMBED_NETWORK       0x06
-#define BBS_BEV_DEVICE          0x80
-#define BBS_UNKNOWN             0xff
-///@}
-
-///
-/// BBS boot priority values
-///@{
-#define BBS_DO_NOT_BOOT_FROM    0xFFFC
-#define BBS_LOWEST_PRIORITY     0xFFFD
-#define BBS_UNPRIORITIZED_ENTRY 0xFFFE
-#define BBS_IGNORE_ENTRY        0xFFFF
-///@}
-
-///
-/// SMM_ATTRIBUTES
-///
-typedef struct {
-  ///
-  /// Access mechanism used to generate the soft SMI. Defined types are below. The other
-  /// values are reserved for future usage.
-  ///
-  UINT16                            Type : 3;
-  
-  ///
-  /// The size of "port" in bits. Defined values are below.
-  ///
-  UINT16                            PortGranularity : 3;
-  
-  ///
-  /// The size of data in bits. Defined values are below.
-  ///
-  UINT16                            DataGranularity : 3;
-  
-  ///
-  /// Reserved for future use.
-  ///
-  UINT16                            Reserved : 7;
-} SMM_ATTRIBUTES;
-
-///
-/// SMM_ATTRIBUTES type values.
-///@{
-#define STANDARD_IO       0x00
-#define STANDARD_MEMORY   0x01
-///@}
-
-///
-/// SMM_ATTRIBUTES port size constants.
-///@{
-#define PORT_SIZE_8       0x00
-#define PORT_SIZE_16      0x01
-#define PORT_SIZE_32      0x02
-#define PORT_SIZE_64      0x03
-///@}
-
-///
-/// SMM_ATTRIBUTES data size constants.
-///@{
-#define DATA_SIZE_8       0x00
-#define DATA_SIZE_16      0x01
-#define DATA_SIZE_32      0x02
-#define DATA_SIZE_64      0x03
-///@}
-
-///
-/// SMM_FUNCTION & relating constants.
-///
-typedef struct {
-  UINT16                            Function : 15;
-  UINT16                            Owner : 1;
-} SMM_FUNCTION;
-
-///
-/// SMM_FUNCTION Function constants.
-///@{
-#define INT15_D042        0x0000
-#define GET_USB_BOOT_INFO 0x0001
-#define DMI_PNP_50_57     0x0002
-///@}
-
-///
-/// SMM_FUNCTION Owner constants.
-///@{
-#define STANDARD_OWNER    0x0
-#define OEM_OWNER         0x1
-///@}
-
-///
-/// This structure assumes both port and data sizes are 1. SmmAttribute must be
-/// properly to reflect that assumption.
-///
-typedef struct {
-  ///
-  /// Describes the access mechanism, SmmPort, and SmmData sizes. Type
-  /// SMM_ATTRIBUTES is defined below.
-  ///
-  SMM_ATTRIBUTES                    SmmAttributes;
-  
-  ///
-  /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below.
-  ///
-  SMM_FUNCTION                      SmmFunction;
-  
-  ///
-  /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
-  ///
-  UINT8                             SmmPort;
-  
-  ///
-  /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
-  ///
-  UINT8                             SmmData;
-} SMM_ENTRY;
-
-///
-/// SMM_TABLE
-///
-typedef struct {
-  UINT16                            NumSmmEntries;    ///< Number of entries represented by SmmEntry.
-  SMM_ENTRY                         SmmEntry;         ///< One entry per function. Type SMM_ENTRY is defined below.
-} SMM_TABLE;
-
-///
-/// UDC_ATTRIBUTES
-///
-typedef struct {
-  ///
-  /// This bit set indicates that the ServiceAreaData is valid.
-  ///
-  UINT8                             DirectoryServiceValidity : 1;
-  
-  ///
-  /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if
-  /// DirectoryServiceValidity is 0.
-  ///
-  UINT8                             RabcaUsedFlag : 1;
-  
-  ///
-  /// This bit set indicates to execute hard disk diagnostics.
-  ///
-  UINT8                             ExecuteHddDiagnosticsFlag : 1;
-  
-  ///
-  /// Reserved for future use. Set to 0.
-  ///
-  UINT8                             Reserved : 5;
-} UDC_ATTRIBUTES;
-
-///
-/// UD_TABLE
-///
-typedef struct {
-  ///
-  /// This field contains the bit-mapped attributes of the PARTIES information. Type
-  /// UDC_ATTRIBUTES is defined below.
-  ///
-  UDC_ATTRIBUTES                    Attributes;
-  
-  ///
-  /// This field contains the zero-based device on which the selected
-  /// ServiceDataArea is present. It is 0 for master and 1 for the slave device.  
-  ///
-  UINT8                             DeviceNumber;
-  
-  ///
-  /// This field contains the zero-based index into the BbsTable for the parent device.
-  /// This index allows the user to reference the parent device information such as PCI
-  /// bus, device function.
-  ///
-  UINT8                             BbsTableEntryNumberForParentDevice;
-  
-  ///
-  /// This field contains the zero-based index into the BbsTable for the boot entry.
-  ///
-  UINT8                             BbsTableEntryNumberForBoot;
-  
-  ///
-  /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry.
-  ///
-  UINT8                             BbsTableEntryNumberForHddDiag;
-  
-  ///
-  /// The raw Beer data.
-  ///
-  UINT8                             BeerData[128];
-  
-  ///
-  /// The raw data of selected service area.
-  ///
-  UINT8                             ServiceAreaData[64];
-} UD_TABLE;
-
-#define EFI_TO_LEGACY_MAJOR_VERSION 0x02
-#define EFI_TO_LEGACY_MINOR_VERSION 0x00
-#define MAX_IDE_CONTROLLER          8
-
-///
-/// EFI_TO_COMPATIBILITY16_BOOT_TABLE
-///
-typedef struct {
-  UINT16                            MajorVersion;                 ///< The EfiCompatibility major version number.
-  UINT16                            MinorVersion;                 ///< The EfiCompatibility minor version number.
-  UINT32                            AcpiTable;                    ///< The location of the RSDT ACPI table. < 4G range.
-  UINT32                            SmbiosTable;                  ///< The location of the SMBIOS table in EFI memory. < 4G range.
-  UINT32                            SmbiosTableLength;
-  //
-  // Legacy SIO state
-  //
-  DEVICE_PRODUCER_DATA_HEADER       SioData;                      ///< Standard traditional device information.
-  UINT16                            DevicePathType;               ///< The default boot type.
-  UINT16                            PciIrqMask;                   ///< Mask of which IRQs have been assigned to PCI.
-  UINT32                            NumberE820Entries;            ///< Number of E820 entries. The number can change from the
-                                                                  ///< Compatibility16InitializeYourself() function.
-  //
-  // Controller & Drive Identify[2] per controller information
-  //
-  HDD_INFO                          HddInfo[MAX_IDE_CONTROLLER];  ///< Hard disk drive information, including raw Identify Drive data.
-  UINT32                            NumberBbsEntries;             ///< Number of entries in the BBS table
-  UINT32                            BbsTable;                     ///< A pointer to the BBS table. Type BBS_TABLE is defined below.
-  UINT32                            SmmTable;                     ///< A pointer to the SMM table. Type SMM_TABLE is defined below.
-  UINT32                            OsMemoryAbove1Mb;             ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can
-                                                                  ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more
-                                                                  ///< memory may have been discovered.
-  UINT32                            UnconventionalDeviceTable;    ///< Information to boot off an unconventional device like a PARTIES partition. Type
-                                                                  ///< UD_TABLE is defined below.
-} EFI_TO_COMPATIBILITY16_BOOT_TABLE;
-
-///
-/// EFI_LEGACY_INSTALL_PCI_HANDLER
-///
-typedef struct {
-  UINT8                             PciBus;             ///< The PCI bus of the device.
-  UINT8                             PciDeviceFun;       ///< The PCI device in bits 7:3 and function in bits 2:0.
-  UINT8                             PciSegment;         ///< The PCI segment of the device.
-  UINT8                             PciClass;           ///< The PCI class code of the device.
-  UINT8                             PciSubclass;        ///< The PCI subclass code of the device.
-  UINT8                             PciInterface;       ///< The PCI interface code of the device.
-  //
-  // Primary section
-  //
-  UINT8                             PrimaryIrq;         ///< The primary device IRQ.
-  UINT8                             PrimaryReserved;    ///< Reserved.
-  UINT16                            PrimaryControl;     ///< The primary device control I/O base.
-  UINT16                            PrimaryBase;        ///< The primary device I/O base.
-  UINT16                            PrimaryBusMaster;   ///< The primary device bus master I/O base.
-  //
-  // Secondary Section
-  //
-  UINT8                             SecondaryIrq;       ///< The secondary device IRQ.
-  UINT8                             SecondaryReserved;  ///< Reserved.
-  UINT16                            SecondaryControl;   ///< The secondary device control I/O base.
-  UINT16                            SecondaryBase;      ///< The secondary device I/O base.
-  UINT16                            SecondaryBusMaster; ///< The secondary device bus master I/O base.
-} EFI_LEGACY_INSTALL_PCI_HANDLER;
-
-#endif
diff --git a/src/acpi-dsdt-cpu-hotplug.dsl b/src/acpi-dsdt-cpu-hotplug.dsl
deleted file mode 100644 (file)
index 0f3e83b..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************
- * CPU hotplug
- ****************************************************************/
-
-Scope(\_SB) {
-    /* Objects filled in by run-time generated SSDT */
-    External(NTFY, MethodObj)
-    External(CPON, PkgObj)
-
-    /* Methods called by run-time generated SSDT Processor objects */
-    Method(CPMA, 1, NotSerialized) {
-        // _MAT method - create an madt apic buffer
-        // Arg0 = Processor ID = Local APIC ID
-        // Local0 = CPON flag for this cpu
-        Store(DerefOf(Index(CPON, Arg0)), Local0)
-        // Local1 = Buffer (in madt apic form) to return
-        Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
-        // Update the processor id, lapic id, and enable/disable status
-        Store(Arg0, Index(Local1, 2))
-        Store(Arg0, Index(Local1, 3))
-        Store(Local0, Index(Local1, 4))
-        Return (Local1)
-    }
-    Method(CPST, 1, NotSerialized) {
-        // _STA method - return ON status of cpu
-        // Arg0 = Processor ID = Local APIC ID
-        // Local0 = CPON flag for this cpu
-        Store(DerefOf(Index(CPON, Arg0)), Local0)
-        If (Local0) {
-            Return (0xF)
-        } Else {
-            Return (0x0)
-        }
-    }
-    Method(CPEJ, 2, NotSerialized) {
-        // _EJ0 method - eject callback
-        Sleep(200)
-    }
-
-    /* CPU hotplug notify method */
-    OperationRegion(PRST, SystemIO, 0xaf00, 32)
-    Field(PRST, ByteAcc, NoLock, Preserve) {
-        PRS, 256
-    }
-    Method(PRSC, 0) {
-        // Local5 = active cpu bitmap
-        Store(PRS, Local5)
-        // Local2 = last read byte from bitmap
-        Store(Zero, Local2)
-        // Local0 = Processor ID / APIC ID iterator
-        Store(Zero, Local0)
-        While (LLess(Local0, SizeOf(CPON))) {
-            // Local1 = CPON flag for this cpu
-            Store(DerefOf(Index(CPON, Local0)), Local1)
-            If (And(Local0, 0x07)) {
-                // Shift down previously read bitmap byte
-                ShiftRight(Local2, 1, Local2)
-            } Else {
-                // Read next byte from cpu bitmap
-                Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
-            }
-            // Local3 = active state for this cpu
-            Store(And(Local2, 1), Local3)
-
-            If (LNotEqual(Local1, Local3)) {
-                // State change - update CPON with new state
-                Store(Local3, Index(CPON, Local0))
-                // Do CPU notify
-                If (LEqual(Local3, 1)) {
-                    NTFY(Local0, 1)
-                } Else {
-                    NTFY(Local0, 3)
-                }
-            }
-            Increment(Local0)
-        }
-    }
-}
diff --git a/src/acpi-dsdt-dbug.dsl b/src/acpi-dsdt-dbug.dsl
deleted file mode 100644 (file)
index 276321f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************
- * Debugging
- ****************************************************************/
-
-Scope(\) {
-    /* Debug Output */
-    OperationRegion(DBG, SystemIO, 0x0402, 0x01)
-    Field(DBG, ByteAcc, NoLock, Preserve) {
-        DBGB,   8,
-    }
-
-    /* Debug method - use this method to send output to the QEMU
-     * BIOS debug port.  This method handles strings, integers,
-     * and buffers.  For example: DBUG("abc") DBUG(0x123) */
-    Method(DBUG, 1) {
-        ToHexString(Arg0, Local0)
-        ToBuffer(Local0, Local0)
-        Subtract(SizeOf(Local0), 1, Local1)
-        Store(Zero, Local2)
-        While (LLess(Local2, Local1)) {
-            Store(DerefOf(Index(Local0, Local2)), DBGB)
-            Increment(Local2)
-        }
-        Store(0x0A, DBGB)
-    }
-}
diff --git a/src/acpi-dsdt-hpet.dsl b/src/acpi-dsdt-hpet.dsl
deleted file mode 100644 (file)
index f33e527..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************
- * HPET
- ****************************************************************/
-
-Scope(\_SB) {
-    Device(HPET) {
-        Name(_HID, EISAID("PNP0103"))
-        Name(_UID, 0)
-        OperationRegion(HPTM, SystemMemory, 0xFED00000, 0x400)
-        Field(HPTM, DWordAcc, Lock, Preserve) {
-            VEND, 32,
-            PRD, 32,
-        }
-        Method(_STA, 0, NotSerialized) {
-            Store(VEND, Local0)
-            Store(PRD, Local1)
-            ShiftRight(Local0, 16, Local0)
-            If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
-                Return (0x0)
-            }
-            If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
-                Return (0x0)
-            }
-            Return (0x0F)
-        }
-        Name(_CRS, ResourceTemplate() {
-#if 0       /* This makes WinXP BSOD for not yet figured reasons. */
-            IRQNoFlags() {2, 8}
-#endif
-            Memory32Fixed(ReadOnly,
-                0xFED00000,         // Address Base
-                0x00000400,         // Address Length
-                )
-        })
-    }
-}
diff --git a/src/acpi-dsdt-isa.dsl b/src/acpi-dsdt-isa.dsl
deleted file mode 100644 (file)
index 23761db..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Common legacy ISA style devices. */
-Scope(\_SB.PCI0.ISA) {
-
-    Device(RTC) {
-        Name(_HID, EisaId("PNP0B00"))
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
-            IRQNoFlags() { 8 }
-            IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
-        })
-    }
-
-    Device(KBD) {
-        Name(_HID, EisaId("PNP0303"))
-        Method(_STA, 0, NotSerialized) {
-            Return (0x0f)
-        }
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
-            IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
-            IRQNoFlags() { 1 }
-        })
-    }
-
-    Device(MOU) {
-        Name(_HID, EisaId("PNP0F13"))
-        Method(_STA, 0, NotSerialized) {
-            Return (0x0f)
-        }
-        Name(_CRS, ResourceTemplate() {
-            IRQNoFlags() { 12 }
-        })
-    }
-
-    Device(FDC0) {
-        Name(_HID, EisaId("PNP0700"))
-        Method(_STA, 0, NotSerialized) {
-            Store(FDEN, Local0)
-            If (LEqual(Local0, 0)) {
-                Return (0x00)
-            } Else {
-                Return (0x0F)
-            }
-        }
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
-            IO(Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
-            IRQNoFlags() { 6 }
-            DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
-        })
-    }
-
-    Device(LPT) {
-        Name(_HID, EisaId("PNP0400"))
-        Method(_STA, 0, NotSerialized) {
-            Store(LPEN, Local0)
-            If (LEqual(Local0, 0)) {
-                Return (0x00)
-            } Else {
-                Return (0x0F)
-            }
-        }
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
-            IRQNoFlags() { 7 }
-        })
-    }
-
-    Device(COM1) {
-        Name(_HID, EisaId("PNP0501"))
-        Name(_UID, 0x01)
-        Method(_STA, 0, NotSerialized) {
-            Store(CAEN, Local0)
-            If (LEqual(Local0, 0)) {
-                Return (0x00)
-            } Else {
-                Return (0x0F)
-            }
-        }
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
-            IRQNoFlags() { 4 }
-        })
-    }
-
-    Device(COM2) {
-        Name(_HID, EisaId("PNP0501"))
-        Name(_UID, 0x02)
-        Method(_STA, 0, NotSerialized) {
-            Store(CBEN, Local0)
-            If (LEqual(Local0, 0)) {
-                Return (0x00)
-            } Else {
-                Return (0x0F)
-            }
-        }
-        Name(_CRS, ResourceTemplate() {
-            IO(Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
-            IRQNoFlags() { 3 }
-        })
-    }
-}
diff --git a/src/acpi-dsdt-pci-crs.dsl b/src/acpi-dsdt-pci-crs.dsl
deleted file mode 100644 (file)
index d421891..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* PCI CRS (current resources) definition. */
-Scope(\_SB.PCI0) {
-
-    Name(CRES, ResourceTemplate() {
-        WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
-            0x0000,             // Address Space Granularity
-            0x0000,             // Address Range Minimum
-            0x00FF,             // Address Range Maximum
-            0x0000,             // Address Translation Offset
-            0x0100,             // Address Length
-            ,, )
-        IO(Decode16,
-            0x0CF8,             // Address Range Minimum
-            0x0CF8,             // Address Range Maximum
-            0x01,               // Address Alignment
-            0x08,               // Address Length
-            )
-        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
-            0x0000,             // Address Space Granularity
-            0x0000,             // Address Range Minimum
-            0x0CF7,             // Address Range Maximum
-            0x0000,             // Address Translation Offset
-            0x0CF8,             // Address Length
-            ,, , TypeStatic)
-        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
-            0x0000,             // Address Space Granularity
-            0x0D00,             // Address Range Minimum
-            0xFFFF,             // Address Range Maximum
-            0x0000,             // Address Translation Offset
-            0xF300,             // Address Length
-            ,, , TypeStatic)
-        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
-            0x00000000,         // Address Space Granularity
-            0x000A0000,         // Address Range Minimum
-            0x000BFFFF,         // Address Range Maximum
-            0x00000000,         // Address Translation Offset
-            0x00020000,         // Address Length
-            ,, , AddressRangeMemory, TypeStatic)
-        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
-            0x00000000,         // Address Space Granularity
-            0xE0000000,         // Address Range Minimum
-            0xFEBFFFFF,         // Address Range Maximum
-            0x00000000,         // Address Translation Offset
-            0x1EC00000,         // Address Length
-            ,, PW32, AddressRangeMemory, TypeStatic)
-    })
-
-    Name(CR64, ResourceTemplate() {
-        QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
-            0x00000000,          // Address Space Granularity
-            0x8000000000,        // Address Range Minimum
-            0xFFFFFFFFFF,        // Address Range Maximum
-            0x00000000,          // Address Translation Offset
-            0x8000000000,        // Address Length
-            ,, PW64, AddressRangeMemory, TypeStatic)
-    })
-
-    Method(_CRS, 0) {
-        /* Fields provided by dynamically created ssdt */
-        External(P0S, IntObj)
-        External(P0E, IntObj)
-        External(P1V, IntObj)
-        External(P1S, BuffObj)
-        External(P1E, BuffObj)
-        External(P1L, BuffObj)
-
-        /* fixup 32bit pci io window */
-        CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32)
-        CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32)
-        CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32)
-        Store(P0S, PS32)
-        Store(P0E, PE32)
-        Store(Add(Subtract(P0E, P0S), 1), PL32)
-
-        If (LEqual(P1V, Zero)) {
-            Return (CRES)
-        }
-
-        /* fixup 64bit pci io window */
-        CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64)
-        CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64)
-        CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64)
-        Store(P1S, PS64)
-        Store(P1E, PE64)
-        Store(P1L, PL64)
-        /* add window and return result */
-        ConcatenateResTemplate(CRES, CR64, Local0)
-        Return (Local0)
-    }
-}
diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl
deleted file mode 100644 (file)
index 158f6b4..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Bochs/QEMU ACPI DSDT ASL definition
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-ACPI_EXTRACT_ALL_CODE AmlCode
-
-DefinitionBlock (
-    "acpi-dsdt.aml",    // Output Filename
-    "DSDT",             // Signature
-    0x01,               // DSDT Compliance Revision
-    "BXPC",             // OEMID
-    "BXDSDT",           // TABLE ID
-    0x1                 // OEM Revision
-    )
-{
-
-#include "acpi-dsdt-dbug.dsl"
-
-
-/****************************************************************
- * PCI Bus definition
- ****************************************************************/
-
-    Scope(\_SB) {
-        Device(PCI0) {
-            Name(_HID, EisaId("PNP0A03"))
-            Name(_ADR, 0x00)
-            Name(_UID, 1)
-        }
-    }
-
-#include "acpi-dsdt-pci-crs.dsl"
-#include "acpi-dsdt-hpet.dsl"
-
-
-/****************************************************************
- * VGA
- ****************************************************************/
-
-    Scope(\_SB.PCI0) {
-        Device(VGA) {
-            Name(_ADR, 0x00020000)
-            OperationRegion(PCIC, PCI_Config, Zero, 0x4)
-            Field(PCIC, DWordAcc, NoLock, Preserve) {
-                VEND, 32
-            }
-            Method(_S1D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S2D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S3D, 0, NotSerialized) {
-                If (LEqual(VEND, 0x1001b36)) {
-                    Return (0x03)           // QXL
-                } Else {
-                    Return (0x00)
-                }
-            }
-        }
-    }
-
-
-/****************************************************************
- * PIIX4 PM
- ****************************************************************/
-
-    Scope(\_SB.PCI0) {
-        Device(PX13) {
-            Name(_ADR, 0x00010003)
-            OperationRegion(P13C, PCI_Config, 0x00, 0xff)
-        }
-    }
-
-
-/****************************************************************
- * PIIX3 ISA bridge
- ****************************************************************/
-
-    Scope(\_SB.PCI0) {
-        Device(ISA) {
-            Name(_ADR, 0x00010000)
-
-            /* PIIX PCI to ISA irq remapping */
-            OperationRegion(P40C, PCI_Config, 0x60, 0x04)
-
-            /* enable bits */
-            Field(\_SB.PCI0.PX13.P13C, AnyAcc, NoLock, Preserve) {
-                Offset(0x5f),
-                , 7,
-                LPEN, 1,         // LPT
-                Offset(0x67),
-                , 3,
-                CAEN, 1,         // COM1
-                , 3,
-                CBEN, 1,         // COM2
-            }
-            Name(FDEN, 1)
-        }
-    }
-
-#include "acpi-dsdt-isa.dsl"
-
-
-/****************************************************************
- * PCI hotplug
- ****************************************************************/
-
-    Scope(\_SB.PCI0) {
-        OperationRegion(PCST, SystemIO, 0xae00, 0x08)
-        Field(PCST, DWordAcc, NoLock, WriteAsZeros) {
-            PCIU, 32,
-            PCID, 32,
-        }
-
-        OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
-        Field(SEJ, DWordAcc, NoLock, WriteAsZeros) {
-            B0EJ, 32,
-        }
-
-        /* Methods called by bulk generated PCI devices below */
-
-        /* Methods called by hotplug devices */
-        Method(PCEJ, 1, NotSerialized) {
-            // _EJ0 method - eject callback
-            Store(ShiftLeft(1, Arg0), B0EJ)
-            Return (0x0)
-        }
-
-        /* Hotplug notification method supplied by SSDT */
-        External(\_SB.PCI0.PCNT, MethodObj)
-
-        /* PCI hotplug notify method */
-        Method(PCNF, 0) {
-            // Local0 = iterator
-            Store(Zero, Local0)
-            While (LLess(Local0, 31)) {
-                Increment(Local0)
-                If (And(PCIU, ShiftLeft(1, Local0))) {
-                    PCNT(Local0, 1)
-                }
-                If (And(PCID, ShiftLeft(1, Local0))) {
-                    PCNT(Local0, 3)
-                }
-            }
-        }
-    }
-
-
-/****************************************************************
- * PCI IRQs
- ****************************************************************/
-
-    Scope(\_SB) {
-        Scope(PCI0) {
-            Name(_PRT, Package() {
-                /* PCI IRQ routing table, example from ACPI 2.0a specification,
-                   section 6.2.8.1 */
-                /* Note: we provide the same info as the PCI routing
-                   table of the Bochs BIOS */
-
-#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \
-    Package() { nr##ffff, 0, lnk0, 0 }, \
-    Package() { nr##ffff, 1, lnk1, 0 }, \
-    Package() { nr##ffff, 2, lnk2, 0 }, \
-    Package() { nr##ffff, 3, lnk3, 0 }
-
-#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC)
-#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD)
-#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA)
-#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB)
-
-                prt_slot0(0x0000),
-                /* Device 1 is power mgmt device, and can only use irq 9 */
-                prt_slot(0x0001, LNKS, LNKB, LNKC, LNKD),
-                prt_slot2(0x0002),
-                prt_slot3(0x0003),
-                prt_slot0(0x0004),
-                prt_slot1(0x0005),
-                prt_slot2(0x0006),
-                prt_slot3(0x0007),
-                prt_slot0(0x0008),
-                prt_slot1(0x0009),
-                prt_slot2(0x000a),
-                prt_slot3(0x000b),
-                prt_slot0(0x000c),
-                prt_slot1(0x000d),
-                prt_slot2(0x000e),
-                prt_slot3(0x000f),
-                prt_slot0(0x0010),
-                prt_slot1(0x0011),
-                prt_slot2(0x0012),
-                prt_slot3(0x0013),
-                prt_slot0(0x0014),
-                prt_slot1(0x0015),
-                prt_slot2(0x0016),
-                prt_slot3(0x0017),
-                prt_slot0(0x0018),
-                prt_slot1(0x0019),
-                prt_slot2(0x001a),
-                prt_slot3(0x001b),
-                prt_slot0(0x001c),
-                prt_slot1(0x001d),
-                prt_slot2(0x001e),
-                prt_slot3(0x001f),
-            })
-        }
-
-        Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) {
-            PRQ0,   8,
-            PRQ1,   8,
-            PRQ2,   8,
-            PRQ3,   8
-        }
-
-        Method(IQST, 1, NotSerialized) {
-            // _STA method - get status
-            If (And(0x80, Arg0)) {
-                Return (0x09)
-            }
-            Return (0x0B)
-        }
-        Method(IQCR, 1, NotSerialized) {
-            // _CRS method - get current settings
-            Name(PRR0, ResourceTemplate() {
-                Interrupt(, Level, ActiveHigh, Shared) { 0 }
-            })
-            CreateDWordField(PRR0, 0x05, PRRI)
-            If (LLess(Arg0, 0x80)) {
-                Store(Arg0, PRRI)
-            }
-            Return (PRR0)
-        }
-
-#define define_link(link, uid, reg)                             \
-        Device(link) {                                          \
-            Name(_HID, EISAID("PNP0C0F"))                       \
-            Name(_UID, uid)                                     \
-            Name(_PRS, ResourceTemplate() {                     \
-                Interrupt(, Level, ActiveHigh, Shared) {        \
-                    5, 10, 11                                   \
-                }                                               \
-            })                                                  \
-            Method(_STA, 0, NotSerialized) {                    \
-                Return (IQST(reg))                              \
-            }                                                   \
-            Method(_DIS, 0, NotSerialized) {                    \
-                Or(reg, 0x80, reg)                              \
-            }                                                   \
-            Method(_CRS, 0, NotSerialized) {                    \
-                Return (IQCR(reg))                              \
-            }                                                   \
-            Method(_SRS, 1, NotSerialized) {                    \
-                CreateDWordField(Arg0, 0x05, PRRI)              \
-                Store(PRRI, reg)                                \
-            }                                                   \
-        }
-
-        define_link(LNKA, 0, PRQ0)
-        define_link(LNKB, 1, PRQ1)
-        define_link(LNKC, 2, PRQ2)
-        define_link(LNKD, 3, PRQ3)
-
-        Device(LNKS) {
-            Name(_HID, EISAID("PNP0C0F"))
-            Name(_UID, 4)
-            Name(_PRS, ResourceTemplate() {
-                Interrupt(, Level, ActiveHigh, Shared) { 9 }
-            })
-
-            // The SCI cannot be disabled and is always attached to GSI 9,
-            // so these are no-ops.  We only need this link to override the
-            // polarity to active high and match the content of the MADT.
-            Method(_STA, 0, NotSerialized) { Return (0x0b) }
-            Method(_DIS, 0, NotSerialized) { }
-            Method(_CRS, 0, NotSerialized) { Return (_PRS) }
-            Method(_SRS, 1, NotSerialized) { }
-        }
-    }
-
-#include "acpi-dsdt-cpu-hotplug.dsl"
-
-
-/****************************************************************
- * General purpose events
- ****************************************************************/
-
-    Scope(\_GPE) {
-        Name(_HID, "ACPI0006")
-
-        Method(_L00) {
-        }
-        Method(_E01) {
-            // PCI hotplug event
-            \_SB.PCI0.PCNF()
-        }
-        Method(_E02) {
-            // CPU hotplug event
-            \_SB.PRSC()
-        }
-        Method(_L03) {
-        }
-        Method(_L04) {
-        }
-        Method(_L05) {
-        }
-        Method(_L06) {
-        }
-        Method(_L07) {
-        }
-        Method(_L08) {
-        }
-        Method(_L09) {
-        }
-        Method(_L0A) {
-        }
-        Method(_L0B) {
-        }
-        Method(_L0C) {
-        }
-        Method(_L0D) {
-        }
-        Method(_L0E) {
-        }
-        Method(_L0F) {
-        }
-    }
-}
diff --git a/src/acpi.c b/src/acpi.c
deleted file mode 100644 (file)
index 774ff95..0000000
+++ /dev/null
@@ -1,788 +0,0 @@
-// Support for generating ACPI tables (on emulators)
-//
-// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "acpi.h" // struct rsdp_descriptor
-#include "util.h" // memcpy
-#include "byteorder.h" // cpu_to_le16
-#include "hw/pci.h" // pci_find_init_device
-#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
-#include "hw/pci_regs.h" // PCI_INTERRUPT_LINE
-#include "ioport.h" // inl
-#include "config.h" // CONFIG_*
-#include "paravirt.h" // RamSize
-#include "dev-q35.h"
-
-#include "acpi-dsdt.hex"
-
-u32 acpi_pm1a_cnt VARFSEG;
-
-static void
-build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
-{
-    h->signature = cpu_to_le32(sig);
-    h->length = cpu_to_le32(len);
-    h->revision = rev;
-    memcpy(h->oem_id, BUILD_APPNAME6, 6);
-    memcpy(h->oem_table_id, BUILD_APPNAME4, 4);
-    memcpy(h->oem_table_id + 4, (void*)&sig, 4);
-    h->oem_revision = cpu_to_le32(1);
-    memcpy(h->asl_compiler_id, BUILD_APPNAME4, 4);
-    h->asl_compiler_revision = cpu_to_le32(1);
-    h->checksum -= checksum(h, len);
-}
-
-#define PIIX4_ACPI_ENABLE       0xf1
-#define PIIX4_ACPI_DISABLE      0xf0
-#define PIIX4_GPE0_BLK          0xafe0
-#define PIIX4_GPE0_BLK_LEN      4
-
-#define PIIX4_PM_INTRRUPT       9       // irq 9
-
-static void piix4_fadt_setup(struct pci_device *pci, void *arg)
-{
-    struct fadt_descriptor_rev1 *fadt = arg;
-
-    fadt->model = 1;
-    fadt->reserved1 = 0;
-    fadt->sci_int = cpu_to_le16(PIIX4_PM_INTRRUPT);
-    fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
-    fadt->acpi_enable = PIIX4_ACPI_ENABLE;
-    fadt->acpi_disable = PIIX4_ACPI_DISABLE;
-    fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
-    fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
-    fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
-    fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK);
-    fadt->pm1_evt_len = 4;
-    fadt->pm1_cnt_len = 2;
-    fadt->pm_tmr_len = 4;
-    fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN;
-    fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
-    fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
-    /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 + USE_PLATFORM_CLOCK */
-    fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7) |
-                              (1 << 15));
-}
-
-/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
-void ich9_lpc_fadt_setup(struct pci_device *dev, void *arg)
-{
-    struct fadt_descriptor_rev1 *fadt = arg;
-
-    fadt->model = 1;
-    fadt->reserved1 = 0;
-    fadt->sci_int = cpu_to_le16(9);
-    fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
-    fadt->acpi_enable = ICH9_ACPI_ENABLE;
-    fadt->acpi_disable = ICH9_ACPI_DISABLE;
-    fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
-    fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
-    fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
-    fadt->gpe0_blk = cpu_to_le32(PORT_ACPI_PM_BASE + ICH9_PMIO_GPE0_STS);
-    fadt->pm1_evt_len = 4;
-    fadt->pm1_cnt_len = 2;
-    fadt->pm_tmr_len = 4;
-    fadt->gpe0_blk_len = ICH9_PMIO_GPE0_BLK_LEN;
-    fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
-    fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
-    /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 + USE_PLATFORM_CLOCK */
-    fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7) |
-                              (1 << 15));
-}
-
-static const struct pci_device_id fadt_init_tbl[] = {
-    /* PIIX4 Power Management device (for ACPI) */
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
-               piix4_fadt_setup),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
-               ich9_lpc_fadt_setup),
-    PCI_DEVICE_END
-};
-
-static void fill_dsdt(struct fadt_descriptor_rev1 *fadt, void *dsdt)
-{
-    if (fadt->dsdt) {
-        free((void *)le32_to_cpu(fadt->dsdt));
-    }
-    fadt->dsdt = cpu_to_le32((u32)dsdt);
-    fadt->checksum -= checksum(fadt, sizeof(*fadt));
-    dprintf(1, "ACPI DSDT=%p\n", dsdt);
-}
-
-static void *
-build_fadt(struct pci_device *pci)
-{
-    struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
-    struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
-
-    if (!fadt || !facs) {
-        warn_noalloc();
-        return NULL;
-    }
-
-    /* FACS */
-    memset(facs, 0, sizeof(*facs));
-    facs->signature = cpu_to_le32(FACS_SIGNATURE);
-    facs->length = cpu_to_le32(sizeof(*facs));
-
-    /* FADT */
-    memset(fadt, 0, sizeof(*fadt));
-    fadt->firmware_ctrl = cpu_to_le32((u32)facs);
-    fadt->dsdt = 0;  /* dsdt will be filled later in acpi_setup()
-                        by fill_dsdt() */
-    pci_init_device(fadt_init_tbl, pci, fadt);
-
-    build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1);
-
-    return fadt;
-}
-
-static void*
-build_madt(void)
-{
-    int madt_size = (sizeof(struct multiple_apic_table)
-                     + sizeof(struct madt_processor_apic) * MaxCountCPUs
-                     + sizeof(struct madt_io_apic)
-                     + sizeof(struct madt_intsrcovr) * 16
-                     + sizeof(struct madt_local_nmi));
-
-    struct multiple_apic_table *madt = malloc_high(madt_size);
-    if (!madt) {
-        warn_noalloc();
-        return NULL;
-    }
-    memset(madt, 0, madt_size);
-    madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
-    madt->flags = cpu_to_le32(1);
-    struct madt_processor_apic *apic = (void*)&madt[1];
-    int i;
-    for (i=0; i<MaxCountCPUs; i++) {
-        apic->type = APIC_PROCESSOR;
-        apic->length = sizeof(*apic);
-        apic->processor_id = i;
-        apic->local_apic_id = i;
-        if (apic_id_is_present(apic->local_apic_id))
-            apic->flags = cpu_to_le32(1);
-        else
-            apic->flags = cpu_to_le32(0);
-        apic++;
-    }
-    struct madt_io_apic *io_apic = (void*)apic;
-    io_apic->type = APIC_IO;
-    io_apic->length = sizeof(*io_apic);
-    io_apic->io_apic_id = BUILD_IOAPIC_ID;
-    io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
-    io_apic->interrupt = cpu_to_le32(0);
-
-    struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1];
-    if (romfile_loadint("etc/irq0-override", 0)) {
-        memset(intsrcovr, 0, sizeof(*intsrcovr));
-        intsrcovr->type   = APIC_XRUPT_OVERRIDE;
-        intsrcovr->length = sizeof(*intsrcovr);
-        intsrcovr->source = 0;
-        intsrcovr->gsi    = cpu_to_le32(2);
-        intsrcovr->flags  = cpu_to_le16(0); /* conforms to bus specifications */
-        intsrcovr++;
-    }
-    for (i = 1; i < 16; i++) {
-        if (!(BUILD_PCI_IRQS & (1 << i)))
-            /* No need for a INT source override structure. */
-            continue;
-        memset(intsrcovr, 0, sizeof(*intsrcovr));
-        intsrcovr->type   = APIC_XRUPT_OVERRIDE;
-        intsrcovr->length = sizeof(*intsrcovr);
-        intsrcovr->source = i;
-        intsrcovr->gsi    = cpu_to_le32(i);
-        intsrcovr->flags  = cpu_to_le16(0xd); /* active high, level triggered */
-        intsrcovr++;
-    }
-
-    struct madt_local_nmi *local_nmi = (void*)intsrcovr;
-    local_nmi->type         = APIC_LOCAL_NMI;
-    local_nmi->length       = sizeof(*local_nmi);
-    local_nmi->processor_id = 0xff; /* all processors */
-    local_nmi->flags        = cpu_to_le16(0);
-    local_nmi->lint         = 1; /* LINT1 */
-    local_nmi++;
-
-    build_header((void*)madt, APIC_SIGNATURE, (void*)local_nmi - (void*)madt, 1);
-    return madt;
-}
-
-// Encode a hex value
-static inline char getHex(u32 val) {
-    val &= 0x0f;
-    return (val <= 9) ? ('0' + val) : ('A' + val - 10);
-}
-
-// Encode a length in an SSDT.
-static u8 *
-encodeLen(u8 *ssdt_ptr, int length, int bytes)
-{
-    switch (bytes) {
-    default:
-    case 4: ssdt_ptr[3] = ((length >> 20) & 0xff);
-    case 3: ssdt_ptr[2] = ((length >> 12) & 0xff);
-    case 2: ssdt_ptr[1] = ((length >> 4) & 0xff);
-            ssdt_ptr[0] = (((bytes-1) & 0x3) << 6) | (length & 0x0f);
-            break;
-    case 1: ssdt_ptr[0] = length & 0x3f;
-    }
-    return ssdt_ptr + bytes;
-}
-
-#include "ssdt-proc.hex"
-
-/* 0x5B 0x83 ProcessorOp PkgLength NameString ProcID */
-#define PROC_OFFSET_CPUHEX (*ssdt_proc_name - *ssdt_proc_start + 2)
-#define PROC_OFFSET_CPUID1 (*ssdt_proc_name - *ssdt_proc_start + 4)
-#define PROC_OFFSET_CPUID2 (*ssdt_proc_id - *ssdt_proc_start)
-#define PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
-#define PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
-
-/* 0x5B 0x82 DeviceOp PkgLength NameString */
-#define PCIHP_OFFSET_HEX (*ssdt_pcihp_name - *ssdt_pcihp_start + 1)
-#define PCIHP_OFFSET_ID (*ssdt_pcihp_id - *ssdt_pcihp_start)
-#define PCIHP_OFFSET_ADR (*ssdt_pcihp_adr - *ssdt_pcihp_start)
-#define PCIHP_OFFSET_EJ0 (*ssdt_pcihp_ej0 - *ssdt_pcihp_start)
-#define PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
-#define PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start)
-#define PCI_SLOTS 32
-
-#define SSDT_SIGNATURE 0x54445353 // SSDT
-#define SSDT_HEADER_LENGTH 36
-
-#include "ssdt-misc.hex"
-#include "ssdt-pcihp.hex"
-
-#define PCI_RMV_BASE 0xae0c
-
-static u8*
-build_notify(u8 *ssdt_ptr, const char *name, int skip, int count,
-             const char *target, int ofs)
-{
-    count -= skip;
-
-    *(ssdt_ptr++) = 0x14; // MethodOp
-    ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*count), 2);
-    memcpy(ssdt_ptr, name, 4);
-    ssdt_ptr += 4;
-    *(ssdt_ptr++) = 0x02; // MethodOp
-
-    int i;
-    for (i = skip; count-- > 0; i++) {
-        *(ssdt_ptr++) = 0xA0; // IfOp
-        ssdt_ptr = encodeLen(ssdt_ptr, 11, 1);
-        *(ssdt_ptr++) = 0x93; // LEqualOp
-        *(ssdt_ptr++) = 0x68; // Arg0Op
-        *(ssdt_ptr++) = 0x0A; // BytePrefix
-        *(ssdt_ptr++) = i;
-        *(ssdt_ptr++) = 0x86; // NotifyOp
-        memcpy(ssdt_ptr, target, 4);
-        ssdt_ptr[ofs] = getHex(i >> 4);
-        ssdt_ptr[ofs + 1] = getHex(i);
-        ssdt_ptr += 4;
-        *(ssdt_ptr++) = 0x69; // Arg1Op
-    }
-    return ssdt_ptr;
-}
-
-static void patch_pcihp(int slot, u8 *ssdt_ptr, u32 eject)
-{
-    ssdt_ptr[PCIHP_OFFSET_HEX] = getHex(slot >> 4);
-    ssdt_ptr[PCIHP_OFFSET_HEX+1] = getHex(slot);
-    ssdt_ptr[PCIHP_OFFSET_ID] = slot;
-    ssdt_ptr[PCIHP_OFFSET_ADR + 2] = slot;
-
-    /* Runtime patching of EJ0: to disable hotplug for a slot,
-     * replace the method name: _EJ0 by EJ0_. */
-    /* Sanity check */
-    if (memcmp(ssdt_ptr + PCIHP_OFFSET_EJ0, "_EJ0", 4)) {
-        warn_internalerror();
-    }
-    if (!eject) {
-        memcpy(ssdt_ptr + PCIHP_OFFSET_EJ0, "EJ0_", 4);
-    }
-}
-
-static void*
-build_ssdt(void)
-{
-    int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs;
-    int length = (sizeof(ssdp_misc_aml)                     // _S3_ / _S4_ / _S5_
-                  + (1+3+4)                                 // Scope(_SB_)
-                  + (acpi_cpus * PROC_SIZEOF)               // procs
-                  + (1+2+5+(12*acpi_cpus))                  // NTFY
-                  + (6+2+1+(1*acpi_cpus))                   // CPON
-                  + (1+3+4)                                 // Scope(PCI0)
-                  + ((PCI_SLOTS - 1) * PCIHP_SIZEOF)        // slots
-                  + (1+2+5+(12*(PCI_SLOTS - 1))));          // PCNT
-    u8 *ssdt = malloc_high(length);
-    if (! ssdt) {
-        warn_noalloc();
-        return NULL;
-    }
-    u8 *ssdt_ptr = ssdt;
-
-    // Copy header and encode fwcfg values in the S3_ / S4_ / S5_ packages
-    int sys_state_size;
-    char *sys_states = romfile_loadfile("etc/system-states", &sys_state_size);
-    if (!sys_states || sys_state_size != 6)
-        sys_states = (char[]){128, 0, 0, 129, 128, 128};
-
-    memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
-    if (!(sys_states[3] & 128))
-        ssdt_ptr[acpi_s3_name[0]] = 'X';
-    if (!(sys_states[4] & 128))
-        ssdt_ptr[acpi_s4_name[0]] = 'X';
-    else
-        ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 127;
-
-    // store pci io windows
-    *(u32*)&ssdt_ptr[acpi_pci32_start[0]] = cpu_to_le32(pcimem_start);
-    *(u32*)&ssdt_ptr[acpi_pci32_end[0]] = cpu_to_le32(pcimem_end - 1);
-    if (pcimem64_start) {
-        ssdt_ptr[acpi_pci64_valid[0]] = 1;
-        *(u64*)&ssdt_ptr[acpi_pci64_start[0]] = cpu_to_le64(pcimem64_start);
-        *(u64*)&ssdt_ptr[acpi_pci64_end[0]] = cpu_to_le64(pcimem64_end - 1);
-        *(u64*)&ssdt_ptr[acpi_pci64_length[0]] = cpu_to_le64(
-            pcimem64_end - pcimem64_start);
-    } else {
-        ssdt_ptr[acpi_pci64_valid[0]] = 0;
-    }
-
-    int pvpanic_port = romfile_loadint("etc/pvpanic-port", 0x0);
-    *(u16 *)(ssdt_ptr + *ssdt_isa_pest) = pvpanic_port;
-
-    ssdt_ptr += sizeof(ssdp_misc_aml);
-
-    // build Scope(_SB_) header
-    *(ssdt_ptr++) = 0x10; // ScopeOp
-    ssdt_ptr = encodeLen(ssdt_ptr, length - (ssdt_ptr - ssdt), 3);
-    *(ssdt_ptr++) = '_';
-    *(ssdt_ptr++) = 'S';
-    *(ssdt_ptr++) = 'B';
-    *(ssdt_ptr++) = '_';
-
-    // build Processor object for each processor
-    int i;
-    for (i=0; i<acpi_cpus; i++) {
-        memcpy(ssdt_ptr, PROC_AML, PROC_SIZEOF);
-        ssdt_ptr[PROC_OFFSET_CPUHEX] = getHex(i >> 4);
-        ssdt_ptr[PROC_OFFSET_CPUHEX+1] = getHex(i);
-        ssdt_ptr[PROC_OFFSET_CPUID1] = i;
-        ssdt_ptr[PROC_OFFSET_CPUID2] = i;
-        ssdt_ptr += PROC_SIZEOF;
-    }
-
-    // build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}"
-    // Arg0 = Processor ID = APIC ID
-    ssdt_ptr = build_notify(ssdt_ptr, "NTFY", 0, acpi_cpus, "CP00", 2);
-
-    // build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
-    *(ssdt_ptr++) = 0x08; // NameOp
-    *(ssdt_ptr++) = 'C';
-    *(ssdt_ptr++) = 'P';
-    *(ssdt_ptr++) = 'O';
-    *(ssdt_ptr++) = 'N';
-    *(ssdt_ptr++) = 0x12; // PackageOp
-    ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2);
-    *(ssdt_ptr++) = acpi_cpus;
-    for (i=0; i<acpi_cpus; i++)
-        *(ssdt_ptr++) = (apic_id_is_present(i)) ? 0x01 : 0x00;
-
-    // build Scope(PCI0) opcode
-    *(ssdt_ptr++) = 0x10; // ScopeOp
-    ssdt_ptr = encodeLen(ssdt_ptr, length - (ssdt_ptr - ssdt), 3);
-    *(ssdt_ptr++) = 'P';
-    *(ssdt_ptr++) = 'C';
-    *(ssdt_ptr++) = 'I';
-    *(ssdt_ptr++) = '0';
-
-    // build Device object for each slot
-    u32 rmvc_pcrm = inl(PCI_RMV_BASE);
-    for (i=1; i<PCI_SLOTS; i++) {
-        u32 eject = rmvc_pcrm & (0x1 << i);
-        memcpy(ssdt_ptr, PCIHP_AML, PCIHP_SIZEOF);
-        patch_pcihp(i, ssdt_ptr, eject != 0);
-        ssdt_ptr += PCIHP_SIZEOF;
-    }
-
-    ssdt_ptr = build_notify(ssdt_ptr, "PCNT", 1, PCI_SLOTS, "S00_", 1);
-
-    build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
-
-    //hexdump(ssdt, ssdt_ptr - ssdt);
-
-    return ssdt;
-}
-
-#define HPET_ID         0x000
-#define HPET_PERIOD     0x004
-
-static void*
-build_hpet(void)
-{
-    struct acpi_20_hpet *hpet;
-    const void *hpet_base = (void *)BUILD_HPET_ADDRESS;
-    u32 hpet_vendor = readl(hpet_base + HPET_ID) >> 16;
-    u32 hpet_period = readl(hpet_base + HPET_PERIOD);
-
-    if (hpet_vendor == 0 || hpet_vendor == 0xffff ||
-        hpet_period == 0 || hpet_period > 100000000)
-        return NULL;
-
-    hpet = malloc_high(sizeof(*hpet));
-    if (!hpet) {
-        warn_noalloc();
-        return NULL;
-    }
-
-    memset(hpet, 0, sizeof(*hpet));
-    /* Note timer_block_id value must be kept in sync with value advertised by
-     * emulated hpet
-     */
-    hpet->timer_block_id = cpu_to_le32(0x8086a201);
-    hpet->addr.address = cpu_to_le64(BUILD_HPET_ADDRESS);
-    build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1);
-
-    return hpet;
-}
-
-static void
-acpi_build_srat_memory(struct srat_memory_affinity *numamem,
-                       u64 base, u64 len, int node, int enabled)
-{
-    numamem->type = SRAT_MEMORY;
-    numamem->length = sizeof(*numamem);
-    memset(numamem->proximity, 0, 4);
-    numamem->proximity[0] = node;
-    numamem->flags = cpu_to_le32(!!enabled);
-    numamem->base_addr = cpu_to_le64(base);
-    numamem->range_length = cpu_to_le64(len);
-}
-
-static void *
-build_srat(void)
-{
-    int numadatasize, numacpusize;
-    u64 *numadata = romfile_loadfile("etc/numa-nodes", &numadatasize);
-    u64 *numacpumap = romfile_loadfile("etc/numa-cpu-map", &numacpusize);
-    if (!numadata || !numacpumap)
-        goto fail;
-    int max_cpu = numacpusize / sizeof(u64);
-    int nb_numa_nodes = numadatasize / sizeof(u64);
-
-    struct system_resource_affinity_table *srat;
-    int srat_size = sizeof(*srat) +
-        sizeof(struct srat_processor_affinity) * max_cpu +
-        sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
-
-    srat = malloc_high(srat_size);
-    if (!srat) {
-        warn_noalloc();
-        goto fail;
-    }
-
-    memset(srat, 0, srat_size);
-    srat->reserved1=cpu_to_le32(1);
-    struct srat_processor_affinity *core = (void*)(srat + 1);
-    int i;
-    u64 curnode;
-
-    for (i = 0; i < max_cpu; ++i) {
-        core->type = SRAT_PROCESSOR;
-        core->length = sizeof(*core);
-        core->local_apic_id = i;
-        curnode = *numacpumap++;
-        core->proximity_lo = curnode;
-        memset(core->proximity_hi, 0, 3);
-        core->local_sapic_eid = 0;
-        if (apic_id_is_present(i))
-            core->flags = cpu_to_le32(1);
-        else
-            core->flags = cpu_to_le32(0);
-        core++;
-    }
-
-
-    /* the memory map is a bit tricky, it contains at least one hole
-     * from 640k-1M and possibly another one from 3.5G-4G.
-     */
-    struct srat_memory_affinity *numamem = (void*)core;
-    int slots = 0;
-    u64 mem_len, mem_base, next_base = 0;
-
-    acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
-    next_base = 1024 * 1024;
-    numamem++;
-    slots++;
-    for (i = 1; i < nb_numa_nodes + 1; ++i) {
-        mem_base = next_base;
-        mem_len = *numadata++;
-        if (i == 1)
-            mem_len -= 1024 * 1024;
-        next_base = mem_base + mem_len;
-
-        /* Cut out the PCI hole */
-        if (mem_base <= RamSize && next_base > RamSize) {
-            mem_len -= next_base - RamSize;
-            if (mem_len > 0) {
-                acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
-                numamem++;
-                slots++;
-            }
-            mem_base = 1ULL << 32;
-            mem_len = next_base - RamSize;
-            next_base += (1ULL << 32) - RamSize;
-        }
-        acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
-        numamem++;
-        slots++;
-    }
-    for (; slots < nb_numa_nodes + 2; slots++) {
-        acpi_build_srat_memory(numamem, 0, 0, 0, 0);
-        numamem++;
-    }
-
-    build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1);
-
-    free(numadata);
-    free(numacpumap);
-    return srat;
-fail:
-    free(numadata);
-    free(numacpumap);
-    return NULL;
-}
-
-static void *
-build_mcfg_q35(void)
-{
-    struct acpi_table_mcfg *mcfg;
-
-    int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
-    mcfg = malloc_high(len);
-    if (!mcfg) {
-        warn_noalloc();
-        return NULL;
-    }
-    memset(mcfg, 0, len);
-    mcfg->allocation[0].address = cpu_to_le64(Q35_HOST_BRIDGE_PCIEXBAR_ADDR);
-    mcfg->allocation[0].pci_segment = cpu_to_le16(Q35_HOST_PCIE_PCI_SEGMENT);
-    mcfg->allocation[0].start_bus_number = Q35_HOST_PCIE_START_BUS_NUMBER;
-    mcfg->allocation[0].end_bus_number = Q35_HOST_PCIE_END_BUS_NUMBER;
-
-    build_header((void *)mcfg, MCFG_SIGNATURE, len, 1);
-    return mcfg;
-}
-
-static const struct pci_device_id acpi_find_tbl[] = {
-    /* PIIX4 Power Management device. */
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC, NULL),
-    PCI_DEVICE_END,
-};
-
-struct rsdp_descriptor *RsdpAddr;
-
-#define MAX_ACPI_TABLES 20
-void
-acpi_setup(void)
-{
-    if (! CONFIG_ACPI)
-        return;
-
-    dprintf(3, "init ACPI tables\n");
-
-    // This code is hardcoded for PIIX4 Power Management device.
-    struct pci_device *pci = pci_find_init_device(acpi_find_tbl, NULL);
-    if (!pci)
-        // Device not found
-        return;
-
-    // Build ACPI tables
-    u32 tables[MAX_ACPI_TABLES], tbl_idx = 0;
-
-#define ACPI_INIT_TABLE(X)                                   \
-    do {                                                     \
-        tables[tbl_idx] = cpu_to_le32((u32)(X));             \
-        if (le32_to_cpu(tables[tbl_idx]))                    \
-            tbl_idx++;                                       \
-    } while(0)
-
-    struct fadt_descriptor_rev1 *fadt = build_fadt(pci);
-    ACPI_INIT_TABLE(fadt);
-    ACPI_INIT_TABLE(build_ssdt());
-    ACPI_INIT_TABLE(build_madt());
-    ACPI_INIT_TABLE(build_hpet());
-    ACPI_INIT_TABLE(build_srat());
-    if (pci->device == PCI_DEVICE_ID_INTEL_ICH9_LPC)
-        ACPI_INIT_TABLE(build_mcfg_q35());
-
-    struct romfile_s *file = NULL;
-    for (;;) {
-        file = romfile_findprefix("acpi/", file);
-        if (!file)
-            break;
-        struct acpi_table_header *table = malloc_high(file->size);
-        if (!table) {
-            warn_noalloc();
-            continue;
-        }
-        int ret = file->copy(file, table, file->size);
-        if (ret <= sizeof(*table))
-            continue;
-        if (table->signature == DSDT_SIGNATURE) {
-            if (fadt) {
-                fill_dsdt(fadt, table);
-            }
-        } else {
-            ACPI_INIT_TABLE(table);
-        }
-        if (tbl_idx == MAX_ACPI_TABLES) {
-            warn_noalloc();
-            break;
-        }
-    }
-
-    if (CONFIG_ACPI_DSDT && fadt && !fadt->dsdt) {
-        /* default DSDT */
-        void *dsdt = malloc_high(sizeof(AmlCode));
-        if (!dsdt) {
-            warn_noalloc();
-            return;
-        }
-        memcpy(dsdt, AmlCode, sizeof(AmlCode));
-        fill_dsdt(fadt, dsdt);
-    }
-
-    // Build final rsdt table
-    struct rsdt_descriptor_rev1 *rsdt;
-    size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx;
-    rsdt = malloc_high(rsdt_len);
-    if (!rsdt) {
-        warn_noalloc();
-        return;
-    }
-    memset(rsdt, 0, rsdt_len);
-    memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx);
-    build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
-
-    // Build rsdp pointer table
-    struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
-    if (!rsdp) {
-        warn_noalloc();
-        return;
-    }
-    memset(rsdp, 0, sizeof(*rsdp));
-    rsdp->signature = cpu_to_le64(RSDP_SIGNATURE);
-    memcpy(rsdp->oem_id, BUILD_APPNAME6, 6);
-    rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt);
-    rsdp->checksum -= checksum(rsdp, 20);
-    RsdpAddr = rsdp;
-    dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt);
-}
-
-static struct fadt_descriptor_rev1 *
-find_fadt(void)
-{
-    dprintf(4, "rsdp=%p\n", RsdpAddr);
-    if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE)
-        return NULL;
-    struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address;
-    dprintf(4, "rsdt=%p\n", rsdt);
-    if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
-        return NULL;
-    void *end = (void*)rsdt + rsdt->length;
-    int i;
-    for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
-        struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i];
-        if (!fadt || fadt->signature != FACP_SIGNATURE)
-            continue;
-        dprintf(4, "fadt=%p\n", fadt);
-        return fadt;
-    }
-    dprintf(4, "no fadt found\n");
-    return NULL;
-}
-
-u32
-find_resume_vector(void)
-{
-    struct fadt_descriptor_rev1 *fadt = find_fadt();
-    if (!fadt)
-        return 0;
-    struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
-    dprintf(4, "facs=%p\n", facs);
-    if (! facs || facs->signature != FACS_SIGNATURE)
-        return 0;
-    // Found it.
-    dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector);
-    return facs->firmware_waking_vector;
-}
-
-void
-find_acpi_features(void)
-{
-    struct fadt_descriptor_rev1 *fadt = find_fadt();
-    if (!fadt)
-        return;
-    u32 pm_tmr = le32_to_cpu(fadt->pm_tmr_blk);
-    u32 pm1a_cnt = le32_to_cpu(fadt->pm1a_cnt_blk);
-    dprintf(4, "pm_tmr_blk=%x\n", pm_tmr);
-    if (pm_tmr)
-        pmtimer_setup(pm_tmr);
-    if (pm1a_cnt)
-        acpi_pm1a_cnt = pm1a_cnt;
-
-    // Theoretically we should check the 'reset_reg_sup' flag, but Windows
-    // doesn't and thus nobody seems to *set* it. If the table is large enough
-    // to include it, let the sanity checks in acpi_set_reset_reg() suffice.
-    if (fadt->length >= 129) {
-        void *p = fadt;
-        acpi_set_reset_reg(p + 116, *(u8 *)(p + 128));
-    }
-}
-
-static struct acpi_20_generic_address acpi_reset_reg;
-static u8 acpi_reset_val;
-
-void
-acpi_reboot(void)
-{
-    // Check it passed the sanity checks in acpi_set_reset_reg() and was set
-    if (acpi_reset_reg.register_bit_width != 8)
-        return;
-
-    u64 addr = le64_to_cpu(acpi_reset_reg.address);
-
-    dprintf(1, "ACPI hard reset %d:%llx (%x)\n",
-            acpi_reset_reg.address_space_id, addr, acpi_reset_val);
-
-    switch (acpi_reset_reg.address_space_id) {
-    case 0: // System Memory
-       writeb((void *)(u32)addr, acpi_reset_val);
-        break;
-    case 1: // System I/O
-        outb(acpi_reset_val, addr);
-        break;
-    case 2: // PCI config space
-        pci_config_writeb(acpi_ga_to_bdf(addr), addr & 0xffff, acpi_reset_val);
-        break;
-    }
-}
-
-void
-acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val)
-{
-    if (!reg || reg->address_space_id > 2 ||
-        reg->register_bit_width != 8 || reg->register_bit_offset)
-        return;
-
-    acpi_reset_reg = *reg;
-    acpi_reset_val = val;
-}
diff --git a/src/acpi.h b/src/acpi.h
deleted file mode 100644 (file)
index f0d24d4..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-#ifndef __ACPI_H
-#define __ACPI_H
-
-#include "types.h" // u32
-
-/*
- * ACPI 2.0 Generic Address Space definition.
- */
-struct acpi_20_generic_address {
-    u8  address_space_id;
-    u8  register_bit_width;
-    u8  register_bit_offset;
-    u8  reserved;
-    u64 address;
-} PACKED;
-#define acpi_ga_to_bdf(addr) pci_to_bdf(0, (addr >> 32) & 0xffff, (addr >> 16) & 0xffff)
-
-void acpi_setup(void);
-u32 find_resume_vector(void);
-void find_acpi_features(void);
-void acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val);
-void acpi_reboot(void);
-
-#define RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
-
-struct rsdp_descriptor {        /* Root System Descriptor Pointer */
-    u64 signature;              /* ACPI signature, contains "RSD PTR " */
-    u8  checksum;               /* To make sum of struct == 0 */
-    u8  oem_id [6];             /* OEM identification */
-    u8  revision;               /* Must be 0 for 1.0, 2 for 2.0 */
-    u32 rsdt_physical_address;  /* 32-bit physical address of RSDT */
-    u32 length;                 /* XSDT Length in bytes including hdr */
-    u64 xsdt_physical_address;  /* 64-bit physical address of XSDT */
-    u8  extended_checksum;      /* Checksum of entire table */
-    u8  reserved [3];           /* Reserved field must be 0 */
-};
-
-extern struct rsdp_descriptor *RsdpAddr;
-extern u32 acpi_pm1a_cnt;
-
-/* Table structure from Linux kernel (the ACPI tables are under the
-   BSD license) */
-
-#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
-    u32 signature;          /* ACPI signature (4 ASCII characters) */ \
-    u32 length;                 /* Length of table, in bytes, including header */ \
-    u8  revision;               /* ACPI Specification minor version # */ \
-    u8  checksum;               /* To make sum of entire table == 0 */ \
-    u8  oem_id [6];             /* OEM identification */ \
-    u8  oem_table_id [8];       /* OEM table identification */ \
-    u32 oem_revision;           /* OEM revision number */ \
-    u8  asl_compiler_id [4];    /* ASL compiler vendor ID */ \
-    u32 asl_compiler_revision;  /* ASL compiler revision number */
-
-
-/*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
- */
-#define FACP_SIGNATURE 0x50434146 // FACP
-struct fadt_descriptor_rev1
-{
-    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
-    u32 firmware_ctrl;          /* Physical address of FACS */
-    u32 dsdt;                   /* Physical address of DSDT */
-    u8  model;                  /* System Interrupt Model */
-    u8  reserved1;              /* Reserved */
-    u16 sci_int;                /* System vector of SCI interrupt */
-    u32 smi_cmd;                /* Port address of SMI command port */
-    u8  acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
-    u8  acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
-    u8  S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
-    u8  reserved2;              /* Reserved - must be zero */
-    u32 pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
-    u32 pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
-    u32 pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
-    u32 pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
-    u32 pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
-    u32 pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
-    u32 gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
-    u32 gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
-    u8  pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
-    u8  pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
-    u8  pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
-    u8  pm_tmr_len;             /* Byte Length of ports at pm_tm_blk */
-    u8  gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
-    u8  gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
-    u8  gpe1_base;              /* Offset in gpe model where gpe1 events start */
-    u8  reserved3;              /* Reserved */
-    u16 plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
-    u16 plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
-    u16 flush_size;             /* Size of area read to flush caches */
-    u16 flush_stride;           /* Stride used in flushing caches */
-    u8  duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
-    u8  duty_width;             /* Bit width of duty cycle field in p_cnt reg */
-    u8  day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
-    u8  mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
-    u8  century;                /* Index to century in RTC CMOS RAM */
-    u8  reserved4;              /* Reserved */
-    u8  reserved4a;             /* Reserved */
-    u8  reserved4b;             /* Reserved */
-    u32 flags;
-} PACKED;
-
-struct acpi_table_header         /* ACPI common table header */
-{
-    ACPI_TABLE_HEADER_DEF
-} PACKED;
-
-/*
- * ACPI 1.0 Root System Description Table (RSDT)
- */
-#define RSDT_SIGNATURE 0x54445352 // RSDT
-struct rsdt_descriptor_rev1
-{
-    ACPI_TABLE_HEADER_DEF       /* ACPI common table header */
-    u32 table_offset_entry[0];  /* Array of pointers to other */
-    /* ACPI tables */
-} PACKED;
-
-/*
- * ACPI 1.0 Firmware ACPI Control Structure (FACS)
- */
-#define FACS_SIGNATURE 0x53434146 // FACS
-struct facs_descriptor_rev1
-{
-    u32 signature;           /* ACPI Signature */
-    u32 length;                 /* Length of structure, in bytes */
-    u32 hardware_signature;     /* Hardware configuration signature */
-    u32 firmware_waking_vector; /* ACPI OS waking vector */
-    u32 global_lock;            /* Global Lock */
-    u32 flags;
-    u8  resverved3 [40];        /* Reserved - must be zero */
-} PACKED;
-
-/*
- * Differentiated System Description Table (DSDT)
- */
-#define DSDT_SIGNATURE 0x54445344 // DSDT
-
-/*
- * MADT values and structures
- */
-
-/* Values for MADT PCATCompat */
-
-#define DUAL_PIC                0
-#define MULTIPLE_APIC           1
-
-/* Master MADT */
-
-#define APIC_SIGNATURE 0x43495041 // APIC
-struct multiple_apic_table
-{
-    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
-    u32 local_apic_address;     /* Physical address of local APIC */
-    u32 flags;
-} PACKED;
-
-/* Values for Type in APIC sub-headers */
-
-#define APIC_PROCESSOR          0
-#define APIC_IO                 1
-#define APIC_XRUPT_OVERRIDE     2
-#define APIC_NMI                3
-#define APIC_LOCAL_NMI          4
-#define APIC_ADDRESS_OVERRIDE   5
-#define APIC_IO_SAPIC           6
-#define APIC_LOCAL_SAPIC        7
-#define APIC_XRUPT_SOURCE       8
-#define APIC_RESERVED           9           /* 9 and greater are reserved */
-
-/*
- * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
- */
-#define ACPI_SUB_HEADER_DEF   /* Common ACPI sub-structure header */\
-    u8  type;                               \
-    u8  length;
-
-/* Sub-structures for MADT */
-
-struct madt_processor_apic
-{
-    ACPI_SUB_HEADER_DEF
-    u8  processor_id;           /* ACPI processor id */
-    u8  local_apic_id;          /* Processor's local APIC id */
-    u32 flags;
-} PACKED;
-
-struct madt_io_apic
-{
-    ACPI_SUB_HEADER_DEF
-    u8  io_apic_id;             /* I/O APIC ID */
-    u8  reserved;               /* Reserved - must be zero */
-    u32 address;                /* APIC physical address */
-    u32 interrupt;              /* Global system interrupt where INTI
-                                 * lines start */
-} PACKED;
-
-struct madt_intsrcovr {
-    ACPI_SUB_HEADER_DEF
-    u8  bus;
-    u8  source;
-    u32 gsi;
-    u16 flags;
-} PACKED;
-
-struct madt_local_nmi {
-    ACPI_SUB_HEADER_DEF
-    u8  processor_id;           /* ACPI processor id */
-    u16 flags;                  /* MPS INTI flags */
-    u8  lint;                   /* Local APIC LINT# */
-} PACKED;
-
-/*
- * HPET Description Table
- */
-#define HPET_SIGNATURE 0x54455048 // HPET
-struct acpi_20_hpet {
-    ACPI_TABLE_HEADER_DEF                    /* ACPI common table header */
-    u32           timer_block_id;
-    struct acpi_20_generic_address addr;
-    u8            hpet_number;
-    u16           min_tick;
-    u8            page_protect;
-} PACKED;
-
-/*
- * SRAT (NUMA topology description) table
- */
-
-#define SRAT_SIGNATURE 0x54415253 // SRAT
-struct system_resource_affinity_table
-{
-    ACPI_TABLE_HEADER_DEF
-    u32    reserved1;
-    u32    reserved2[2];
-} PACKED;
-
-#define SRAT_PROCESSOR          0
-#define SRAT_MEMORY             1
-
-struct srat_processor_affinity
-{
-    ACPI_SUB_HEADER_DEF
-    u8     proximity_lo;
-    u8     local_apic_id;
-    u32    flags;
-    u8     local_sapic_eid;
-    u8     proximity_hi[3];
-    u32    reserved;
-} PACKED;
-
-struct srat_memory_affinity
-{
-    ACPI_SUB_HEADER_DEF
-    u8     proximity[4];
-    u16    reserved1;
-    u64    base_addr;
-    u64    range_length;
-    u32    reserved2;
-    u32    flags;
-    u32    reserved3[2];
-} PACKED;
-
-/* PCI fw r3.0 MCFG table. */
-/* Subtable */
-struct acpi_mcfg_allocation {
-    u64 address;                /* Base address, processor-relative */
-    u16 pci_segment;            /* PCI segment group number */
-    u8 start_bus_number;       /* Starting PCI Bus number */
-    u8 end_bus_number;         /* Final PCI Bus number */
-    u32 reserved;
-} PACKED;
-
-#define MCFG_SIGNATURE 0x4746434d       // MCFG
-struct acpi_table_mcfg {
-    ACPI_TABLE_HEADER_DEF;
-    u8 reserved[8];
-    struct acpi_mcfg_allocation allocation[0];
-} PACKED;
-
-#endif // acpi.h
index de6bd997968aee68e94a9db2bcd6123dee15f6e4..211424c25c636634bbb753048e480043eb4dd2e1 100644 (file)
--- a/src/apm.c
+++ b/src/apm.c
@@ -11,8 +11,8 @@
 #include "util.h" // dprintf
 #include "config.h" // CONFIG_*
 #include "biosvar.h" // GET_GLOBAL
-#include "paravirt.h" // runningOnQEMU
-#include "acpi.h" // acpi_pm_ctl
+#include "fw/paravirt.h" // runningOnQEMU
+#include "fw/acpi.h" // acpi_pm_ctl
 
 static void
 out_str(const char *str_cs)
diff --git a/src/biostables.c b/src/biostables.c
deleted file mode 100644 (file)
index beb0bed..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-// Coreboot interface support.
-//
-// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "config.h" // CONFIG_*
-#include "util.h" // dprintf
-#include "hw/pci.h" // struct pir_header
-#include "acpi.h" // struct rsdp_descriptor
-#include "mptable.h" // MPTABLE_SIGNATURE
-#include "smbios.h" // struct smbios_entry_point
-
-static void
-copy_pir(void *pos)
-{
-    struct pir_header *p = pos;
-    if (p->signature != PIR_SIGNATURE)
-        return;
-    if (PirAddr)
-        return;
-    if (p->size < sizeof(*p))
-        return;
-    if (checksum(pos, p->size) != 0)
-        return;
-    void *newpos = malloc_fseg(p->size);
-    if (!newpos) {
-        warn_noalloc();
-        return;
-    }
-    dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
-    memcpy(newpos, pos, p->size);
-    PirAddr = newpos;
-}
-
-static void
-copy_mptable(void *pos)
-{
-    struct mptable_floating_s *p = pos;
-    if (p->signature != MPTABLE_SIGNATURE)
-        return;
-    if (!p->physaddr)
-        return;
-    if (checksum(pos, sizeof(*p)) != 0)
-        return;
-    u32 length = p->length * 16;
-    u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
-    struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
-    if (!newpos) {
-        warn_noalloc();
-        return;
-    }
-    dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
-    memcpy(newpos, pos, length);
-    newpos->physaddr = (u32)newpos + length;
-    newpos->checksum -= checksum(newpos, sizeof(*newpos));
-    memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
-}
-
-static void
-copy_acpi_rsdp(void *pos)
-{
-    if (RsdpAddr)
-        return;
-    struct rsdp_descriptor *p = pos;
-    if (p->signature != RSDP_SIGNATURE)
-        return;
-    u32 length = 20;
-    if (checksum(pos, length) != 0)
-        return;
-    if (p->revision > 1) {
-        length = p->length;
-        if (checksum(pos, length) != 0)
-            return;
-    }
-    void *newpos = malloc_fseg(length);
-    if (!newpos) {
-        warn_noalloc();
-        return;
-    }
-    dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
-    memcpy(newpos, pos, length);
-    RsdpAddr = newpos;
-}
-
-void
-copy_smbios(void *pos)
-{
-    if (SMBiosAddr)
-        return;
-    struct smbios_entry_point *p = pos;
-    if (memcmp(p->anchor_string, "_SM_", 4))
-        return;
-    if (checksum(pos, 0x10) != 0)
-        return;
-    if (memcmp(p->intermediate_anchor_string, "_DMI_", 5))
-        return;
-    if (checksum(pos+0x10, p->length-0x10) != 0)
-        return;
-    struct smbios_entry_point *newpos = malloc_fseg(p->length);
-    if (!newpos) {
-        warn_noalloc();
-        return;
-    }
-    dprintf(1, "Copying SMBIOS entry point from %p to %p\n", pos, newpos);
-    memcpy(newpos, pos, p->length);
-    SMBiosAddr = newpos;
-}
-
-void
-copy_table(void *pos)
-{
-    copy_pir(pos);
-    copy_mptable(pos);
-    copy_acpi_rsdp(pos);
-    copy_smbios(pos);
-}
index 4d8f1613bed4edbe4a552f5730220c61891ee1a4..bbe9155ff88c04399380e4950227dd8e1baede28 100644 (file)
 #include "bregs.h" // struct bregs
 #include "boot.h" // func defs
 #include "hw/cmos.h" // inb_cmos
-#include "paravirt.h" // qemu_cfg_show_boot_menu
+#include "fw/paravirt.h" // qemu_cfg_show_boot_menu
 #include "hw/pci.h" // pci_bdf_to_*
 #include "hw/usb.h" // struct usbdevice_s
-#include "csm.h" // csm_bootprio_*
+#include "fw/csm.h" // csm_bootprio_*
 #include "list.h" // hlist_node
 
 
index 84fca7f01577675ae4ca18ddc2114ead7627408b..bd91102fbeeab467c3ed85c2a0e04c80aaf538c3 100644 (file)
@@ -12,7 +12,7 @@
 #include "jpeg.h" // splash
 #include "vbe.h" // struct vbe_info
 #include "bmp.h" // bmp_alloc
-#include "smbios.h" // display_uuid
+#include "fw/smbios.h" // display_uuid
 
 
 /****************************************************************
diff --git a/src/coreboot.c b/src/coreboot.c
deleted file mode 100644 (file)
index 126649a..0000000
+++ /dev/null
@@ -1,501 +0,0 @@
-// Coreboot interface support.
-//
-// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "memmap.h" // add_e820
-#include "util.h" // dprintf
-#include "byteorder.h" // be32_to_cpu
-#include "lzmadecode.h" // LzmaDecode
-#include "smbios.h" // smbios_init
-#include "boot.h" // boot_add_cbfs
-#include "disk.h" // MAXDESCSIZE
-#include "config.h" // CONFIG_*
-#include "acpi.h" // find_acpi_features
-#include "hw/pci.h" // pci_probe_devices
-#include "paravirt.h" // PlatformRunningOn
-
-
-/****************************************************************
- * Memory map
- ****************************************************************/
-
-struct cb_header {
-    u32 signature;
-    u32 header_bytes;
-    u32 header_checksum;
-    u32 table_bytes;
-    u32 table_checksum;
-    u32 table_entries;
-};
-
-#define CB_SIGNATURE 0x4f49424C // "LBIO"
-
-struct cb_memory_range {
-    u64 start;
-    u64 size;
-    u32 type;
-};
-
-#define CB_MEM_TABLE    16
-
-struct cb_memory {
-    u32 tag;
-    u32 size;
-    struct cb_memory_range map[0];
-};
-
-#define CB_TAG_MEMORY 0x01
-
-#define MEM_RANGE_COUNT(_rec) \
-        (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))
-
-struct cb_mainboard {
-    u32 tag;
-    u32 size;
-    u8  vendor_idx;
-    u8  part_idx;
-    char  strings[0];
-};
-
-#define CB_TAG_MAINBOARD 0x0003
-
-struct cb_forward {
-    u32 tag;
-    u32 size;
-    u64 forward;
-};
-
-#define CB_TAG_FORWARD 0x11
-
-struct cb_cbmem_ref {
-    u32 tag;
-    u32 size;
-    u64 cbmem_addr;
-};
-
-#define CB_TAG_CBMEM_CONSOLE 0x17
-
-struct cbmem_console {
-       u32 buffer_size;
-       u32 buffer_cursor;
-       u8  buffer_body[0];
-} PACKED;
-static struct cbmem_console *cbcon = NULL;
-
-static u16
-ipchksum(char *buf, int count)
-{
-    u16 *p = (u16*)buf;
-    u32 sum = 0;
-    while (count > 1) {
-        sum += *p++;
-        count -= 2;
-    }
-    if (count)
-        sum += *(u8*)p;
-    sum = (sum >> 16) + (sum & 0xffff);
-    sum += (sum >> 16);
-    return ~sum;
-}
-
-// Try to locate the coreboot header in a given address range.
-static struct cb_header *
-find_cb_header(char *addr, int len)
-{
-    char *end = addr + len;
-    for (; addr < end; addr += 16) {
-        struct cb_header *cbh = (struct cb_header *)addr;
-        if (cbh->signature != CB_SIGNATURE)
-            continue;
-        if (! cbh->table_bytes)
-            continue;
-        if (ipchksum(addr, sizeof(*cbh)) != 0)
-            continue;
-        if (ipchksum(addr + sizeof(*cbh), cbh->table_bytes)
-            != cbh->table_checksum)
-            continue;
-        return cbh;
-    }
-    return NULL;
-}
-
-// Try to find the coreboot memory table in the given coreboot table.
-static void *
-find_cb_subtable(struct cb_header *cbh, u32 tag)
-{
-    char *tbl = (char *)cbh + sizeof(*cbh);
-    int i;
-    for (i=0; i<cbh->table_entries; i++) {
-        struct cb_memory *cbm = (struct cb_memory *)tbl;
-        tbl += cbm->size;
-        if (cbm->tag == tag)
-            return cbm;
-    }
-    return NULL;
-}
-
-static struct cb_memory *CBMemTable;
-const char *CBvendor = "", *CBpart = "";
-
-// Populate max ram and e820 map info by scanning for a coreboot table.
-void
-coreboot_preinit(void)
-{
-    if (!CONFIG_COREBOOT)
-        return;
-
-    dprintf(3, "Attempting to find coreboot table\n");
-
-    // Find coreboot table.
-    struct cb_header *cbh = find_cb_header(0, 0x1000);
-    if (!cbh)
-        goto fail;
-    struct cb_forward *cbf = find_cb_subtable(cbh, CB_TAG_FORWARD);
-    if (cbf) {
-        dprintf(3, "Found coreboot table forwarder.\n");
-        cbh = find_cb_header((char *)((u32)cbf->forward), 0x100);
-        if (!cbh)
-            goto fail;
-    }
-    dprintf(3, "Now attempting to find coreboot memory map\n");
-    struct cb_memory *cbm = CBMemTable = find_cb_subtable(cbh, CB_TAG_MEMORY);
-    if (!cbm)
-        goto fail;
-
-    int i, count = MEM_RANGE_COUNT(cbm);
-    for (i=0; i<count; i++) {
-        struct cb_memory_range *m = &cbm->map[i];
-        u32 type = m->type;
-        if (type == CB_MEM_TABLE)
-            type = E820_RESERVED;
-        add_e820(m->start, m->size, type);
-    }
-
-    // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this
-    // confuses grub.  So, override it.
-    add_e820(0, 16*1024, E820_RAM);
-
-    struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, CB_TAG_CBMEM_CONSOLE);
-    if (cbref) {
-        cbcon = (void*)(u32)cbref->cbmem_addr;
-        dprintf(1, "----- [ seabios log starts here ] -----\n");
-        dprintf(1, "Found coreboot cbmem console @ %llx\n", cbref->cbmem_addr);
-    }
-
-    struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD);
-    if (cbmb) {
-        CBvendor = &cbmb->strings[cbmb->vendor_idx];
-        CBpart = &cbmb->strings[cbmb->part_idx];
-        if (strcmp(CBvendor, "Emulation") == 0 &&
-            memcmp(CBpart, "QEMU", 4) == 0) {
-            PlatformRunningOn |= PF_QEMU;
-        }
-        dprintf(1, "Found mainboard %s %s\n", CBvendor, CBpart);
-    }
-
-    return;
-
-fail:
-    // No table found..  Use 16Megs as a dummy value.
-    dprintf(1, "Unable to find coreboot table!\n");
-    add_e820(0, 16*1024*1024, E820_RAM);
-    return;
-}
-
-void debug_cbmem(char c)
-{
-    if (!CONFIG_DEBUG_COREBOOT)
-        return;
-    if (!cbcon)
-        return;
-    if (cbcon->buffer_cursor == cbcon->buffer_size)
-        return;
-    cbcon->buffer_body[cbcon->buffer_cursor++] = c;
-}
-
-/****************************************************************
- * BIOS table copying
- ****************************************************************/
-
-// Attempt to find (and relocate) any standard bios tables found in a
-// given address range.
-static void
-scan_tables(u32 start, u32 size)
-{
-    void *p = (void*)ALIGN(start, 16);
-    void *end = (void*)start + size;
-    for (; p<end; p += 16)
-        copy_table(p);
-}
-
-void
-coreboot_platform_setup(void)
-{
-    if (!CONFIG_COREBOOT)
-        return;
-    pci_probe_devices();
-
-    struct cb_memory *cbm = CBMemTable;
-    if (!cbm)
-        return;
-
-    dprintf(3, "Relocating coreboot bios tables\n");
-
-    // Scan CB_MEM_TABLE areas for bios tables.
-    int i, count = MEM_RANGE_COUNT(cbm);
-    for (i=0; i<count; i++) {
-        struct cb_memory_range *m = &cbm->map[i];
-        if (m->type == CB_MEM_TABLE)
-            scan_tables(m->start, m->size);
-    }
-
-    find_acpi_features();
-}
-
-
-/****************************************************************
- * ulzma
- ****************************************************************/
-
-// Uncompress data in flash to an area of memory.
-static int
-ulzma(u8 *dst, u32 maxlen, const u8 *src, u32 srclen)
-{
-    dprintf(3, "Uncompressing data %d@%p to %d@%p\n", srclen, src, maxlen, dst);
-    CLzmaDecoderState state;
-    int ret = LzmaDecodeProperties(&state.Properties, src, LZMA_PROPERTIES_SIZE);
-    if (ret != LZMA_RESULT_OK) {
-        dprintf(1, "LzmaDecodeProperties error - %d\n", ret);
-        return -1;
-    }
-    u8 scratch[15980];
-    int need = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
-    if (need > sizeof(scratch)) {
-        dprintf(1, "LzmaDecode need %d have %d\n", need, (unsigned int)sizeof(scratch));
-        return -1;
-    }
-    state.Probs = (CProb *)scratch;
-
-    u32 dstlen = *(u32*)(src + LZMA_PROPERTIES_SIZE);
-    if (dstlen > maxlen) {
-        dprintf(1, "LzmaDecode too large (max %d need %d)\n", maxlen, dstlen);
-        return -1;
-    }
-    u32 inProcessed, outProcessed;
-    ret = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, srclen
-                     , &inProcessed, dst, dstlen, &outProcessed);
-    if (ret) {
-        dprintf(1, "LzmaDecode returned %d\n", ret);
-        return -1;
-    }
-    return dstlen;
-}
-
-
-/****************************************************************
- * Coreboot flash format
- ****************************************************************/
-
-#define CBFS_HEADER_MAGIC 0x4F524243
-#define CBFS_HEADPTR_ADDR 0xFFFFFFFc
-#define CBFS_VERSION1 0x31313131
-
-struct cbfs_header {
-    u32 magic;
-    u32 version;
-    u32 romsize;
-    u32 bootblocksize;
-    u32 align;
-    u32 offset;
-    u32 pad[2];
-} PACKED;
-
-#define CBFS_FILE_MAGIC 0x455649484352414cLL // LARCHIVE
-
-struct cbfs_file {
-    u64 magic;
-    u32 len;
-    u32 type;
-    u32 checksum;
-    u32 offset;
-    char filename[0];
-} PACKED;
-
-struct cbfs_romfile_s {
-    struct romfile_s file;
-    struct cbfs_file *fhdr;
-    void *data;
-    u32 rawsize, flags;
-};
-
-// Copy a file to memory (uncompressing if necessary)
-static int
-cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen)
-{
-    if (!CONFIG_COREBOOT_FLASH)
-        return -1;
-
-    struct cbfs_romfile_s *cfile;
-    cfile = container_of(file, struct cbfs_romfile_s, file);
-    u32 size = cfile->rawsize;
-    void *src = cfile->data;
-    if (cfile->flags) {
-        // Compressed - copy to temp ram and uncompress it.
-        void *temp = malloc_tmphigh(size);
-        if (!temp) {
-            warn_noalloc();
-            return -1;
-        }
-        iomemcpy(temp, src, size);
-        int ret = ulzma(dst, maxlen, temp, size);
-        yield();
-        free(temp);
-        return ret;
-    }
-
-    // Not compressed.
-    dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst);
-    if (size > maxlen) {
-        warn_noalloc();
-        return -1;
-    }
-    iomemcpy(dst, src, size);
-    return size;
-}
-
-void
-coreboot_cbfs_init(void)
-{
-    if (!CONFIG_COREBOOT_FLASH)
-        return;
-
-    struct cbfs_header *hdr = *(void **)CBFS_HEADPTR_ADDR;
-    if (hdr->magic != cpu_to_be32(CBFS_HEADER_MAGIC)) {
-        dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n"
-                , hdr, hdr->magic, cpu_to_be32(CBFS_HEADER_MAGIC));
-        return;
-    }
-    dprintf(1, "Found CBFS header at %p\n", hdr);
-
-    struct cbfs_file *fhdr = (void *)(0 - be32_to_cpu(hdr->romsize)
-                                      + be32_to_cpu(hdr->offset));
-    for (;;) {
-        if (fhdr < (struct cbfs_file *)(0xFFFFFFFF - be32_to_cpu(hdr->romsize)))
-            break;
-        u64 magic = fhdr->magic;
-        if (magic != CBFS_FILE_MAGIC)
-            break;
-        struct cbfs_romfile_s *cfile = malloc_tmp(sizeof(*cfile));
-        if (!cfile) {
-            warn_noalloc();
-            break;
-        }
-        memset(cfile, 0, sizeof(*cfile));
-        strtcpy(cfile->file.name, fhdr->filename, sizeof(cfile->file.name));
-        cfile->file.size = cfile->rawsize = be32_to_cpu(fhdr->len);
-        cfile->fhdr = fhdr;
-        cfile->file.copy = cbfs_copyfile;
-        cfile->data = (void*)fhdr + be32_to_cpu(fhdr->offset);
-        int len = strlen(cfile->file.name);
-        if (len > 5 && strcmp(&cfile->file.name[len-5], ".lzma") == 0) {
-            // Using compression.
-            cfile->flags = 1;
-            cfile->file.name[len-5] = '\0';
-            cfile->file.size = *(u32*)(cfile->data + LZMA_PROPERTIES_SIZE);
-        }
-        romfile_add(&cfile->file);
-
-        fhdr = (void*)ALIGN((u32)cfile->data + cfile->rawsize
-                            , be32_to_cpu(hdr->align));
-    }
-}
-
-struct cbfs_payload_segment {
-    u32 type;
-    u32 compression;
-    u32 offset;
-    u64 load_addr;
-    u32 len;
-    u32 mem_len;
-} PACKED;
-
-#define PAYLOAD_SEGMENT_BSS    0x20535342
-#define PAYLOAD_SEGMENT_ENTRY  0x52544E45
-
-#define CBFS_COMPRESS_NONE  0
-#define CBFS_COMPRESS_LZMA  1
-
-struct cbfs_payload {
-    struct cbfs_payload_segment segments[1];
-};
-
-void
-cbfs_run_payload(struct cbfs_file *fhdr)
-{
-    if (!CONFIG_COREBOOT_FLASH || !fhdr)
-        return;
-    dprintf(1, "Run %s\n", fhdr->filename);
-    struct cbfs_payload *pay = (void*)fhdr + be32_to_cpu(fhdr->offset);
-    struct cbfs_payload_segment *seg = pay->segments;
-    for (;;) {
-        void *src = (void*)pay + be32_to_cpu(seg->offset);
-        void *dest = (void*)(u32)be64_to_cpu(seg->load_addr);
-        u32 src_len = be32_to_cpu(seg->len);
-        u32 dest_len = be32_to_cpu(seg->mem_len);
-        switch (seg->type) {
-        case PAYLOAD_SEGMENT_BSS:
-            dprintf(3, "BSS segment %d@%p\n", dest_len, dest);
-            memset(dest, 0, dest_len);
-            break;
-        case PAYLOAD_SEGMENT_ENTRY: {
-            dprintf(1, "Calling addr %p\n", dest);
-            void (*func)() = dest;
-            func();
-            return;
-        }
-        default:
-            dprintf(3, "Segment %x %d@%p -> %d@%p\n"
-                    , seg->type, src_len, src, dest_len, dest);
-            if (seg->compression == cpu_to_be32(CBFS_COMPRESS_NONE)) {
-                if (src_len > dest_len)
-                    src_len = dest_len;
-                memcpy(dest, src, src_len);
-            } else if (CONFIG_LZMA
-                       && seg->compression == cpu_to_be32(CBFS_COMPRESS_LZMA)) {
-                int ret = ulzma(dest, dest_len, src, src_len);
-                if (ret < 0)
-                    return;
-                src_len = ret;
-            } else {
-                dprintf(1, "No support for compression type %x\n"
-                        , seg->compression);
-                return;
-            }
-            if (dest_len > src_len)
-                memset(dest + src_len, 0, dest_len - src_len);
-            break;
-        }
-        seg++;
-    }
-}
-
-// Register payloads in "img/" directory with boot system.
-void
-cbfs_payload_setup(void)
-{
-    if (!CONFIG_COREBOOT_FLASH)
-        return;
-    struct romfile_s *file = NULL;
-    for (;;) {
-        file = romfile_findprefix("img/", file);
-        if (!file)
-            break;
-        struct cbfs_romfile_s *cfile;
-        cfile = container_of(file, struct cbfs_romfile_s, file);
-        const char *filename = file->name;
-        char *desc = znprintf(MAXDESCSIZE, "Payload [%s]", &filename[4]);
-        boot_add_cbfs(cfile->fhdr, desc, bootprio_find_named_rom(filename, 0));
-    }
-}
diff --git a/src/csm.c b/src/csm.c
deleted file mode 100644 (file)
index 0093bee..0000000
--- a/src/csm.c
+++ /dev/null
@@ -1,330 +0,0 @@
-// Compatibility Support Module (CSM) for UEFI / EDK-II
-//
-// Copyright Â© 2013 Intel Corporation
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "config.h" // CONFIG_*
-#include "csm.h"
-#include "util.h" // checksum
-#include "bregs.h"
-#include "optionroms.h"
-#include "hw/pci.h"
-#include "memmap.h"
-#include "biosvar.h"
-#include "post.h"
-#include "acpi.h"
-#include "boot.h"
-#include "smbios.h"
-#include "hw/pic.h"
-
-struct rsdp_descriptor csm_rsdp VARFSEG __aligned(16);
-
-EFI_COMPATIBILITY16_TABLE csm_compat_table VARFSEG __aligned(16) = {
-    .Signature = 0x24454649,
-    .TableChecksum = 0 /* Filled in by checkrom.py */,
-    .TableLength = sizeof(csm_compat_table),
-    .Compatibility16CallSegment = SEG_BIOS,
-    .Compatibility16CallOffset = 0 /* Filled in by checkrom.py */,
-    .OemIdStringPointer = (u32)"SeaBIOS",
-    .AcpiRsdPtrPointer = (u32)&csm_rsdp,
-};
-
-EFI_TO_COMPATIBILITY16_INIT_TABLE *csm_init_table;
-EFI_TO_COMPATIBILITY16_BOOT_TABLE *csm_boot_table;
-
-static u16 PICMask = PIC_IRQMASK_DEFAULT;
-
-extern void __csm_return(struct bregs *regs) __noreturn;
-
-static void
-csm_return(struct bregs *regs)
-{
-    dprintf(3, "handle_csm returning AX=%04x\n", regs->ax);
-
-    PICMask = pic_irqmask_read();
-    __csm_return(regs);
-}
-
-static void
-csm_maininit(struct bregs *regs)
-{
-    interface_init();
-    pci_probe_devices();
-
-    csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS;
-    csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();
-
-    regs->ax = 0;
-
-    csm_return(regs);
-}
-
-/* Legacy16InitializeYourself */
-static void
-handle_csm_0000(struct bregs *regs)
-{
-    dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es,
-            regs->bx);
-
-    csm_init_table = MAKE_FLATPTR(regs->es, regs->bx);
-
-    dprintf(3, "BiosLessThan1MB %08x\n", csm_init_table->BiosLessThan1MB);
-    dprintf(3, "HiPmmMemory     %08x\n", csm_init_table->HiPmmMemory);
-    dprintf(3, "HiPmmMemorySize %08x\n", csm_init_table->HiPmmMemorySizeInBytes);
-    dprintf(3, "ReverseThunk    %04x:%04x\n", csm_init_table->ReverseThunkCallSegment,
-            csm_init_table->ReverseThunkCallOffset);
-    dprintf(3, "NumE820Entries  %08x\n", csm_init_table->NumberE820Entries);
-    dprintf(3, "OsMemoryAbove1M %08x\n", csm_init_table->OsMemoryAbove1Mb);
-    dprintf(3, "ThunkStart      %08x\n", csm_init_table->ThunkStart);
-    dprintf(3, "ThunkSize       %08x\n", csm_init_table->ThunkSizeInBytes);
-    dprintf(3, "LoPmmMemory     %08x\n", csm_init_table->LowPmmMemory);
-    dprintf(3, "LoPmmMemorySize %08x\n", csm_init_table->LowPmmMemorySizeInBytes);
-
-    csm_malloc_preinit(csm_init_table->LowPmmMemory,
-                       csm_init_table->LowPmmMemorySizeInBytes,
-                       csm_init_table->HiPmmMemory,
-                       csm_init_table->HiPmmMemorySizeInBytes);
-    reloc_preinit(csm_maininit, regs);
-}
-
-/* Legacy16UpdateBbs */
-static void
-handle_csm_0001(struct bregs *regs)
-{
-    if (!CONFIG_BOOT) {
-        regs->ax = 1;
-        return;
-    }
-
-    dprintf(3, "Legacy16UpdateBbs table %04x:%04x\n", regs->es, regs->bx);
-
-    csm_boot_table = MAKE_FLATPTR(regs->es, regs->bx);
-    dprintf(3, "MajorVersion %04x\n", csm_boot_table->MajorVersion);
-    dprintf(3, "MinorVersion %04x\n", csm_boot_table->MinorVersion);
-    dprintf(3, "AcpiTable %08x\n", csm_boot_table->AcpiTable);
-    dprintf(3, "SmbiosTable %08x\n", csm_boot_table->SmbiosTable);
-    dprintf(3, "SmbiosTableLength %08x\n", csm_boot_table->SmbiosTableLength);
-//    dprintf(3, "SioData %08x\n", csm_boot_table->SioData);
-    dprintf(3, "DevicePathType %04x\n", csm_boot_table->DevicePathType);
-    dprintf(3, "PciIrqMask %04x\n", csm_boot_table->PciIrqMask);
-    dprintf(3, "NumberE820Entries %08x\n", csm_boot_table->NumberE820Entries);
-//    dprintf(3, "HddInfo %08x\n", csm_boot_table->HddInfo);
-    dprintf(3, "NumberBbsEntries %08x\n", csm_boot_table->NumberBbsEntries);
-    dprintf(3, "BBsTable %08x\n", csm_boot_table->BbsTable);
-    dprintf(3, "SmmTable %08x\n", csm_boot_table->SmmTable);
-    dprintf(3, "OsMemoryAbove1Mb %08x\n", csm_boot_table->OsMemoryAbove1Mb);
-    dprintf(3, "UnconventionalDeviceTable %08x\n", csm_boot_table->UnconventionalDeviceTable);
-
-    regs->ax = 0;
-}
-
-/* PrepareToBoot */
-static void
-handle_csm_0002(struct bregs *regs)
-{
-    if (!CONFIG_BOOT) {
-        regs->ax = 1;
-        return;
-    }
-
-    dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx);
-
-    struct e820entry *p = (void *)csm_compat_table.E820Pointer;
-    int i;
-    for (i=0; i < csm_compat_table.E820Length / sizeof(struct e820entry); i++)
-        add_e820(p[i].start, p[i].size, p[i].type);
-
-    if (csm_init_table->HiPmmMemorySizeInBytes > BUILD_MAX_HIGHTABLE) {
-        u32 hi_pmm_end = csm_init_table->HiPmmMemory + csm_init_table->HiPmmMemorySizeInBytes;
-        add_e820(hi_pmm_end - BUILD_MAX_HIGHTABLE, BUILD_MAX_HIGHTABLE, E820_RESERVED);
-    }
-
-    // For PCIBIOS 1ab10e
-    if (csm_compat_table.IrqRoutingTablePointer &&
-        csm_compat_table.IrqRoutingTableLength) {
-        PirAddr = (void *)csm_compat_table.IrqRoutingTablePointer;
-        dprintf(3, "CSM PIRQ table at %p\n", PirAddr);
-    }
-
-    // For find_resume_vector()... and find_acpi_features()
-    if (csm_rsdp.signature == RSDP_SIGNATURE) {
-        RsdpAddr = &csm_rsdp;
-        dprintf(3, "CSM ACPI RSDP at %p\n", RsdpAddr);
-
-        find_acpi_features();
-    }
-
-    // SMBIOS table needs to be copied into the f-seg
-    // XX: OVMF doesn't seem to set SmbiosTableLength so don't check it
-    if (csm_boot_table->SmbiosTable && !SMBiosAddr)
-        copy_smbios((void *)csm_boot_table->SmbiosTable);
-
-    // MPTABLE is just there; we don't care where.
-
-    // EFI may have reinitialised the video using its *own* driver.
-    enable_vga_console();
-
-    // EFI fills this in for us. Zero it for now...
-    struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0);
-    bda->hdcount = 0;
-
-    mathcp_setup();
-    timer_setup();
-    clock_setup();
-    device_hardware_setup();
-    wait_threads();
-    interactive_bootmenu();
-
-    prepareboot();
-
-    regs->ax = 0;
-}
-
-/* Boot */
-static void
-handle_csm_0003(struct bregs *regs)
-{
-    if (!CONFIG_BOOT) {
-        regs->ax = 1;
-        return;
-    }
-
-    dprintf(3, "Boot\n");
-
-    startBoot();
-
-    regs->ax = 1;
-}
-
-/* Legacy16DispatchOprom */
-static void
-handle_csm_0005(struct bregs *regs)
-{
-    EFI_DISPATCH_OPROM_TABLE *table = MAKE_FLATPTR(regs->es, regs->bx);
-    struct rom_header *rom;
-    u16 bdf;
-
-    if (!CONFIG_OPTIONROMS) {
-        regs->ax = 1;
-        return;
-    }
-
-    dprintf(3, "Legacy16DispatchOprom rom %p\n", table);
-
-    dprintf(3, "OpromSegment   %04x\n", table->OpromSegment);
-    dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment);
-    dprintf(3, "PnPInstallationCheck %04x:%04x\n",
-            table->PnPInstallationCheckSegment,
-            table->PnPInstallationCheckOffset);
-    dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment);
-
-    rom = MAKE_FLATPTR(table->OpromSegment, 0);
-    bdf = pci_bus_devfn_to_bdf(table->PciBus, table->PciDeviceFunction);
-
-    rom_reserve(rom->size * 512);
-
-    // XX PnP seg/ofs should never be other than default
-    callrom(rom, bdf);
-
-    rom_confirm(rom->size * 512);
-
-    regs->bx = 0; // FIXME
-    regs->ax = 0;
-}
-
-/* Legacy16GetTableAddress */
-static void
-handle_csm_0006(struct bregs *regs)
-{
-    u16 size = regs->cx;
-    u16 align = regs->dx;
-    u16 region = regs->bx; // (1 for F000 seg, 2 for E000 seg, 0 for either)
-    void *chunk = NULL;
-
-    if (!region)
-        region = 3;
-
-    dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n",
-        size, align, region);
-
-    if (region & 2)
-        chunk = pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align);
-    if (!chunk && (region & 1))
-        chunk = pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, align);
-
-    dprintf(3, "Legacy16GetTableAddress size %x align %x region %d yields %p\n",
-        size, align, region, chunk);
-    if (chunk) {
-        regs->ds = FLATPTR_TO_SEG(chunk);
-        regs->bx = FLATPTR_TO_OFFSET(chunk);
-        regs->ax = 0;
-    } else {
-        regs->ax = 1;
-    }
-}
-
-void VISIBLE32INIT
-handle_csm(struct bregs *regs)
-{
-    ASSERT32FLAT();
-
-    if (!CONFIG_CSM)
-        return;
-
-    dprintf(3, "handle_csm regs %p AX=%04x\n", regs, regs->ax);
-
-    pic_irqmask_write(PICMask);
-
-    switch(regs->ax) {
-    case 0000: handle_csm_0000(regs); break;
-    case 0001: handle_csm_0001(regs); break;
-    case 0002: handle_csm_0002(regs); break;
-    case 0003: handle_csm_0003(regs); break;
-//    case 0004: handle_csm_0004(regs); break;
-    case 0005: handle_csm_0005(regs); break;
-    case 0006: handle_csm_0006(regs); break;
-//    case 0007: handle_csm_0007(regs); break;
-//    case 0008: hamdle_csm_0008(regs); break;
-    default: regs->al = 1;
-    }
-
-    csm_return(regs);
-}
-
-int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave)
-{
-    if (!csm_boot_table)
-        return -1;
-    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
-    int index = 1 + (chanid * 2) + slave;
-    dprintf(3, "CSM bootprio for ATA%d,%d (index %d) is %d\n", chanid, slave,
-            index, bbs[index].BootPriority);
-    return bbs[index].BootPriority;
-}
-
-int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid)
-{
-    if (!csm_boot_table)
-        return -1;
-    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
-    dprintf(3, "CSM bootprio for FDC is %d\n", bbs[0].BootPriority);
-    return bbs[0].BootPriority;
-}
-
-int csm_bootprio_pci(struct pci_device *pci)
-{
-    if (!csm_boot_table)
-        return -1;
-    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
-    int i;
-
-    for (i = 5; i < csm_boot_table->NumberBbsEntries; i++) {
-        if (pci->bdf == pci_to_bdf(bbs[i].Bus, bbs[i].Device, bbs[i].Function)) {
-            dprintf(3, "CSM bootprio for PCI(%d,%d,%d) is %d\n", bbs[i].Bus,
-                    bbs[i].Device, bbs[i].Function, bbs[i].BootPriority);
-            return bbs[i].BootPriority;
-        }
-    }
-    return -1;
-}
diff --git a/src/csm.h b/src/csm.h
deleted file mode 100644 (file)
index 997e3f7..0000000
--- a/src/csm.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __CSM_H
-#define __CSM_H
-
-#include "types.h"
-
-#define UINT8 u8
-#define UINT16 u16
-#define UINT32 u32
-
-// csm.c
-struct pci_device;
-int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid);
-int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave);
-int csm_bootprio_pci(struct pci_device *pci);
-
-#include "LegacyBios.h"
-
-#endif // __CSM_H
diff --git a/src/dev-q35.h b/src/dev-q35.h
deleted file mode 100644 (file)
index 6ae039f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __DEV_Q35_H
-#define __DEV_Q35_H
-
-#include "types.h"      // u16
-
-#define PCI_DEVICE_ID_INTEL_Q35_MCH     0x29c0
-#define Q35_HOST_BRIDGE_PAM0            0x90
-#define Q35_HOST_BRIDGE_SMRAM           0x9d
-#define Q35_HOST_BRIDGE_PCIEXBAR        0x60
-#define Q35_HOST_BRIDGE_PCIEXBAR_SIZE   (256 * 1024 * 1024)
-#define Q35_HOST_BRIDGE_PCIEXBAR_ADDR   0xb0000000
-#define Q35_HOST_BRIDGE_PCIEXBAREN      ((u64)1)
-#define Q35_HOST_PCIE_PCI_SEGMENT       0
-#define Q35_HOST_PCIE_START_BUS_NUMBER  0
-#define Q35_HOST_PCIE_END_BUS_NUMBER    255
-
-#define PCI_DEVICE_ID_INTEL_ICH9_LPC    0x2918
-#define ICH9_LPC_PMBASE                 0x40
-#define ICH9_LPC_PMBASE_RTE             0x1
-
-#define ICH9_LPC_ACPI_CTRL             0x44
-#define ICH9_LPC_ACPI_CTRL_ACPI_EN     0x80
-#define ICH9_LPC_PIRQA_ROUT            0x60
-#define ICH9_LPC_PIRQE_ROUT            0x68
-#define ICH9_LPC_PIRQ_ROUT_IRQEN       0x80
-#define ICH9_LPC_PORT_ELCR1            0x4d0
-#define ICH9_LPC_PORT_ELCR2            0x4d1
-#define PCI_DEVICE_ID_INTEL_ICH9_SMBUS 0x2930
-#define ICH9_SMB_SMB_BASE              0x20
-#define ICH9_SMB_HOSTC                 0x40
-#define ICH9_SMB_HOSTC_HST_EN          0x01
-
-#define ICH9_ACPI_ENABLE               0x2
-#define ICH9_ACPI_DISABLE              0x3
-
-/* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */
-#define ICH9_PMIO_GPE0_STS             0x20
-#define ICH9_PMIO_GPE0_BLK_LEN         0x10
-#define ICH9_PMIO_SMI_EN               0x30
-#define ICH9_PMIO_SMI_EN_APMC_EN       (1 << 5)
-
-/* FADT ACPI_ENABLE/ACPI_DISABLE */
-#define ICH9_APM_ACPI_ENABLE           0x2
-#define ICH9_APM_ACPI_DISABLE          0x3
-
-#endif // dev-q35.h
diff --git a/src/fw/LegacyBios.h b/src/fw/LegacyBios.h
new file mode 100644 (file)
index 0000000..cf0c3c5
--- /dev/null
@@ -0,0 +1,965 @@
+/** @file
+  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage
+  under EFI and Legacy OS boot.  This file also includes all the related
+  COMPATIBILIY16 structures and defintions.
+
+  Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow
+  well known naming conventions.
+
+  Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode
+       environment. Reverse thunk is the code that does the opposite.
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.                                          
+    
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  This protocol is defined in Framework for EFI Compatibility Support Module spec
+  Version 0.97.
+
+**/
+
+#ifndef _EFI_LEGACY_BIOS_H_
+#define _EFI_LEGACY_BIOS_H_
+
+///
+/// 
+///
+#pragma pack(1)
+
+typedef UINT8                       SERIAL_MODE;
+typedef UINT8                       PARALLEL_MODE;
+
+#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$')
+
+///
+/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx
+/// physical address range. It is located on a 16-byte boundary and provides the physical address of the
+/// entry point for the Compatibility16 functions. These functions provide the platform-specific
+/// information that is required by the generic EfiCompatibility code. The functions are invoked via
+/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical
+/// entry point.
+///
+typedef struct {
+  ///
+  /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte
+  /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32.
+  ///
+  UINT32                            Signature;
+  
+  ///
+  /// The value required such that byte checksum of TableLength equals zero.
+  ///
+  UINT8                             TableChecksum;
+  
+  ///
+  /// The length of this table.
+  ///
+  UINT8                             TableLength;
+  
+  ///
+  /// The major EFI revision for which this table was generated.
+  /// 
+  UINT8                             EfiMajorRevision;
+  
+  ///
+  /// The minor EFI revision for which this table was generated.
+  ///
+  UINT8                             EfiMinorRevision;
+  
+  ///
+  /// The major revision of this table.
+  ///
+  UINT8                             TableMajorRevision;
+  
+  ///
+  /// The minor revision of this table.
+  ///
+  UINT8                             TableMinorRevision;
+  
+  ///
+  /// Reserved for future usage.
+  ///
+  UINT16                            Reserved;
+  
+  ///
+  /// The segment of the entry point within the traditional BIOS for Compatibility16 functions.
+  ///
+  UINT16                            Compatibility16CallSegment;
+  
+  ///
+  /// The offset of the entry point within the traditional BIOS for Compatibility16 functions.
+  ///
+  UINT16                            Compatibility16CallOffset;
+  
+  ///
+  /// The segment of the entry point within the traditional BIOS for EfiCompatibility 
+  /// to invoke the PnP installation check.
+  ///
+  UINT16                            PnPInstallationCheckSegment;
+  
+  ///
+  /// The Offset of the entry point within the traditional BIOS for EfiCompatibility 
+  /// to invoke the PnP installation check.
+  ///
+  UINT16                            PnPInstallationCheckOffset;
+  
+  ///
+  /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform 
+  ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS).
+  ///
+  UINT32                            EfiSystemTable; 
+  
+  ///
+  /// The address of an OEM-provided identifier string. The string is null terminated.
+  ///
+  UINT32                            OemIdStringPointer;
+  
+  ///
+  /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional
+  /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size
+  /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI
+  /// RSD PTR with either the ACPI 1.0b or 2.0 values.
+  ///
+  UINT32                            AcpiRsdPtrPointer;
+  
+  ///
+  /// The OEM revision number. Usage is undefined but provided for OEM module usage.
+  ///
+  UINT16                            OemRevision;
+  
+  ///
+  /// The 32-bit physical address where INT15 E820 data is stored within the traditional
+  /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the
+  /// data to the indicated area.
+  ///
+  UINT32                            E820Pointer;
+  
+  ///
+  /// The length of the E820 data and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            E820Length;
+  
+  ///
+  /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS.
+  /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and
+  /// copy the data to the indicated area.
+  ///
+  UINT32                            IrqRoutingTablePointer;
+  
+  ///
+  /// The length of the $PIR table and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            IrqRoutingTableLength;
+  
+  ///
+  /// The 32-bit physical address where the MP table is stored in the traditional BIOS.
+  /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data 
+  /// to the indicated area.
+  ///
+  UINT32                            MpTablePtr;
+  
+  ///
+  /// The length of the MP table and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            MpTableLength;
+  
+  ///
+  /// The segment of the OEM-specific INT table/code.
+  /// 
+  UINT16                            OemIntSegment;
+  
+  ///
+  /// The offset of the OEM-specific INT table/code.
+  ///
+  UINT16                            OemIntOffset;
+  
+  ///
+  /// The segment of the OEM-specific 32-bit table/code.
+  ///
+  UINT16                            Oem32Segment;
+  
+  ///
+  /// The offset of the OEM-specific 32-bit table/code.
+  ///
+  UINT16                            Oem32Offset;
+  
+  ///
+  /// The segment of the OEM-specific 16-bit table/code.
+  ///
+  UINT16                            Oem16Segment;
+  
+  ///
+  /// The offset of the OEM-specific 16-bit table/code.
+  ///
+  UINT16                            Oem16Offset;
+  
+  ///
+  /// The segment of the TPM binary passed to 16-bit CSM.
+  ///
+  UINT16                            TpmSegment;
+  
+  ///
+  /// The offset of the TPM binary passed to 16-bit CSM.
+  ///
+  UINT16                            TpmOffset;
+  
+  ///
+  /// A pointer to a string identifying the independent BIOS vendor.
+  ///
+  UINT32                            IbvPointer;
+  
+  ///
+  /// This field is NULL for all systems not supporting PCI Express. This field is the base
+  /// value of the start of the PCI Express memory-mapped configuration registers and
+  /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function
+  /// Compatibility16InitializeYourself().
+  /// Compatibility16InitializeYourself() is defined in Compatability16
+  /// Functions.
+  ///
+  UINT32                            PciExpressBase;
+  
+  ///
+  /// Maximum PCI bus number assigned.
+  ///
+  UINT8                             LastPciBus;
+} EFI_COMPATIBILITY16_TABLE;
+
+///
+/// Functions provided by the CSM binary which communicate between the EfiCompatibility 
+/// and Compatability16 code.
+///
+/// Inconsistent with the specification here: 
+/// The member's name started with "Compatibility16" [defined in Intel Framework 
+/// Compatibility Support Module Specification / 0.97 version] 
+/// has been changed to "Legacy16" since keeping backward compatible.
+///
+typedef enum {
+  ///
+  /// Causes the Compatibility16 code to do any internal initialization required.
+  /// Input:
+  ///   AX = Compatibility16InitializeYourself
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE
+  /// Return:
+  ///   AX = Return Status codes
+  ///
+  Legacy16InitializeYourself    = 0x0000,
+  
+  ///
+  /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence.
+  /// Input:
+  ///   AX = Compatibility16UpdateBbs
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
+  /// Return:
+  ///   AX = Returned status codes
+  ///
+  Legacy16UpdateBbs             = 0x0001,
+  
+  ///
+  /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16
+  /// code is read/write.
+  /// Input:
+  ///   AX = Compatibility16PrepareToBoot
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure  
+  /// Return:
+  ///   AX = Returned status codes
+  ///
+  Legacy16PrepareToBoot         = 0x0002,
+  
+  ///
+  /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only.
+  /// Input:
+  ///   AX = Compatibility16Boot
+  /// Output:
+  ///   AX = Returned status codes
+  ///
+  Legacy16Boot                  = 0x0003,
+  
+  ///
+  /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is
+  /// stored in CMOS and is the priority number of the last attempted boot device.
+  /// Input:
+  ///   AX = Compatibility16RetrieveLastBootDevice
+  /// Output:
+  ///   AX = Returned status codes
+  ///   BX = Priority number of the boot device.
+  ///
+  Legacy16RetrieveLastBootDevice = 0x0004,
+  
+  ///
+  /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM.
+  /// Input:
+  ///   AX = Compatibility16DispatchOprom
+  ///   ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE
+  /// Output:
+  ///   AX = Returned status codes
+  ///   BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant.
+  ///
+  Legacy16DispatchOprom         = 0x0005,
+  
+  ///
+  /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address
+  /// of that region.
+  /// Input:
+  ///   AX = Compatibility16GetTableAddress
+  ///   BX = Allocation region
+  ///       00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.
+  ///       Bit 0 = 1 Allocate from 0xF0000 64 KB block
+  ///       Bit 1 = 1 Allocate from 0xE0000 64 KB block
+  ///   CX = Requested length in bytes.
+  ///   DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment.
+  /// Output:
+  ///   AX = Returned status codes
+  ///   DS:BX = Address of the region
+  ///
+  Legacy16GetTableAddress       = 0x0006,
+  
+  ///
+  /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state.
+  /// Input:
+  ///   AX = Compatibility16SetKeyboardLeds
+  ///   CL = LED status.
+  ///     Bit 0  Scroll Lock 0 = Off
+  ///     Bit 1  NumLock
+  ///     Bit 2  Caps Lock
+  /// Output:
+  ///     AX = Returned status codes
+  ///
+  Legacy16SetKeyboardLeds       = 0x0007,
+  
+  ///
+  /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that
+  /// do not have an OpROM associated with them. An example is SATA.
+  /// Input:
+  ///   AX = Compatibility16InstallPciHandler
+  ///   ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure
+  /// Output:
+  ///   AX = Returned status codes
+  ///
+  Legacy16InstallPciHandler     = 0x0008
+} EFI_COMPATIBILITY_FUNCTIONS;
+
+
+///
+/// EFI_DISPATCH_OPROM_TABLE
+///
+typedef struct {
+  UINT16  PnPInstallationCheckSegment;  ///< A pointer to the PnpInstallationCheck data structure.
+  UINT16  PnPInstallationCheckOffset;   ///< A pointer to the PnpInstallationCheck data structure.
+  UINT16  OpromSegment;                 ///< The segment where the OpROM was placed. Offset is assumed to be 3.
+  UINT8   PciBus;                       ///< The PCI bus.
+  UINT8   PciDeviceFunction;            ///< The PCI device * 0x08 | PCI function.
+  UINT8   NumberBbsEntries;             ///< The number of valid BBS table entries upon entry and exit. The IBV code may
+                                        ///< increase this number, if BBS-compliant devices also hook INTs in order to force the
+                                        ///< OpROM BIOS Setup to be executed.
+  UINT32  BbsTablePointer;              ///< A pointer to the BBS table.
+  UINT16  RuntimeSegment;               ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this
+                                        ///< means that the relocation of this run time code is not supported.
+                                        ///< Inconsistent with specification here: 
+                                        ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version] 
+                                        ///< has been changed to "RuntimeSegment" since keeping backward compatible.
+
+} EFI_DISPATCH_OPROM_TABLE;
+
+///
+/// EFI_TO_COMPATIBILITY16_INIT_TABLE
+///
+typedef struct {
+  ///
+  /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF.
+  ///
+  UINT32                            BiosLessThan1MB;
+  
+  ///
+  /// The starting address of the high memory block.
+  ///
+  UINT32                            HiPmmMemory;
+  
+  ///
+  /// The length of high memory block.
+  ///
+  UINT32                            HiPmmMemorySizeInBytes;
+  
+  ///
+  /// The segment of the reverse thunk call code.
+  ///
+  UINT16                            ReverseThunkCallSegment;
+  
+  ///
+  /// The offset of the reverse thunk call code.
+  ///
+  UINT16                            ReverseThunkCallOffset;
+  
+  ///
+  /// The number of E820 entries copied to the Compatibility16 BIOS.
+  ///
+  UINT32                            NumberE820Entries;
+  
+  ///
+  /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory.
+  ///
+  UINT32                            OsMemoryAbove1Mb;
+  
+  ///
+  /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM.
+  ///
+  UINT32                            ThunkStart;
+  
+  ///
+  /// The size of the thunk code.
+  ///
+  UINT32                            ThunkSizeInBytes;
+  
+  ///
+  /// Starting address of memory under 1 MB.
+  ///
+  UINT32                            LowPmmMemory;
+  
+  ///
+  /// The length of low Memory block.
+  ///
+  UINT32                            LowPmmMemorySizeInBytes;
+} EFI_TO_COMPATIBILITY16_INIT_TABLE;
+
+///
+/// DEVICE_PRODUCER_SERIAL.
+///
+typedef struct {
+  UINT16                            Address;    ///< I/O address assigned to the serial port.
+  UINT8                             Irq;        ///< IRQ assigned to the serial port.
+  SERIAL_MODE                       Mode;       ///< Mode of serial port. Values are defined below.
+} DEVICE_PRODUCER_SERIAL;
+
+///
+/// DEVICE_PRODUCER_SERIAL's modes.
+///@{
+#define DEVICE_SERIAL_MODE_NORMAL               0x00
+#define DEVICE_SERIAL_MODE_IRDA                 0x01
+#define DEVICE_SERIAL_MODE_ASK_IR               0x02
+#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00
+#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10
+///@)
+
+///
+/// DEVICE_PRODUCER_PARALLEL.
+///
+typedef struct {
+  UINT16                            Address;  ///< I/O address assigned to the parallel port.
+  UINT8                             Irq;      ///< IRQ assigned to the parallel port.
+  UINT8                             Dma;      ///< DMA assigned to the parallel port.
+  PARALLEL_MODE                     Mode;     ///< Mode of the parallel port. Values are defined below.
+} DEVICE_PRODUCER_PARALLEL;
+
+///
+/// DEVICE_PRODUCER_PARALLEL's modes.
+///@{
+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00
+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01
+#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02
+#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03
+///@}
+
+///
+/// DEVICE_PRODUCER_FLOPPY
+///
+typedef struct {
+  UINT16                            Address;          ///< I/O address assigned to the floppy.
+  UINT8                             Irq;              ///< IRQ assigned to the floppy.
+  UINT8                             Dma;              ///< DMA assigned to the floppy.
+  UINT8                             NumberOfFloppy;   ///< Number of floppies in the system.
+} DEVICE_PRODUCER_FLOPPY;
+
+///
+/// LEGACY_DEVICE_FLAGS
+///
+typedef struct {
+  UINT32                            A20Kybd : 1;      ///< A20 controller by keyboard controller.
+  UINT32                            A20Port90 : 1;    ///< A20 controlled by port 0x92.
+  UINT32                            Reserved : 30;    ///< Reserved for future usage.
+} LEGACY_DEVICE_FLAGS;
+
+///
+/// DEVICE_PRODUCER_DATA_HEADER
+///
+typedef struct {
+  DEVICE_PRODUCER_SERIAL            Serial[4];      ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below.
+  DEVICE_PRODUCER_PARALLEL          Parallel[3];    ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below.
+  DEVICE_PRODUCER_FLOPPY            Floppy;         ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below.
+  UINT8                             MousePresent;   ///< Flag to indicate if mouse is present.
+  LEGACY_DEVICE_FLAGS               Flags;          ///< Miscellaneous Boolean state information passed to CSM.
+} DEVICE_PRODUCER_DATA_HEADER;
+
+///
+/// ATAPI_IDENTIFY
+///
+typedef struct {
+  UINT16                            Raw[256];     ///< Raw data from the IDE IdentifyDrive command.
+} ATAPI_IDENTIFY;
+
+///
+/// HDD_INFO
+///
+typedef struct {
+  ///
+  /// Status of IDE device. Values are defined below. There is one HDD_INFO structure
+  /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index
+  /// 1 is slave.
+  ///
+  UINT16                            Status;   
+  
+  ///
+  /// PCI bus of IDE controller.
+  ///
+  UINT32                            Bus;
+  
+  ///
+  /// PCI device of IDE controller.
+  ///
+  UINT32                            Device;
+  
+  ///
+  /// PCI function of IDE controller.
+  ///
+  UINT32                            Function;
+  
+  ///
+  /// Command ports base address.
+  ///
+  UINT16                            CommandBaseAddress;
+  
+  ///
+  /// Control ports base address.
+  ///
+  UINT16                            ControlBaseAddress;
+  
+  ///
+  /// Bus master address.
+  ///
+  UINT16                            BusMasterAddress;
+  
+  UINT8                             HddIrq;
+  
+  ///
+  /// Data that identifies the drive data; one per possible attached drive.
+  ///
+  ATAPI_IDENTIFY                    IdentifyDrive[2];
+} HDD_INFO;
+
+///
+/// HDD_INFO status bits
+///
+#define HDD_PRIMARY               0x01
+#define HDD_SECONDARY             0x02
+#define HDD_MASTER_ATAPI_CDROM    0x04
+#define HDD_SLAVE_ATAPI_CDROM     0x08
+#define HDD_MASTER_IDE            0x20
+#define HDD_SLAVE_IDE             0x40
+#define HDD_MASTER_ATAPI_ZIPDISK  0x10
+#define HDD_SLAVE_ATAPI_ZIPDISK   0x80
+
+///
+/// BBS_STATUS_FLAGS;\.
+///
+typedef struct {
+  UINT16                            OldPosition : 4;    ///< Prior priority.
+  UINT16                            Reserved1 : 4;      ///< Reserved for future use.
+  UINT16                            Enabled : 1;        ///< If 0, ignore this entry.
+  UINT16                            Failed : 1;         ///< 0 = Not known if boot failure occurred.
+                                                        ///< 1 = Boot attempted failed.
+  
+  ///
+  /// State of media present.
+  ///   00 = No bootable media is present in the device.
+  ///   01 = Unknown if a bootable media present.
+  ///   10 = Media is present and appears bootable.
+  ///   11 = Reserved.
+  ///
+  UINT16                            MediaPresent : 2;
+  UINT16                            Reserved2 : 4;      ///< Reserved for future use.
+} BBS_STATUS_FLAGS;
+
+///
+/// BBS_TABLE, device type values & boot priority values.
+///
+typedef struct {
+  ///
+  /// The boot priority for this boot device. Values are defined below.
+  ///
+  UINT16                            BootPriority;
+  
+  ///
+  /// The PCI bus for this boot device.
+  ///
+  UINT32                            Bus;
+  
+  ///
+  /// The PCI device for this boot device.
+  ///
+  UINT32                            Device;
+  
+  ///
+  /// The PCI function for the boot device.
+  ///
+  UINT32                            Function;
+  
+  ///
+  /// The PCI class for this boot device.
+  ///
+  UINT8                             Class;
+  
+  ///
+  /// The PCI Subclass for this boot device.
+  ///
+  UINT8                             SubClass;
+  
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
+  ///
+  UINT16                            MfgStringOffset;
+  
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
+  ///  
+  UINT16                            MfgStringSegment;
+  
+  ///
+  /// BBS device type. BBS device types are defined below.
+  ///
+  UINT16                            DeviceType;
+  
+  ///
+  /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below.
+  ///
+  BBS_STATUS_FLAGS                  StatusFlags;
+  
+  ///
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
+  /// BCV devices.
+  ///
+  UINT16                            BootHandlerOffset;
+  
+  ///
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
+  /// BCV devices.
+  ///  
+  UINT16                            BootHandlerSegment;
+  
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing this device.
+  ///
+  UINT16                            DescStringOffset;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing this device.
+  ///
+  UINT16                            DescStringSegment;
+  
+  ///
+  /// Reserved.
+  ///
+  UINT32                            InitPerReserved;
+  
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq13Handler;
+  
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///  
+  UINT32                            AdditionalIrq18Handler;
+  
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///  
+  UINT32                            AdditionalIrq19Handler;
+  
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///  
+  UINT32                            AdditionalIrq40Handler;
+  UINT8                             AssignedDriveNumber;
+  UINT32                            AdditionalIrq41Handler;
+  UINT32                            AdditionalIrq46Handler;
+  UINT32                            IBV1;
+  UINT32                            IBV2;
+} BBS_TABLE;
+
+///
+/// BBS device type values
+///@{
+#define BBS_FLOPPY              0x01
+#define BBS_HARDDISK            0x02
+#define BBS_CDROM               0x03
+#define BBS_PCMCIA              0x04
+#define BBS_USB                 0x05
+#define BBS_EMBED_NETWORK       0x06
+#define BBS_BEV_DEVICE          0x80
+#define BBS_UNKNOWN             0xff
+///@}
+
+///
+/// BBS boot priority values
+///@{
+#define BBS_DO_NOT_BOOT_FROM    0xFFFC
+#define BBS_LOWEST_PRIORITY     0xFFFD
+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE
+#define BBS_IGNORE_ENTRY        0xFFFF
+///@}
+
+///
+/// SMM_ATTRIBUTES
+///
+typedef struct {
+  ///
+  /// Access mechanism used to generate the soft SMI. Defined types are below. The other
+  /// values are reserved for future usage.
+  ///
+  UINT16                            Type : 3;
+  
+  ///
+  /// The size of "port" in bits. Defined values are below.
+  ///
+  UINT16                            PortGranularity : 3;
+  
+  ///
+  /// The size of data in bits. Defined values are below.
+  ///
+  UINT16                            DataGranularity : 3;
+  
+  ///
+  /// Reserved for future use.
+  ///
+  UINT16                            Reserved : 7;
+} SMM_ATTRIBUTES;
+
+///
+/// SMM_ATTRIBUTES type values.
+///@{
+#define STANDARD_IO       0x00
+#define STANDARD_MEMORY   0x01
+///@}
+
+///
+/// SMM_ATTRIBUTES port size constants.
+///@{
+#define PORT_SIZE_8       0x00
+#define PORT_SIZE_16      0x01
+#define PORT_SIZE_32      0x02
+#define PORT_SIZE_64      0x03
+///@}
+
+///
+/// SMM_ATTRIBUTES data size constants.
+///@{
+#define DATA_SIZE_8       0x00
+#define DATA_SIZE_16      0x01
+#define DATA_SIZE_32      0x02
+#define DATA_SIZE_64      0x03
+///@}
+
+///
+/// SMM_FUNCTION & relating constants.
+///
+typedef struct {
+  UINT16                            Function : 15;
+  UINT16                            Owner : 1;
+} SMM_FUNCTION;
+
+///
+/// SMM_FUNCTION Function constants.
+///@{
+#define INT15_D042        0x0000
+#define GET_USB_BOOT_INFO 0x0001
+#define DMI_PNP_50_57     0x0002
+///@}
+
+///
+/// SMM_FUNCTION Owner constants.
+///@{
+#define STANDARD_OWNER    0x0
+#define OEM_OWNER         0x1
+///@}
+
+///
+/// This structure assumes both port and data sizes are 1. SmmAttribute must be
+/// properly to reflect that assumption.
+///
+typedef struct {
+  ///
+  /// Describes the access mechanism, SmmPort, and SmmData sizes. Type
+  /// SMM_ATTRIBUTES is defined below.
+  ///
+  SMM_ATTRIBUTES                    SmmAttributes;
+  
+  ///
+  /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below.
+  ///
+  SMM_FUNCTION                      SmmFunction;
+  
+  ///
+  /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
+  ///
+  UINT8                             SmmPort;
+  
+  ///
+  /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
+  ///
+  UINT8                             SmmData;
+} SMM_ENTRY;
+
+///
+/// SMM_TABLE
+///
+typedef struct {
+  UINT16                            NumSmmEntries;    ///< Number of entries represented by SmmEntry.
+  SMM_ENTRY                         SmmEntry;         ///< One entry per function. Type SMM_ENTRY is defined below.
+} SMM_TABLE;
+
+///
+/// UDC_ATTRIBUTES
+///
+typedef struct {
+  ///
+  /// This bit set indicates that the ServiceAreaData is valid.
+  ///
+  UINT8                             DirectoryServiceValidity : 1;
+  
+  ///
+  /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if
+  /// DirectoryServiceValidity is 0.
+  ///
+  UINT8                             RabcaUsedFlag : 1;
+  
+  ///
+  /// This bit set indicates to execute hard disk diagnostics.
+  ///
+  UINT8                             ExecuteHddDiagnosticsFlag : 1;
+  
+  ///
+  /// Reserved for future use. Set to 0.
+  ///
+  UINT8                             Reserved : 5;
+} UDC_ATTRIBUTES;
+
+///
+/// UD_TABLE
+///
+typedef struct {
+  ///
+  /// This field contains the bit-mapped attributes of the PARTIES information. Type
+  /// UDC_ATTRIBUTES is defined below.
+  ///
+  UDC_ATTRIBUTES                    Attributes;
+  
+  ///
+  /// This field contains the zero-based device on which the selected
+  /// ServiceDataArea is present. It is 0 for master and 1 for the slave device.  
+  ///
+  UINT8                             DeviceNumber;
+  
+  ///
+  /// This field contains the zero-based index into the BbsTable for the parent device.
+  /// This index allows the user to reference the parent device information such as PCI
+  /// bus, device function.
+  ///
+  UINT8                             BbsTableEntryNumberForParentDevice;
+  
+  ///
+  /// This field contains the zero-based index into the BbsTable for the boot entry.
+  ///
+  UINT8                             BbsTableEntryNumberForBoot;
+  
+  ///
+  /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry.
+  ///
+  UINT8                             BbsTableEntryNumberForHddDiag;
+  
+  ///
+  /// The raw Beer data.
+  ///
+  UINT8                             BeerData[128];
+  
+  ///
+  /// The raw data of selected service area.
+  ///
+  UINT8                             ServiceAreaData[64];
+} UD_TABLE;
+
+#define EFI_TO_LEGACY_MAJOR_VERSION 0x02
+#define EFI_TO_LEGACY_MINOR_VERSION 0x00
+#define MAX_IDE_CONTROLLER          8
+
+///
+/// EFI_TO_COMPATIBILITY16_BOOT_TABLE
+///
+typedef struct {
+  UINT16                            MajorVersion;                 ///< The EfiCompatibility major version number.
+  UINT16                            MinorVersion;                 ///< The EfiCompatibility minor version number.
+  UINT32                            AcpiTable;                    ///< The location of the RSDT ACPI table. < 4G range.
+  UINT32                            SmbiosTable;                  ///< The location of the SMBIOS table in EFI memory. < 4G range.
+  UINT32                            SmbiosTableLength;
+  //
+  // Legacy SIO state
+  //
+  DEVICE_PRODUCER_DATA_HEADER       SioData;                      ///< Standard traditional device information.
+  UINT16                            DevicePathType;               ///< The default boot type.
+  UINT16                            PciIrqMask;                   ///< Mask of which IRQs have been assigned to PCI.
+  UINT32                            NumberE820Entries;            ///< Number of E820 entries. The number can change from the
+                                                                  ///< Compatibility16InitializeYourself() function.
+  //
+  // Controller & Drive Identify[2] per controller information
+  //
+  HDD_INFO                          HddInfo[MAX_IDE_CONTROLLER];  ///< Hard disk drive information, including raw Identify Drive data.
+  UINT32                            NumberBbsEntries;             ///< Number of entries in the BBS table
+  UINT32                            BbsTable;                     ///< A pointer to the BBS table. Type BBS_TABLE is defined below.
+  UINT32                            SmmTable;                     ///< A pointer to the SMM table. Type SMM_TABLE is defined below.
+  UINT32                            OsMemoryAbove1Mb;             ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can
+                                                                  ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more
+                                                                  ///< memory may have been discovered.
+  UINT32                            UnconventionalDeviceTable;    ///< Information to boot off an unconventional device like a PARTIES partition. Type
+                                                                  ///< UD_TABLE is defined below.
+} EFI_TO_COMPATIBILITY16_BOOT_TABLE;
+
+///
+/// EFI_LEGACY_INSTALL_PCI_HANDLER
+///
+typedef struct {
+  UINT8                             PciBus;             ///< The PCI bus of the device.
+  UINT8                             PciDeviceFun;       ///< The PCI device in bits 7:3 and function in bits 2:0.
+  UINT8                             PciSegment;         ///< The PCI segment of the device.
+  UINT8                             PciClass;           ///< The PCI class code of the device.
+  UINT8                             PciSubclass;        ///< The PCI subclass code of the device.
+  UINT8                             PciInterface;       ///< The PCI interface code of the device.
+  //
+  // Primary section
+  //
+  UINT8                             PrimaryIrq;         ///< The primary device IRQ.
+  UINT8                             PrimaryReserved;    ///< Reserved.
+  UINT16                            PrimaryControl;     ///< The primary device control I/O base.
+  UINT16                            PrimaryBase;        ///< The primary device I/O base.
+  UINT16                            PrimaryBusMaster;   ///< The primary device bus master I/O base.
+  //
+  // Secondary Section
+  //
+  UINT8                             SecondaryIrq;       ///< The secondary device IRQ.
+  UINT8                             SecondaryReserved;  ///< Reserved.
+  UINT16                            SecondaryControl;   ///< The secondary device control I/O base.
+  UINT16                            SecondaryBase;      ///< The secondary device I/O base.
+  UINT16                            SecondaryBusMaster; ///< The secondary device bus master I/O base.
+} EFI_LEGACY_INSTALL_PCI_HANDLER;
+
+#endif
diff --git a/src/fw/acpi-dsdt-cpu-hotplug.dsl b/src/fw/acpi-dsdt-cpu-hotplug.dsl
new file mode 100644 (file)
index 0000000..0f3e83b
--- /dev/null
@@ -0,0 +1,78 @@
+/****************************************************************
+ * CPU hotplug
+ ****************************************************************/
+
+Scope(\_SB) {
+    /* Objects filled in by run-time generated SSDT */
+    External(NTFY, MethodObj)
+    External(CPON, PkgObj)
+
+    /* Methods called by run-time generated SSDT Processor objects */
+    Method(CPMA, 1, NotSerialized) {
+        // _MAT method - create an madt apic buffer
+        // Arg0 = Processor ID = Local APIC ID
+        // Local0 = CPON flag for this cpu
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
+        // Local1 = Buffer (in madt apic form) to return
+        Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
+        // Update the processor id, lapic id, and enable/disable status
+        Store(Arg0, Index(Local1, 2))
+        Store(Arg0, Index(Local1, 3))
+        Store(Local0, Index(Local1, 4))
+        Return (Local1)
+    }
+    Method(CPST, 1, NotSerialized) {
+        // _STA method - return ON status of cpu
+        // Arg0 = Processor ID = Local APIC ID
+        // Local0 = CPON flag for this cpu
+        Store(DerefOf(Index(CPON, Arg0)), Local0)
+        If (Local0) {
+            Return (0xF)
+        } Else {
+            Return (0x0)
+        }
+    }
+    Method(CPEJ, 2, NotSerialized) {
+        // _EJ0 method - eject callback
+        Sleep(200)
+    }
+
+    /* CPU hotplug notify method */
+    OperationRegion(PRST, SystemIO, 0xaf00, 32)
+    Field(PRST, ByteAcc, NoLock, Preserve) {
+        PRS, 256
+    }
+    Method(PRSC, 0) {
+        // Local5 = active cpu bitmap
+        Store(PRS, Local5)
+        // Local2 = last read byte from bitmap
+        Store(Zero, Local2)
+        // Local0 = Processor ID / APIC ID iterator
+        Store(Zero, Local0)
+        While (LLess(Local0, SizeOf(CPON))) {
+            // Local1 = CPON flag for this cpu
+            Store(DerefOf(Index(CPON, Local0)), Local1)
+            If (And(Local0, 0x07)) {
+                // Shift down previously read bitmap byte
+                ShiftRight(Local2, 1, Local2)
+            } Else {
+                // Read next byte from cpu bitmap
+                Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
+            }
+            // Local3 = active state for this cpu
+            Store(And(Local2, 1), Local3)
+
+            If (LNotEqual(Local1, Local3)) {
+                // State change - update CPON with new state
+                Store(Local3, Index(CPON, Local0))
+                // Do CPU notify
+                If (LEqual(Local3, 1)) {
+                    NTFY(Local0, 1)
+                } Else {
+                    NTFY(Local0, 3)
+                }
+            }
+            Increment(Local0)
+        }
+    }
+}
diff --git a/src/fw/acpi-dsdt-dbug.dsl b/src/fw/acpi-dsdt-dbug.dsl
new file mode 100644 (file)
index 0000000..276321f
--- /dev/null
@@ -0,0 +1,26 @@
+/****************************************************************
+ * Debugging
+ ****************************************************************/
+
+Scope(\) {
+    /* Debug Output */
+    OperationRegion(DBG, SystemIO, 0x0402, 0x01)
+    Field(DBG, ByteAcc, NoLock, Preserve) {
+        DBGB,   8,
+    }
+
+    /* Debug method - use this method to send output to the QEMU
+     * BIOS debug port.  This method handles strings, integers,
+     * and buffers.  For example: DBUG("abc") DBUG(0x123) */
+    Method(DBUG, 1) {
+        ToHexString(Arg0, Local0)
+        ToBuffer(Local0, Local0)
+        Subtract(SizeOf(Local0), 1, Local1)
+        Store(Zero, Local2)
+        While (LLess(Local2, Local1)) {
+            Store(DerefOf(Index(Local0, Local2)), DBGB)
+            Increment(Local2)
+        }
+        Store(0x0A, DBGB)
+    }
+}
diff --git a/src/fw/acpi-dsdt-hpet.dsl b/src/fw/acpi-dsdt-hpet.dsl
new file mode 100644 (file)
index 0000000..f33e527
--- /dev/null
@@ -0,0 +1,36 @@
+/****************************************************************
+ * HPET
+ ****************************************************************/
+
+Scope(\_SB) {
+    Device(HPET) {
+        Name(_HID, EISAID("PNP0103"))
+        Name(_UID, 0)
+        OperationRegion(HPTM, SystemMemory, 0xFED00000, 0x400)
+        Field(HPTM, DWordAcc, Lock, Preserve) {
+            VEND, 32,
+            PRD, 32,
+        }
+        Method(_STA, 0, NotSerialized) {
+            Store(VEND, Local0)
+            Store(PRD, Local1)
+            ShiftRight(Local0, 16, Local0)
+            If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
+                Return (0x0)
+            }
+            If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
+                Return (0x0)
+            }
+            Return (0x0F)
+        }
+        Name(_CRS, ResourceTemplate() {
+#if 0       /* This makes WinXP BSOD for not yet figured reasons. */
+            IRQNoFlags() {2, 8}
+#endif
+            Memory32Fixed(ReadOnly,
+                0xFED00000,         // Address Base
+                0x00000400,         // Address Length
+                )
+        })
+    }
+}
diff --git a/src/fw/acpi-dsdt-isa.dsl b/src/fw/acpi-dsdt-isa.dsl
new file mode 100644 (file)
index 0000000..23761db
--- /dev/null
@@ -0,0 +1,102 @@
+/* Common legacy ISA style devices. */
+Scope(\_SB.PCI0.ISA) {
+
+    Device(RTC) {
+        Name(_HID, EisaId("PNP0B00"))
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
+            IRQNoFlags() { 8 }
+            IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
+        })
+    }
+
+    Device(KBD) {
+        Name(_HID, EisaId("PNP0303"))
+        Method(_STA, 0, NotSerialized) {
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
+            IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
+            IRQNoFlags() { 1 }
+        })
+    }
+
+    Device(MOU) {
+        Name(_HID, EisaId("PNP0F13"))
+        Method(_STA, 0, NotSerialized) {
+            Return (0x0f)
+        }
+        Name(_CRS, ResourceTemplate() {
+            IRQNoFlags() { 12 }
+        })
+    }
+
+    Device(FDC0) {
+        Name(_HID, EisaId("PNP0700"))
+        Method(_STA, 0, NotSerialized) {
+            Store(FDEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x03F2, 0x03F2, 0x00, 0x04)
+            IO(Decode16, 0x03F7, 0x03F7, 0x00, 0x01)
+            IRQNoFlags() { 6 }
+            DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
+        })
+    }
+
+    Device(LPT) {
+        Name(_HID, EisaId("PNP0400"))
+        Method(_STA, 0, NotSerialized) {
+            Store(LPEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
+            IRQNoFlags() { 7 }
+        })
+    }
+
+    Device(COM1) {
+        Name(_HID, EisaId("PNP0501"))
+        Name(_UID, 0x01)
+        Method(_STA, 0, NotSerialized) {
+            Store(CAEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x03F8, 0x03F8, 0x00, 0x08)
+            IRQNoFlags() { 4 }
+        })
+    }
+
+    Device(COM2) {
+        Name(_HID, EisaId("PNP0501"))
+        Name(_UID, 0x02)
+        Method(_STA, 0, NotSerialized) {
+            Store(CBEN, Local0)
+            If (LEqual(Local0, 0)) {
+                Return (0x00)
+            } Else {
+                Return (0x0F)
+            }
+        }
+        Name(_CRS, ResourceTemplate() {
+            IO(Decode16, 0x02F8, 0x02F8, 0x00, 0x08)
+            IRQNoFlags() { 3 }
+        })
+    }
+}
diff --git a/src/fw/acpi-dsdt-pci-crs.dsl b/src/fw/acpi-dsdt-pci-crs.dsl
new file mode 100644 (file)
index 0000000..d421891
--- /dev/null
@@ -0,0 +1,90 @@
+/* PCI CRS (current resources) definition. */
+Scope(\_SB.PCI0) {
+
+    Name(CRES, ResourceTemplate() {
+        WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
+            0x0000,             // Address Space Granularity
+            0x0000,             // Address Range Minimum
+            0x00FF,             // Address Range Maximum
+            0x0000,             // Address Translation Offset
+            0x0100,             // Address Length
+            ,, )
+        IO(Decode16,
+            0x0CF8,             // Address Range Minimum
+            0x0CF8,             // Address Range Maximum
+            0x01,               // Address Alignment
+            0x08,               // Address Length
+            )
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+            0x0000,             // Address Space Granularity
+            0x0000,             // Address Range Minimum
+            0x0CF7,             // Address Range Maximum
+            0x0000,             // Address Translation Offset
+            0x0CF8,             // Address Length
+            ,, , TypeStatic)
+        WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+            0x0000,             // Address Space Granularity
+            0x0D00,             // Address Range Minimum
+            0xFFFF,             // Address Range Maximum
+            0x0000,             // Address Translation Offset
+            0xF300,             // Address Length
+            ,, , TypeStatic)
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+            0x00000000,         // Address Space Granularity
+            0x000A0000,         // Address Range Minimum
+            0x000BFFFF,         // Address Range Maximum
+            0x00000000,         // Address Translation Offset
+            0x00020000,         // Address Length
+            ,, , AddressRangeMemory, TypeStatic)
+        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
+            0x00000000,         // Address Space Granularity
+            0xE0000000,         // Address Range Minimum
+            0xFEBFFFFF,         // Address Range Maximum
+            0x00000000,         // Address Translation Offset
+            0x1EC00000,         // Address Length
+            ,, PW32, AddressRangeMemory, TypeStatic)
+    })
+
+    Name(CR64, ResourceTemplate() {
+        QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+            0x00000000,          // Address Space Granularity
+            0x8000000000,        // Address Range Minimum
+            0xFFFFFFFFFF,        // Address Range Maximum
+            0x00000000,          // Address Translation Offset
+            0x8000000000,        // Address Length
+            ,, PW64, AddressRangeMemory, TypeStatic)
+    })
+
+    Method(_CRS, 0) {
+        /* Fields provided by dynamically created ssdt */
+        External(P0S, IntObj)
+        External(P0E, IntObj)
+        External(P1V, IntObj)
+        External(P1S, BuffObj)
+        External(P1E, BuffObj)
+        External(P1L, BuffObj)
+
+        /* fixup 32bit pci io window */
+        CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32)
+        CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32)
+        CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32)
+        Store(P0S, PS32)
+        Store(P0E, PE32)
+        Store(Add(Subtract(P0E, P0S), 1), PL32)
+
+        If (LEqual(P1V, Zero)) {
+            Return (CRES)
+        }
+
+        /* fixup 64bit pci io window */
+        CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64)
+        CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64)
+        CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64)
+        Store(P1S, PS64)
+        Store(P1E, PE64)
+        Store(P1L, PL64)
+        /* add window and return result */
+        ConcatenateResTemplate(CRES, CR64, Local0)
+        Return (Local0)
+    }
+}
diff --git a/src/fw/acpi-dsdt.dsl b/src/fw/acpi-dsdt.dsl
new file mode 100644 (file)
index 0000000..158f6b4
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Bochs/QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+ACPI_EXTRACT_ALL_CODE AmlCode
+
+DefinitionBlock (
+    "acpi-dsdt.aml",    // Output Filename
+    "DSDT",             // Signature
+    0x01,               // DSDT Compliance Revision
+    "BXPC",             // OEMID
+    "BXDSDT",           // TABLE ID
+    0x1                 // OEM Revision
+    )
+{
+
+#include "acpi-dsdt-dbug.dsl"
+
+
+/****************************************************************
+ * PCI Bus definition
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Device(PCI0) {
+            Name(_HID, EisaId("PNP0A03"))
+            Name(_ADR, 0x00)
+            Name(_UID, 1)
+        }
+    }
+
+#include "acpi-dsdt-pci-crs.dsl"
+#include "acpi-dsdt-hpet.dsl"
+
+
+/****************************************************************
+ * VGA
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(VGA) {
+            Name(_ADR, 0x00020000)
+            OperationRegion(PCIC, PCI_Config, Zero, 0x4)
+            Field(PCIC, DWordAcc, NoLock, Preserve) {
+                VEND, 32
+            }
+            Method(_S1D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S2D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S3D, 0, NotSerialized) {
+                If (LEqual(VEND, 0x1001b36)) {
+                    Return (0x03)           // QXL
+                } Else {
+                    Return (0x00)
+                }
+            }
+        }
+    }
+
+
+/****************************************************************
+ * PIIX4 PM
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(PX13) {
+            Name(_ADR, 0x00010003)
+            OperationRegion(P13C, PCI_Config, 0x00, 0xff)
+        }
+    }
+
+
+/****************************************************************
+ * PIIX3 ISA bridge
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(ISA) {
+            Name(_ADR, 0x00010000)
+
+            /* PIIX PCI to ISA irq remapping */
+            OperationRegion(P40C, PCI_Config, 0x60, 0x04)
+
+            /* enable bits */
+            Field(\_SB.PCI0.PX13.P13C, AnyAcc, NoLock, Preserve) {
+                Offset(0x5f),
+                , 7,
+                LPEN, 1,         // LPT
+                Offset(0x67),
+                , 3,
+                CAEN, 1,         // COM1
+                , 3,
+                CBEN, 1,         // COM2
+            }
+            Name(FDEN, 1)
+        }
+    }
+
+#include "acpi-dsdt-isa.dsl"
+
+
+/****************************************************************
+ * PCI hotplug
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        OperationRegion(PCST, SystemIO, 0xae00, 0x08)
+        Field(PCST, DWordAcc, NoLock, WriteAsZeros) {
+            PCIU, 32,
+            PCID, 32,
+        }
+
+        OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
+        Field(SEJ, DWordAcc, NoLock, WriteAsZeros) {
+            B0EJ, 32,
+        }
+
+        /* Methods called by bulk generated PCI devices below */
+
+        /* Methods called by hotplug devices */
+        Method(PCEJ, 1, NotSerialized) {
+            // _EJ0 method - eject callback
+            Store(ShiftLeft(1, Arg0), B0EJ)
+            Return (0x0)
+        }
+
+        /* Hotplug notification method supplied by SSDT */
+        External(\_SB.PCI0.PCNT, MethodObj)
+
+        /* PCI hotplug notify method */
+        Method(PCNF, 0) {
+            // Local0 = iterator
+            Store(Zero, Local0)
+            While (LLess(Local0, 31)) {
+                Increment(Local0)
+                If (And(PCIU, ShiftLeft(1, Local0))) {
+                    PCNT(Local0, 1)
+                }
+                If (And(PCID, ShiftLeft(1, Local0))) {
+                    PCNT(Local0, 3)
+                }
+            }
+        }
+    }
+
+
+/****************************************************************
+ * PCI IRQs
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Scope(PCI0) {
+            Name(_PRT, Package() {
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
+                   section 6.2.8.1 */
+                /* Note: we provide the same info as the PCI routing
+                   table of the Bochs BIOS */
+
+#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \
+    Package() { nr##ffff, 0, lnk0, 0 }, \
+    Package() { nr##ffff, 1, lnk1, 0 }, \
+    Package() { nr##ffff, 2, lnk2, 0 }, \
+    Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC)
+#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB)
+
+                prt_slot0(0x0000),
+                /* Device 1 is power mgmt device, and can only use irq 9 */
+                prt_slot(0x0001, LNKS, LNKB, LNKC, LNKD),
+                prt_slot2(0x0002),
+                prt_slot3(0x0003),
+                prt_slot0(0x0004),
+                prt_slot1(0x0005),
+                prt_slot2(0x0006),
+                prt_slot3(0x0007),
+                prt_slot0(0x0008),
+                prt_slot1(0x0009),
+                prt_slot2(0x000a),
+                prt_slot3(0x000b),
+                prt_slot0(0x000c),
+                prt_slot1(0x000d),
+                prt_slot2(0x000e),
+                prt_slot3(0x000f),
+                prt_slot0(0x0010),
+                prt_slot1(0x0011),
+                prt_slot2(0x0012),
+                prt_slot3(0x0013),
+                prt_slot0(0x0014),
+                prt_slot1(0x0015),
+                prt_slot2(0x0016),
+                prt_slot3(0x0017),
+                prt_slot0(0x0018),
+                prt_slot1(0x0019),
+                prt_slot2(0x001a),
+                prt_slot3(0x001b),
+                prt_slot0(0x001c),
+                prt_slot1(0x001d),
+                prt_slot2(0x001e),
+                prt_slot3(0x001f),
+            })
+        }
+
+        Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) {
+            PRQ0,   8,
+            PRQ1,   8,
+            PRQ2,   8,
+            PRQ3,   8
+        }
+
+        Method(IQST, 1, NotSerialized) {
+            // _STA method - get status
+            If (And(0x80, Arg0)) {
+                Return (0x09)
+            }
+            Return (0x0B)
+        }
+        Method(IQCR, 1, NotSerialized) {
+            // _CRS method - get current settings
+            Name(PRR0, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
+            })
+            CreateDWordField(PRR0, 0x05, PRRI)
+            If (LLess(Arg0, 0x80)) {
+                Store(Arg0, PRRI)
+            }
+            Return (PRR0)
+        }
+
+#define define_link(link, uid, reg)                             \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    5, 10, 11                                   \
+                }                                               \
+            })                                                  \
+            Method(_STA, 0, NotSerialized) {                    \
+                Return (IQST(reg))                              \
+            }                                                   \
+            Method(_DIS, 0, NotSerialized) {                    \
+                Or(reg, 0x80, reg)                              \
+            }                                                   \
+            Method(_CRS, 0, NotSerialized) {                    \
+                Return (IQCR(reg))                              \
+            }                                                   \
+            Method(_SRS, 1, NotSerialized) {                    \
+                CreateDWordField(Arg0, 0x05, PRRI)              \
+                Store(PRRI, reg)                                \
+            }                                                   \
+        }
+
+        define_link(LNKA, 0, PRQ0)
+        define_link(LNKB, 1, PRQ1)
+        define_link(LNKC, 2, PRQ2)
+        define_link(LNKD, 3, PRQ3)
+
+        Device(LNKS) {
+            Name(_HID, EISAID("PNP0C0F"))
+            Name(_UID, 4)
+            Name(_PRS, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 9 }
+            })
+
+            // The SCI cannot be disabled and is always attached to GSI 9,
+            // so these are no-ops.  We only need this link to override the
+            // polarity to active high and match the content of the MADT.
+            Method(_STA, 0, NotSerialized) { Return (0x0b) }
+            Method(_DIS, 0, NotSerialized) { }
+            Method(_CRS, 0, NotSerialized) { Return (_PRS) }
+            Method(_SRS, 1, NotSerialized) { }
+        }
+    }
+
+#include "acpi-dsdt-cpu-hotplug.dsl"
+
+
+/****************************************************************
+ * General purpose events
+ ****************************************************************/
+
+    Scope(\_GPE) {
+        Name(_HID, "ACPI0006")
+
+        Method(_L00) {
+        }
+        Method(_E01) {
+            // PCI hotplug event
+            \_SB.PCI0.PCNF()
+        }
+        Method(_E02) {
+            // CPU hotplug event
+            \_SB.PRSC()
+        }
+        Method(_L03) {
+        }
+        Method(_L04) {
+        }
+        Method(_L05) {
+        }
+        Method(_L06) {
+        }
+        Method(_L07) {
+        }
+        Method(_L08) {
+        }
+        Method(_L09) {
+        }
+        Method(_L0A) {
+        }
+        Method(_L0B) {
+        }
+        Method(_L0C) {
+        }
+        Method(_L0D) {
+        }
+        Method(_L0E) {
+        }
+        Method(_L0F) {
+        }
+    }
+}
diff --git a/src/fw/acpi.c b/src/fw/acpi.c
new file mode 100644 (file)
index 0000000..9fd1c05
--- /dev/null
@@ -0,0 +1,788 @@
+// Support for generating ACPI tables (on emulators)
+//
+// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "acpi.h" // struct rsdp_descriptor
+#include "util.h" // memcpy
+#include "byteorder.h" // cpu_to_le16
+#include "hw/pci.h" // pci_find_init_device
+#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
+#include "hw/pci_regs.h" // PCI_INTERRUPT_LINE
+#include "ioport.h" // inl
+#include "config.h" // CONFIG_*
+#include "paravirt.h" // RamSize
+#include "dev-q35.h"
+
+#include "src/fw/acpi-dsdt.hex"
+
+u32 acpi_pm1a_cnt VARFSEG;
+
+static void
+build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
+{
+    h->signature = cpu_to_le32(sig);
+    h->length = cpu_to_le32(len);
+    h->revision = rev;
+    memcpy(h->oem_id, BUILD_APPNAME6, 6);
+    memcpy(h->oem_table_id, BUILD_APPNAME4, 4);
+    memcpy(h->oem_table_id + 4, (void*)&sig, 4);
+    h->oem_revision = cpu_to_le32(1);
+    memcpy(h->asl_compiler_id, BUILD_APPNAME4, 4);
+    h->asl_compiler_revision = cpu_to_le32(1);
+    h->checksum -= checksum(h, len);
+}
+
+#define PIIX4_ACPI_ENABLE       0xf1
+#define PIIX4_ACPI_DISABLE      0xf0
+#define PIIX4_GPE0_BLK          0xafe0
+#define PIIX4_GPE0_BLK_LEN      4
+
+#define PIIX4_PM_INTRRUPT       9       // irq 9
+
+static void piix4_fadt_setup(struct pci_device *pci, void *arg)
+{
+    struct fadt_descriptor_rev1 *fadt = arg;
+
+    fadt->model = 1;
+    fadt->reserved1 = 0;
+    fadt->sci_int = cpu_to_le16(PIIX4_PM_INTRRUPT);
+    fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
+    fadt->acpi_enable = PIIX4_ACPI_ENABLE;
+    fadt->acpi_disable = PIIX4_ACPI_DISABLE;
+    fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
+    fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
+    fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
+    fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK);
+    fadt->pm1_evt_len = 4;
+    fadt->pm1_cnt_len = 2;
+    fadt->pm_tmr_len = 4;
+    fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN;
+    fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
+    fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
+    /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 + USE_PLATFORM_CLOCK */
+    fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7) |
+                              (1 << 15));
+}
+
+/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
+void ich9_lpc_fadt_setup(struct pci_device *dev, void *arg)
+{
+    struct fadt_descriptor_rev1 *fadt = arg;
+
+    fadt->model = 1;
+    fadt->reserved1 = 0;
+    fadt->sci_int = cpu_to_le16(9);
+    fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
+    fadt->acpi_enable = ICH9_ACPI_ENABLE;
+    fadt->acpi_disable = ICH9_ACPI_DISABLE;
+    fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
+    fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
+    fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
+    fadt->gpe0_blk = cpu_to_le32(PORT_ACPI_PM_BASE + ICH9_PMIO_GPE0_STS);
+    fadt->pm1_evt_len = 4;
+    fadt->pm1_cnt_len = 2;
+    fadt->pm_tmr_len = 4;
+    fadt->gpe0_blk_len = ICH9_PMIO_GPE0_BLK_LEN;
+    fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
+    fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
+    /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 + USE_PLATFORM_CLOCK */
+    fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7) |
+                              (1 << 15));
+}
+
+static const struct pci_device_id fadt_init_tbl[] = {
+    /* PIIX4 Power Management device (for ACPI) */
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
+               piix4_fadt_setup),
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
+               ich9_lpc_fadt_setup),
+    PCI_DEVICE_END
+};
+
+static void fill_dsdt(struct fadt_descriptor_rev1 *fadt, void *dsdt)
+{
+    if (fadt->dsdt) {
+        free((void *)le32_to_cpu(fadt->dsdt));
+    }
+    fadt->dsdt = cpu_to_le32((u32)dsdt);
+    fadt->checksum -= checksum(fadt, sizeof(*fadt));
+    dprintf(1, "ACPI DSDT=%p\n", dsdt);
+}
+
+static void *
+build_fadt(struct pci_device *pci)
+{
+    struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
+    struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
+
+    if (!fadt || !facs) {
+        warn_noalloc();
+        return NULL;
+    }
+
+    /* FACS */
+    memset(facs, 0, sizeof(*facs));
+    facs->signature = cpu_to_le32(FACS_SIGNATURE);
+    facs->length = cpu_to_le32(sizeof(*facs));
+
+    /* FADT */
+    memset(fadt, 0, sizeof(*fadt));
+    fadt->firmware_ctrl = cpu_to_le32((u32)facs);
+    fadt->dsdt = 0;  /* dsdt will be filled later in acpi_setup()
+                        by fill_dsdt() */
+    pci_init_device(fadt_init_tbl, pci, fadt);
+
+    build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1);
+
+    return fadt;
+}
+
+static void*
+build_madt(void)
+{
+    int madt_size = (sizeof(struct multiple_apic_table)
+                     + sizeof(struct madt_processor_apic) * MaxCountCPUs
+                     + sizeof(struct madt_io_apic)
+                     + sizeof(struct madt_intsrcovr) * 16
+                     + sizeof(struct madt_local_nmi));
+
+    struct multiple_apic_table *madt = malloc_high(madt_size);
+    if (!madt) {
+        warn_noalloc();
+        return NULL;
+    }
+    memset(madt, 0, madt_size);
+    madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
+    madt->flags = cpu_to_le32(1);
+    struct madt_processor_apic *apic = (void*)&madt[1];
+    int i;
+    for (i=0; i<MaxCountCPUs; i++) {
+        apic->type = APIC_PROCESSOR;
+        apic->length = sizeof(*apic);
+        apic->processor_id = i;
+        apic->local_apic_id = i;
+        if (apic_id_is_present(apic->local_apic_id))
+            apic->flags = cpu_to_le32(1);
+        else
+            apic->flags = cpu_to_le32(0);
+        apic++;
+    }
+    struct madt_io_apic *io_apic = (void*)apic;
+    io_apic->type = APIC_IO;
+    io_apic->length = sizeof(*io_apic);
+    io_apic->io_apic_id = BUILD_IOAPIC_ID;
+    io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
+    io_apic->interrupt = cpu_to_le32(0);
+
+    struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1];
+    if (romfile_loadint("etc/irq0-override", 0)) {
+        memset(intsrcovr, 0, sizeof(*intsrcovr));
+        intsrcovr->type   = APIC_XRUPT_OVERRIDE;
+        intsrcovr->length = sizeof(*intsrcovr);
+        intsrcovr->source = 0;
+        intsrcovr->gsi    = cpu_to_le32(2);
+        intsrcovr->flags  = cpu_to_le16(0); /* conforms to bus specifications */
+        intsrcovr++;
+    }
+    for (i = 1; i < 16; i++) {
+        if (!(BUILD_PCI_IRQS & (1 << i)))
+            /* No need for a INT source override structure. */
+            continue;
+        memset(intsrcovr, 0, sizeof(*intsrcovr));
+        intsrcovr->type   = APIC_XRUPT_OVERRIDE;
+        intsrcovr->length = sizeof(*intsrcovr);
+        intsrcovr->source = i;
+        intsrcovr->gsi    = cpu_to_le32(i);
+        intsrcovr->flags  = cpu_to_le16(0xd); /* active high, level triggered */
+        intsrcovr++;
+    }
+
+    struct madt_local_nmi *local_nmi = (void*)intsrcovr;
+    local_nmi->type         = APIC_LOCAL_NMI;
+    local_nmi->length       = sizeof(*local_nmi);
+    local_nmi->processor_id = 0xff; /* all processors */
+    local_nmi->flags        = cpu_to_le16(0);
+    local_nmi->lint         = 1; /* LINT1 */
+    local_nmi++;
+
+    build_header((void*)madt, APIC_SIGNATURE, (void*)local_nmi - (void*)madt, 1);
+    return madt;
+}
+
+// Encode a hex value
+static inline char getHex(u32 val) {
+    val &= 0x0f;
+    return (val <= 9) ? ('0' + val) : ('A' + val - 10);
+}
+
+// Encode a length in an SSDT.
+static u8 *
+encodeLen(u8 *ssdt_ptr, int length, int bytes)
+{
+    switch (bytes) {
+    default:
+    case 4: ssdt_ptr[3] = ((length >> 20) & 0xff);
+    case 3: ssdt_ptr[2] = ((length >> 12) & 0xff);
+    case 2: ssdt_ptr[1] = ((length >> 4) & 0xff);
+            ssdt_ptr[0] = (((bytes-1) & 0x3) << 6) | (length & 0x0f);
+            break;
+    case 1: ssdt_ptr[0] = length & 0x3f;
+    }
+    return ssdt_ptr + bytes;
+}
+
+#include "src/fw/ssdt-proc.hex"
+
+/* 0x5B 0x83 ProcessorOp PkgLength NameString ProcID */
+#define PROC_OFFSET_CPUHEX (*ssdt_proc_name - *ssdt_proc_start + 2)
+#define PROC_OFFSET_CPUID1 (*ssdt_proc_name - *ssdt_proc_start + 4)
+#define PROC_OFFSET_CPUID2 (*ssdt_proc_id - *ssdt_proc_start)
+#define PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
+#define PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
+
+/* 0x5B 0x82 DeviceOp PkgLength NameString */
+#define PCIHP_OFFSET_HEX (*ssdt_pcihp_name - *ssdt_pcihp_start + 1)
+#define PCIHP_OFFSET_ID (*ssdt_pcihp_id - *ssdt_pcihp_start)
+#define PCIHP_OFFSET_ADR (*ssdt_pcihp_adr - *ssdt_pcihp_start)
+#define PCIHP_OFFSET_EJ0 (*ssdt_pcihp_ej0 - *ssdt_pcihp_start)
+#define PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
+#define PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start)
+#define PCI_SLOTS 32
+
+#define SSDT_SIGNATURE 0x54445353 // SSDT
+#define SSDT_HEADER_LENGTH 36
+
+#include "src/fw/ssdt-misc.hex"
+#include "src/fw/ssdt-pcihp.hex"
+
+#define PCI_RMV_BASE 0xae0c
+
+static u8*
+build_notify(u8 *ssdt_ptr, const char *name, int skip, int count,
+             const char *target, int ofs)
+{
+    count -= skip;
+
+    *(ssdt_ptr++) = 0x14; // MethodOp
+    ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*count), 2);
+    memcpy(ssdt_ptr, name, 4);
+    ssdt_ptr += 4;
+    *(ssdt_ptr++) = 0x02; // MethodOp
+
+    int i;
+    for (i = skip; count-- > 0; i++) {
+        *(ssdt_ptr++) = 0xA0; // IfOp
+        ssdt_ptr = encodeLen(ssdt_ptr, 11, 1);
+        *(ssdt_ptr++) = 0x93; // LEqualOp
+        *(ssdt_ptr++) = 0x68; // Arg0Op
+        *(ssdt_ptr++) = 0x0A; // BytePrefix
+        *(ssdt_ptr++) = i;
+        *(ssdt_ptr++) = 0x86; // NotifyOp
+        memcpy(ssdt_ptr, target, 4);
+        ssdt_ptr[ofs] = getHex(i >> 4);
+        ssdt_ptr[ofs + 1] = getHex(i);
+        ssdt_ptr += 4;
+        *(ssdt_ptr++) = 0x69; // Arg1Op
+    }
+    return ssdt_ptr;
+}
+
+static void patch_pcihp(int slot, u8 *ssdt_ptr, u32 eject)
+{
+    ssdt_ptr[PCIHP_OFFSET_HEX] = getHex(slot >> 4);
+    ssdt_ptr[PCIHP_OFFSET_HEX+1] = getHex(slot);
+    ssdt_ptr[PCIHP_OFFSET_ID] = slot;
+    ssdt_ptr[PCIHP_OFFSET_ADR + 2] = slot;
+
+    /* Runtime patching of EJ0: to disable hotplug for a slot,
+     * replace the method name: _EJ0 by EJ0_. */
+    /* Sanity check */
+    if (memcmp(ssdt_ptr + PCIHP_OFFSET_EJ0, "_EJ0", 4)) {
+        warn_internalerror();
+    }
+    if (!eject) {
+        memcpy(ssdt_ptr + PCIHP_OFFSET_EJ0, "EJ0_", 4);
+    }
+}
+
+static void*
+build_ssdt(void)
+{
+    int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs;
+    int length = (sizeof(ssdp_misc_aml)                     // _S3_ / _S4_ / _S5_
+                  + (1+3+4)                                 // Scope(_SB_)
+                  + (acpi_cpus * PROC_SIZEOF)               // procs
+                  + (1+2+5+(12*acpi_cpus))                  // NTFY
+                  + (6+2+1+(1*acpi_cpus))                   // CPON
+                  + (1+3+4)                                 // Scope(PCI0)
+                  + ((PCI_SLOTS - 1) * PCIHP_SIZEOF)        // slots
+                  + (1+2+5+(12*(PCI_SLOTS - 1))));          // PCNT
+    u8 *ssdt = malloc_high(length);
+    if (! ssdt) {
+        warn_noalloc();
+        return NULL;
+    }
+    u8 *ssdt_ptr = ssdt;
+
+    // Copy header and encode fwcfg values in the S3_ / S4_ / S5_ packages
+    int sys_state_size;
+    char *sys_states = romfile_loadfile("etc/system-states", &sys_state_size);
+    if (!sys_states || sys_state_size != 6)
+        sys_states = (char[]){128, 0, 0, 129, 128, 128};
+
+    memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
+    if (!(sys_states[3] & 128))
+        ssdt_ptr[acpi_s3_name[0]] = 'X';
+    if (!(sys_states[4] & 128))
+        ssdt_ptr[acpi_s4_name[0]] = 'X';
+    else
+        ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 127;
+
+    // store pci io windows
+    *(u32*)&ssdt_ptr[acpi_pci32_start[0]] = cpu_to_le32(pcimem_start);
+    *(u32*)&ssdt_ptr[acpi_pci32_end[0]] = cpu_to_le32(pcimem_end - 1);
+    if (pcimem64_start) {
+        ssdt_ptr[acpi_pci64_valid[0]] = 1;
+        *(u64*)&ssdt_ptr[acpi_pci64_start[0]] = cpu_to_le64(pcimem64_start);
+        *(u64*)&ssdt_ptr[acpi_pci64_end[0]] = cpu_to_le64(pcimem64_end - 1);
+        *(u64*)&ssdt_ptr[acpi_pci64_length[0]] = cpu_to_le64(
+            pcimem64_end - pcimem64_start);
+    } else {
+        ssdt_ptr[acpi_pci64_valid[0]] = 0;
+    }
+
+    int pvpanic_port = romfile_loadint("etc/pvpanic-port", 0x0);
+    *(u16 *)(ssdt_ptr + *ssdt_isa_pest) = pvpanic_port;
+
+    ssdt_ptr += sizeof(ssdp_misc_aml);
+
+    // build Scope(_SB_) header
+    *(ssdt_ptr++) = 0x10; // ScopeOp
+    ssdt_ptr = encodeLen(ssdt_ptr, length - (ssdt_ptr - ssdt), 3);
+    *(ssdt_ptr++) = '_';
+    *(ssdt_ptr++) = 'S';
+    *(ssdt_ptr++) = 'B';
+    *(ssdt_ptr++) = '_';
+
+    // build Processor object for each processor
+    int i;
+    for (i=0; i<acpi_cpus; i++) {
+        memcpy(ssdt_ptr, PROC_AML, PROC_SIZEOF);
+        ssdt_ptr[PROC_OFFSET_CPUHEX] = getHex(i >> 4);
+        ssdt_ptr[PROC_OFFSET_CPUHEX+1] = getHex(i);
+        ssdt_ptr[PROC_OFFSET_CPUID1] = i;
+        ssdt_ptr[PROC_OFFSET_CPUID2] = i;
+        ssdt_ptr += PROC_SIZEOF;
+    }
+
+    // build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}"
+    // Arg0 = Processor ID = APIC ID
+    ssdt_ptr = build_notify(ssdt_ptr, "NTFY", 0, acpi_cpus, "CP00", 2);
+
+    // build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
+    *(ssdt_ptr++) = 0x08; // NameOp
+    *(ssdt_ptr++) = 'C';
+    *(ssdt_ptr++) = 'P';
+    *(ssdt_ptr++) = 'O';
+    *(ssdt_ptr++) = 'N';
+    *(ssdt_ptr++) = 0x12; // PackageOp
+    ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2);
+    *(ssdt_ptr++) = acpi_cpus;
+    for (i=0; i<acpi_cpus; i++)
+        *(ssdt_ptr++) = (apic_id_is_present(i)) ? 0x01 : 0x00;
+
+    // build Scope(PCI0) opcode
+    *(ssdt_ptr++) = 0x10; // ScopeOp
+    ssdt_ptr = encodeLen(ssdt_ptr, length - (ssdt_ptr - ssdt), 3);
+    *(ssdt_ptr++) = 'P';
+    *(ssdt_ptr++) = 'C';
+    *(ssdt_ptr++) = 'I';
+    *(ssdt_ptr++) = '0';
+
+    // build Device object for each slot
+    u32 rmvc_pcrm = inl(PCI_RMV_BASE);
+    for (i=1; i<PCI_SLOTS; i++) {
+        u32 eject = rmvc_pcrm & (0x1 << i);
+        memcpy(ssdt_ptr, PCIHP_AML, PCIHP_SIZEOF);
+        patch_pcihp(i, ssdt_ptr, eject != 0);
+        ssdt_ptr += PCIHP_SIZEOF;
+    }
+
+    ssdt_ptr = build_notify(ssdt_ptr, "PCNT", 1, PCI_SLOTS, "S00_", 1);
+
+    build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
+
+    //hexdump(ssdt, ssdt_ptr - ssdt);
+
+    return ssdt;
+}
+
+#define HPET_ID         0x000
+#define HPET_PERIOD     0x004
+
+static void*
+build_hpet(void)
+{
+    struct acpi_20_hpet *hpet;
+    const void *hpet_base = (void *)BUILD_HPET_ADDRESS;
+    u32 hpet_vendor = readl(hpet_base + HPET_ID) >> 16;
+    u32 hpet_period = readl(hpet_base + HPET_PERIOD);
+
+    if (hpet_vendor == 0 || hpet_vendor == 0xffff ||
+        hpet_period == 0 || hpet_period > 100000000)
+        return NULL;
+
+    hpet = malloc_high(sizeof(*hpet));
+    if (!hpet) {
+        warn_noalloc();
+        return NULL;
+    }
+
+    memset(hpet, 0, sizeof(*hpet));
+    /* Note timer_block_id value must be kept in sync with value advertised by
+     * emulated hpet
+     */
+    hpet->timer_block_id = cpu_to_le32(0x8086a201);
+    hpet->addr.address = cpu_to_le64(BUILD_HPET_ADDRESS);
+    build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1);
+
+    return hpet;
+}
+
+static void
+acpi_build_srat_memory(struct srat_memory_affinity *numamem,
+                       u64 base, u64 len, int node, int enabled)
+{
+    numamem->type = SRAT_MEMORY;
+    numamem->length = sizeof(*numamem);
+    memset(numamem->proximity, 0, 4);
+    numamem->proximity[0] = node;
+    numamem->flags = cpu_to_le32(!!enabled);
+    numamem->base_addr = cpu_to_le64(base);
+    numamem->range_length = cpu_to_le64(len);
+}
+
+static void *
+build_srat(void)
+{
+    int numadatasize, numacpusize;
+    u64 *numadata = romfile_loadfile("etc/numa-nodes", &numadatasize);
+    u64 *numacpumap = romfile_loadfile("etc/numa-cpu-map", &numacpusize);
+    if (!numadata || !numacpumap)
+        goto fail;
+    int max_cpu = numacpusize / sizeof(u64);
+    int nb_numa_nodes = numadatasize / sizeof(u64);
+
+    struct system_resource_affinity_table *srat;
+    int srat_size = sizeof(*srat) +
+        sizeof(struct srat_processor_affinity) * max_cpu +
+        sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
+
+    srat = malloc_high(srat_size);
+    if (!srat) {
+        warn_noalloc();
+        goto fail;
+    }
+
+    memset(srat, 0, srat_size);
+    srat->reserved1=cpu_to_le32(1);
+    struct srat_processor_affinity *core = (void*)(srat + 1);
+    int i;
+    u64 curnode;
+
+    for (i = 0; i < max_cpu; ++i) {
+        core->type = SRAT_PROCESSOR;
+        core->length = sizeof(*core);
+        core->local_apic_id = i;
+        curnode = *numacpumap++;
+        core->proximity_lo = curnode;
+        memset(core->proximity_hi, 0, 3);
+        core->local_sapic_eid = 0;
+        if (apic_id_is_present(i))
+            core->flags = cpu_to_le32(1);
+        else
+            core->flags = cpu_to_le32(0);
+        core++;
+    }
+
+
+    /* the memory map is a bit tricky, it contains at least one hole
+     * from 640k-1M and possibly another one from 3.5G-4G.
+     */
+    struct srat_memory_affinity *numamem = (void*)core;
+    int slots = 0;
+    u64 mem_len, mem_base, next_base = 0;
+
+    acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
+    next_base = 1024 * 1024;
+    numamem++;
+    slots++;
+    for (i = 1; i < nb_numa_nodes + 1; ++i) {
+        mem_base = next_base;
+        mem_len = *numadata++;
+        if (i == 1)
+            mem_len -= 1024 * 1024;
+        next_base = mem_base + mem_len;
+
+        /* Cut out the PCI hole */
+        if (mem_base <= RamSize && next_base > RamSize) {
+            mem_len -= next_base - RamSize;
+            if (mem_len > 0) {
+                acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
+                numamem++;
+                slots++;
+            }
+            mem_base = 1ULL << 32;
+            mem_len = next_base - RamSize;
+            next_base += (1ULL << 32) - RamSize;
+        }
+        acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
+        numamem++;
+        slots++;
+    }
+    for (; slots < nb_numa_nodes + 2; slots++) {
+        acpi_build_srat_memory(numamem, 0, 0, 0, 0);
+        numamem++;
+    }
+
+    build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1);
+
+    free(numadata);
+    free(numacpumap);
+    return srat;
+fail:
+    free(numadata);
+    free(numacpumap);
+    return NULL;
+}
+
+static void *
+build_mcfg_q35(void)
+{
+    struct acpi_table_mcfg *mcfg;
+
+    int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
+    mcfg = malloc_high(len);
+    if (!mcfg) {
+        warn_noalloc();
+        return NULL;
+    }
+    memset(mcfg, 0, len);
+    mcfg->allocation[0].address = cpu_to_le64(Q35_HOST_BRIDGE_PCIEXBAR_ADDR);
+    mcfg->allocation[0].pci_segment = cpu_to_le16(Q35_HOST_PCIE_PCI_SEGMENT);
+    mcfg->allocation[0].start_bus_number = Q35_HOST_PCIE_START_BUS_NUMBER;
+    mcfg->allocation[0].end_bus_number = Q35_HOST_PCIE_END_BUS_NUMBER;
+
+    build_header((void *)mcfg, MCFG_SIGNATURE, len, 1);
+    return mcfg;
+}
+
+static const struct pci_device_id acpi_find_tbl[] = {
+    /* PIIX4 Power Management device. */
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL),
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC, NULL),
+    PCI_DEVICE_END,
+};
+
+struct rsdp_descriptor *RsdpAddr;
+
+#define MAX_ACPI_TABLES 20
+void
+acpi_setup(void)
+{
+    if (! CONFIG_ACPI)
+        return;
+
+    dprintf(3, "init ACPI tables\n");
+
+    // This code is hardcoded for PIIX4 Power Management device.
+    struct pci_device *pci = pci_find_init_device(acpi_find_tbl, NULL);
+    if (!pci)
+        // Device not found
+        return;
+
+    // Build ACPI tables
+    u32 tables[MAX_ACPI_TABLES], tbl_idx = 0;
+
+#define ACPI_INIT_TABLE(X)                                   \
+    do {                                                     \
+        tables[tbl_idx] = cpu_to_le32((u32)(X));             \
+        if (le32_to_cpu(tables[tbl_idx]))                    \
+            tbl_idx++;                                       \
+    } while(0)
+
+    struct fadt_descriptor_rev1 *fadt = build_fadt(pci);
+    ACPI_INIT_TABLE(fadt);
+    ACPI_INIT_TABLE(build_ssdt());
+    ACPI_INIT_TABLE(build_madt());
+    ACPI_INIT_TABLE(build_hpet());
+    ACPI_INIT_TABLE(build_srat());
+    if (pci->device == PCI_DEVICE_ID_INTEL_ICH9_LPC)
+        ACPI_INIT_TABLE(build_mcfg_q35());
+
+    struct romfile_s *file = NULL;
+    for (;;) {
+        file = romfile_findprefix("acpi/", file);
+        if (!file)
+            break;
+        struct acpi_table_header *table = malloc_high(file->size);
+        if (!table) {
+            warn_noalloc();
+            continue;
+        }
+        int ret = file->copy(file, table, file->size);
+        if (ret <= sizeof(*table))
+            continue;
+        if (table->signature == DSDT_SIGNATURE) {
+            if (fadt) {
+                fill_dsdt(fadt, table);
+            }
+        } else {
+            ACPI_INIT_TABLE(table);
+        }
+        if (tbl_idx == MAX_ACPI_TABLES) {
+            warn_noalloc();
+            break;
+        }
+    }
+
+    if (CONFIG_ACPI_DSDT && fadt && !fadt->dsdt) {
+        /* default DSDT */
+        void *dsdt = malloc_high(sizeof(AmlCode));
+        if (!dsdt) {
+            warn_noalloc();
+            return;
+        }
+        memcpy(dsdt, AmlCode, sizeof(AmlCode));
+        fill_dsdt(fadt, dsdt);
+    }
+
+    // Build final rsdt table
+    struct rsdt_descriptor_rev1 *rsdt;
+    size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx;
+    rsdt = malloc_high(rsdt_len);
+    if (!rsdt) {
+        warn_noalloc();
+        return;
+    }
+    memset(rsdt, 0, rsdt_len);
+    memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx);
+    build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
+
+    // Build rsdp pointer table
+    struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
+    if (!rsdp) {
+        warn_noalloc();
+        return;
+    }
+    memset(rsdp, 0, sizeof(*rsdp));
+    rsdp->signature = cpu_to_le64(RSDP_SIGNATURE);
+    memcpy(rsdp->oem_id, BUILD_APPNAME6, 6);
+    rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt);
+    rsdp->checksum -= checksum(rsdp, 20);
+    RsdpAddr = rsdp;
+    dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt);
+}
+
+static struct fadt_descriptor_rev1 *
+find_fadt(void)
+{
+    dprintf(4, "rsdp=%p\n", RsdpAddr);
+    if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE)
+        return NULL;
+    struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address;
+    dprintf(4, "rsdt=%p\n", rsdt);
+    if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
+        return NULL;
+    void *end = (void*)rsdt + rsdt->length;
+    int i;
+    for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
+        struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i];
+        if (!fadt || fadt->signature != FACP_SIGNATURE)
+            continue;
+        dprintf(4, "fadt=%p\n", fadt);
+        return fadt;
+    }
+    dprintf(4, "no fadt found\n");
+    return NULL;
+}
+
+u32
+find_resume_vector(void)
+{
+    struct fadt_descriptor_rev1 *fadt = find_fadt();
+    if (!fadt)
+        return 0;
+    struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
+    dprintf(4, "facs=%p\n", facs);
+    if (! facs || facs->signature != FACS_SIGNATURE)
+        return 0;
+    // Found it.
+    dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector);
+    return facs->firmware_waking_vector;
+}
+
+void
+find_acpi_features(void)
+{
+    struct fadt_descriptor_rev1 *fadt = find_fadt();
+    if (!fadt)
+        return;
+    u32 pm_tmr = le32_to_cpu(fadt->pm_tmr_blk);
+    u32 pm1a_cnt = le32_to_cpu(fadt->pm1a_cnt_blk);
+    dprintf(4, "pm_tmr_blk=%x\n", pm_tmr);
+    if (pm_tmr)
+        pmtimer_setup(pm_tmr);
+    if (pm1a_cnt)
+        acpi_pm1a_cnt = pm1a_cnt;
+
+    // Theoretically we should check the 'reset_reg_sup' flag, but Windows
+    // doesn't and thus nobody seems to *set* it. If the table is large enough
+    // to include it, let the sanity checks in acpi_set_reset_reg() suffice.
+    if (fadt->length >= 129) {
+        void *p = fadt;
+        acpi_set_reset_reg(p + 116, *(u8 *)(p + 128));
+    }
+}
+
+static struct acpi_20_generic_address acpi_reset_reg;
+static u8 acpi_reset_val;
+
+void
+acpi_reboot(void)
+{
+    // Check it passed the sanity checks in acpi_set_reset_reg() and was set
+    if (acpi_reset_reg.register_bit_width != 8)
+        return;
+
+    u64 addr = le64_to_cpu(acpi_reset_reg.address);
+
+    dprintf(1, "ACPI hard reset %d:%llx (%x)\n",
+            acpi_reset_reg.address_space_id, addr, acpi_reset_val);
+
+    switch (acpi_reset_reg.address_space_id) {
+    case 0: // System Memory
+       writeb((void *)(u32)addr, acpi_reset_val);
+        break;
+    case 1: // System I/O
+        outb(acpi_reset_val, addr);
+        break;
+    case 2: // PCI config space
+        pci_config_writeb(acpi_ga_to_bdf(addr), addr & 0xffff, acpi_reset_val);
+        break;
+    }
+}
+
+void
+acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val)
+{
+    if (!reg || reg->address_space_id > 2 ||
+        reg->register_bit_width != 8 || reg->register_bit_offset)
+        return;
+
+    acpi_reset_reg = *reg;
+    acpi_reset_val = val;
+}
diff --git a/src/fw/acpi.h b/src/fw/acpi.h
new file mode 100644 (file)
index 0000000..f0d24d4
--- /dev/null
@@ -0,0 +1,282 @@
+#ifndef __ACPI_H
+#define __ACPI_H
+
+#include "types.h" // u32
+
+/*
+ * ACPI 2.0 Generic Address Space definition.
+ */
+struct acpi_20_generic_address {
+    u8  address_space_id;
+    u8  register_bit_width;
+    u8  register_bit_offset;
+    u8  reserved;
+    u64 address;
+} PACKED;
+#define acpi_ga_to_bdf(addr) pci_to_bdf(0, (addr >> 32) & 0xffff, (addr >> 16) & 0xffff)
+
+void acpi_setup(void);
+u32 find_resume_vector(void);
+void find_acpi_features(void);
+void acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val);
+void acpi_reboot(void);
+
+#define RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
+
+struct rsdp_descriptor {        /* Root System Descriptor Pointer */
+    u64 signature;              /* ACPI signature, contains "RSD PTR " */
+    u8  checksum;               /* To make sum of struct == 0 */
+    u8  oem_id [6];             /* OEM identification */
+    u8  revision;               /* Must be 0 for 1.0, 2 for 2.0 */
+    u32 rsdt_physical_address;  /* 32-bit physical address of RSDT */
+    u32 length;                 /* XSDT Length in bytes including hdr */
+    u64 xsdt_physical_address;  /* 64-bit physical address of XSDT */
+    u8  extended_checksum;      /* Checksum of entire table */
+    u8  reserved [3];           /* Reserved field must be 0 */
+};
+
+extern struct rsdp_descriptor *RsdpAddr;
+extern u32 acpi_pm1a_cnt;
+
+/* Table structure from Linux kernel (the ACPI tables are under the
+   BSD license) */
+
+#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
+    u32 signature;          /* ACPI signature (4 ASCII characters) */ \
+    u32 length;                 /* Length of table, in bytes, including header */ \
+    u8  revision;               /* ACPI Specification minor version # */ \
+    u8  checksum;               /* To make sum of entire table == 0 */ \
+    u8  oem_id [6];             /* OEM identification */ \
+    u8  oem_table_id [8];       /* OEM table identification */ \
+    u32 oem_revision;           /* OEM revision number */ \
+    u8  asl_compiler_id [4];    /* ASL compiler vendor ID */ \
+    u32 asl_compiler_revision;  /* ASL compiler revision number */
+
+
+/*
+ * ACPI 1.0 Fixed ACPI Description Table (FADT)
+ */
+#define FACP_SIGNATURE 0x50434146 // FACP
+struct fadt_descriptor_rev1
+{
+    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
+    u32 firmware_ctrl;          /* Physical address of FACS */
+    u32 dsdt;                   /* Physical address of DSDT */
+    u8  model;                  /* System Interrupt Model */
+    u8  reserved1;              /* Reserved */
+    u16 sci_int;                /* System vector of SCI interrupt */
+    u32 smi_cmd;                /* Port address of SMI command port */
+    u8  acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
+    u8  acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
+    u8  S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
+    u8  reserved2;              /* Reserved - must be zero */
+    u32 pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
+    u32 pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
+    u32 pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
+    u32 pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
+    u32 pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
+    u32 pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
+    u32 gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
+    u32 gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
+    u8  pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
+    u8  pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
+    u8  pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
+    u8  pm_tmr_len;             /* Byte Length of ports at pm_tm_blk */
+    u8  gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
+    u8  gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
+    u8  gpe1_base;              /* Offset in gpe model where gpe1 events start */
+    u8  reserved3;              /* Reserved */
+    u16 plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
+    u16 plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
+    u16 flush_size;             /* Size of area read to flush caches */
+    u16 flush_stride;           /* Stride used in flushing caches */
+    u8  duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
+    u8  duty_width;             /* Bit width of duty cycle field in p_cnt reg */
+    u8  day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
+    u8  mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
+    u8  century;                /* Index to century in RTC CMOS RAM */
+    u8  reserved4;              /* Reserved */
+    u8  reserved4a;             /* Reserved */
+    u8  reserved4b;             /* Reserved */
+    u32 flags;
+} PACKED;
+
+struct acpi_table_header         /* ACPI common table header */
+{
+    ACPI_TABLE_HEADER_DEF
+} PACKED;
+
+/*
+ * ACPI 1.0 Root System Description Table (RSDT)
+ */
+#define RSDT_SIGNATURE 0x54445352 // RSDT
+struct rsdt_descriptor_rev1
+{
+    ACPI_TABLE_HEADER_DEF       /* ACPI common table header */
+    u32 table_offset_entry[0];  /* Array of pointers to other */
+    /* ACPI tables */
+} PACKED;
+
+/*
+ * ACPI 1.0 Firmware ACPI Control Structure (FACS)
+ */
+#define FACS_SIGNATURE 0x53434146 // FACS
+struct facs_descriptor_rev1
+{
+    u32 signature;           /* ACPI Signature */
+    u32 length;                 /* Length of structure, in bytes */
+    u32 hardware_signature;     /* Hardware configuration signature */
+    u32 firmware_waking_vector; /* ACPI OS waking vector */
+    u32 global_lock;            /* Global Lock */
+    u32 flags;
+    u8  resverved3 [40];        /* Reserved - must be zero */
+} PACKED;
+
+/*
+ * Differentiated System Description Table (DSDT)
+ */
+#define DSDT_SIGNATURE 0x54445344 // DSDT
+
+/*
+ * MADT values and structures
+ */
+
+/* Values for MADT PCATCompat */
+
+#define DUAL_PIC                0
+#define MULTIPLE_APIC           1
+
+/* Master MADT */
+
+#define APIC_SIGNATURE 0x43495041 // APIC
+struct multiple_apic_table
+{
+    ACPI_TABLE_HEADER_DEF     /* ACPI common table header */
+    u32 local_apic_address;     /* Physical address of local APIC */
+    u32 flags;
+} PACKED;
+
+/* Values for Type in APIC sub-headers */
+
+#define APIC_PROCESSOR          0
+#define APIC_IO                 1
+#define APIC_XRUPT_OVERRIDE     2
+#define APIC_NMI                3
+#define APIC_LOCAL_NMI          4
+#define APIC_ADDRESS_OVERRIDE   5
+#define APIC_IO_SAPIC           6
+#define APIC_LOCAL_SAPIC        7
+#define APIC_XRUPT_SOURCE       8
+#define APIC_RESERVED           9           /* 9 and greater are reserved */
+
+/*
+ * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
+ */
+#define ACPI_SUB_HEADER_DEF   /* Common ACPI sub-structure header */\
+    u8  type;                               \
+    u8  length;
+
+/* Sub-structures for MADT */
+
+struct madt_processor_apic
+{
+    ACPI_SUB_HEADER_DEF
+    u8  processor_id;           /* ACPI processor id */
+    u8  local_apic_id;          /* Processor's local APIC id */
+    u32 flags;
+} PACKED;
+
+struct madt_io_apic
+{
+    ACPI_SUB_HEADER_DEF
+    u8  io_apic_id;             /* I/O APIC ID */
+    u8  reserved;               /* Reserved - must be zero */
+    u32 address;                /* APIC physical address */
+    u32 interrupt;              /* Global system interrupt where INTI
+                                 * lines start */
+} PACKED;
+
+struct madt_intsrcovr {
+    ACPI_SUB_HEADER_DEF
+    u8  bus;
+    u8  source;
+    u32 gsi;
+    u16 flags;
+} PACKED;
+
+struct madt_local_nmi {
+    ACPI_SUB_HEADER_DEF
+    u8  processor_id;           /* ACPI processor id */
+    u16 flags;                  /* MPS INTI flags */
+    u8  lint;                   /* Local APIC LINT# */
+} PACKED;
+
+/*
+ * HPET Description Table
+ */
+#define HPET_SIGNATURE 0x54455048 // HPET
+struct acpi_20_hpet {
+    ACPI_TABLE_HEADER_DEF                    /* ACPI common table header */
+    u32           timer_block_id;
+    struct acpi_20_generic_address addr;
+    u8            hpet_number;
+    u16           min_tick;
+    u8            page_protect;
+} PACKED;
+
+/*
+ * SRAT (NUMA topology description) table
+ */
+
+#define SRAT_SIGNATURE 0x54415253 // SRAT
+struct system_resource_affinity_table
+{
+    ACPI_TABLE_HEADER_DEF
+    u32    reserved1;
+    u32    reserved2[2];
+} PACKED;
+
+#define SRAT_PROCESSOR          0
+#define SRAT_MEMORY             1
+
+struct srat_processor_affinity
+{
+    ACPI_SUB_HEADER_DEF
+    u8     proximity_lo;
+    u8     local_apic_id;
+    u32    flags;
+    u8     local_sapic_eid;
+    u8     proximity_hi[3];
+    u32    reserved;
+} PACKED;
+
+struct srat_memory_affinity
+{
+    ACPI_SUB_HEADER_DEF
+    u8     proximity[4];
+    u16    reserved1;
+    u64    base_addr;
+    u64    range_length;
+    u32    reserved2;
+    u32    flags;
+    u32    reserved3[2];
+} PACKED;
+
+/* PCI fw r3.0 MCFG table. */
+/* Subtable */
+struct acpi_mcfg_allocation {
+    u64 address;                /* Base address, processor-relative */
+    u16 pci_segment;            /* PCI segment group number */
+    u8 start_bus_number;       /* Starting PCI Bus number */
+    u8 end_bus_number;         /* Final PCI Bus number */
+    u32 reserved;
+} PACKED;
+
+#define MCFG_SIGNATURE 0x4746434d       // MCFG
+struct acpi_table_mcfg {
+    ACPI_TABLE_HEADER_DEF;
+    u8 reserved[8];
+    struct acpi_mcfg_allocation allocation[0];
+} PACKED;
+
+#endif // acpi.h
diff --git a/src/fw/biostables.c b/src/fw/biostables.c
new file mode 100644 (file)
index 0000000..beb0bed
--- /dev/null
@@ -0,0 +1,117 @@
+// Coreboot interface support.
+//
+// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_*
+#include "util.h" // dprintf
+#include "hw/pci.h" // struct pir_header
+#include "acpi.h" // struct rsdp_descriptor
+#include "mptable.h" // MPTABLE_SIGNATURE
+#include "smbios.h" // struct smbios_entry_point
+
+static void
+copy_pir(void *pos)
+{
+    struct pir_header *p = pos;
+    if (p->signature != PIR_SIGNATURE)
+        return;
+    if (PirAddr)
+        return;
+    if (p->size < sizeof(*p))
+        return;
+    if (checksum(pos, p->size) != 0)
+        return;
+    void *newpos = malloc_fseg(p->size);
+    if (!newpos) {
+        warn_noalloc();
+        return;
+    }
+    dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
+    memcpy(newpos, pos, p->size);
+    PirAddr = newpos;
+}
+
+static void
+copy_mptable(void *pos)
+{
+    struct mptable_floating_s *p = pos;
+    if (p->signature != MPTABLE_SIGNATURE)
+        return;
+    if (!p->physaddr)
+        return;
+    if (checksum(pos, sizeof(*p)) != 0)
+        return;
+    u32 length = p->length * 16;
+    u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
+    struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
+    if (!newpos) {
+        warn_noalloc();
+        return;
+    }
+    dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
+    memcpy(newpos, pos, length);
+    newpos->physaddr = (u32)newpos + length;
+    newpos->checksum -= checksum(newpos, sizeof(*newpos));
+    memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
+}
+
+static void
+copy_acpi_rsdp(void *pos)
+{
+    if (RsdpAddr)
+        return;
+    struct rsdp_descriptor *p = pos;
+    if (p->signature != RSDP_SIGNATURE)
+        return;
+    u32 length = 20;
+    if (checksum(pos, length) != 0)
+        return;
+    if (p->revision > 1) {
+        length = p->length;
+        if (checksum(pos, length) != 0)
+            return;
+    }
+    void *newpos = malloc_fseg(length);
+    if (!newpos) {
+        warn_noalloc();
+        return;
+    }
+    dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
+    memcpy(newpos, pos, length);
+    RsdpAddr = newpos;
+}
+
+void
+copy_smbios(void *pos)
+{
+    if (SMBiosAddr)
+        return;
+    struct smbios_entry_point *p = pos;
+    if (memcmp(p->anchor_string, "_SM_", 4))
+        return;
+    if (checksum(pos, 0x10) != 0)
+        return;
+    if (memcmp(p->intermediate_anchor_string, "_DMI_", 5))
+        return;
+    if (checksum(pos+0x10, p->length-0x10) != 0)
+        return;
+    struct smbios_entry_point *newpos = malloc_fseg(p->length);
+    if (!newpos) {
+        warn_noalloc();
+        return;
+    }
+    dprintf(1, "Copying SMBIOS entry point from %p to %p\n", pos, newpos);
+    memcpy(newpos, pos, p->length);
+    SMBiosAddr = newpos;
+}
+
+void
+copy_table(void *pos)
+{
+    copy_pir(pos);
+    copy_mptable(pos);
+    copy_acpi_rsdp(pos);
+    copy_smbios(pos);
+}
diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c
new file mode 100644 (file)
index 0000000..126649a
--- /dev/null
@@ -0,0 +1,501 @@
+// Coreboot interface support.
+//
+// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "memmap.h" // add_e820
+#include "util.h" // dprintf
+#include "byteorder.h" // be32_to_cpu
+#include "lzmadecode.h" // LzmaDecode
+#include "smbios.h" // smbios_init
+#include "boot.h" // boot_add_cbfs
+#include "disk.h" // MAXDESCSIZE
+#include "config.h" // CONFIG_*
+#include "acpi.h" // find_acpi_features
+#include "hw/pci.h" // pci_probe_devices
+#include "paravirt.h" // PlatformRunningOn
+
+
+/****************************************************************
+ * Memory map
+ ****************************************************************/
+
+struct cb_header {
+    u32 signature;
+    u32 header_bytes;
+    u32 header_checksum;
+    u32 table_bytes;
+    u32 table_checksum;
+    u32 table_entries;
+};
+
+#define CB_SIGNATURE 0x4f49424C // "LBIO"
+
+struct cb_memory_range {
+    u64 start;
+    u64 size;
+    u32 type;
+};
+
+#define CB_MEM_TABLE    16
+
+struct cb_memory {
+    u32 tag;
+    u32 size;
+    struct cb_memory_range map[0];
+};
+
+#define CB_TAG_MEMORY 0x01
+
+#define MEM_RANGE_COUNT(_rec) \
+        (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))
+
+struct cb_mainboard {
+    u32 tag;
+    u32 size;
+    u8  vendor_idx;
+    u8  part_idx;
+    char  strings[0];
+};
+
+#define CB_TAG_MAINBOARD 0x0003
+
+struct cb_forward {
+    u32 tag;
+    u32 size;
+    u64 forward;
+};
+
+#define CB_TAG_FORWARD 0x11
+
+struct cb_cbmem_ref {
+    u32 tag;
+    u32 size;
+    u64 cbmem_addr;
+};
+
+#define CB_TAG_CBMEM_CONSOLE 0x17
+
+struct cbmem_console {
+       u32 buffer_size;
+       u32 buffer_cursor;
+       u8  buffer_body[0];
+} PACKED;
+static struct cbmem_console *cbcon = NULL;
+
+static u16
+ipchksum(char *buf, int count)
+{
+    u16 *p = (u16*)buf;
+    u32 sum = 0;
+    while (count > 1) {
+        sum += *p++;
+        count -= 2;
+    }
+    if (count)
+        sum += *(u8*)p;
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+    return ~sum;
+}
+
+// Try to locate the coreboot header in a given address range.
+static struct cb_header *
+find_cb_header(char *addr, int len)
+{
+    char *end = addr + len;
+    for (; addr < end; addr += 16) {
+        struct cb_header *cbh = (struct cb_header *)addr;
+        if (cbh->signature != CB_SIGNATURE)
+            continue;
+        if (! cbh->table_bytes)
+            continue;
+        if (ipchksum(addr, sizeof(*cbh)) != 0)
+            continue;
+        if (ipchksum(addr + sizeof(*cbh), cbh->table_bytes)
+            != cbh->table_checksum)
+            continue;
+        return cbh;
+    }
+    return NULL;
+}
+
+// Try to find the coreboot memory table in the given coreboot table.
+static void *
+find_cb_subtable(struct cb_header *cbh, u32 tag)
+{
+    char *tbl = (char *)cbh + sizeof(*cbh);
+    int i;
+    for (i=0; i<cbh->table_entries; i++) {
+        struct cb_memory *cbm = (struct cb_memory *)tbl;
+        tbl += cbm->size;
+        if (cbm->tag == tag)
+            return cbm;
+    }
+    return NULL;
+}
+
+static struct cb_memory *CBMemTable;
+const char *CBvendor = "", *CBpart = "";
+
+// Populate max ram and e820 map info by scanning for a coreboot table.
+void
+coreboot_preinit(void)
+{
+    if (!CONFIG_COREBOOT)
+        return;
+
+    dprintf(3, "Attempting to find coreboot table\n");
+
+    // Find coreboot table.
+    struct cb_header *cbh = find_cb_header(0, 0x1000);
+    if (!cbh)
+        goto fail;
+    struct cb_forward *cbf = find_cb_subtable(cbh, CB_TAG_FORWARD);
+    if (cbf) {
+        dprintf(3, "Found coreboot table forwarder.\n");
+        cbh = find_cb_header((char *)((u32)cbf->forward), 0x100);
+        if (!cbh)
+            goto fail;
+    }
+    dprintf(3, "Now attempting to find coreboot memory map\n");
+    struct cb_memory *cbm = CBMemTable = find_cb_subtable(cbh, CB_TAG_MEMORY);
+    if (!cbm)
+        goto fail;
+
+    int i, count = MEM_RANGE_COUNT(cbm);
+    for (i=0; i<count; i++) {
+        struct cb_memory_range *m = &cbm->map[i];
+        u32 type = m->type;
+        if (type == CB_MEM_TABLE)
+            type = E820_RESERVED;
+        add_e820(m->start, m->size, type);
+    }
+
+    // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this
+    // confuses grub.  So, override it.
+    add_e820(0, 16*1024, E820_RAM);
+
+    struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, CB_TAG_CBMEM_CONSOLE);
+    if (cbref) {
+        cbcon = (void*)(u32)cbref->cbmem_addr;
+        dprintf(1, "----- [ seabios log starts here ] -----\n");
+        dprintf(1, "Found coreboot cbmem console @ %llx\n", cbref->cbmem_addr);
+    }
+
+    struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD);
+    if (cbmb) {
+        CBvendor = &cbmb->strings[cbmb->vendor_idx];
+        CBpart = &cbmb->strings[cbmb->part_idx];
+        if (strcmp(CBvendor, "Emulation") == 0 &&
+            memcmp(CBpart, "QEMU", 4) == 0) {
+            PlatformRunningOn |= PF_QEMU;
+        }
+        dprintf(1, "Found mainboard %s %s\n", CBvendor, CBpart);
+    }
+
+    return;
+
+fail:
+    // No table found..  Use 16Megs as a dummy value.
+    dprintf(1, "Unable to find coreboot table!\n");
+    add_e820(0, 16*1024*1024, E820_RAM);
+    return;
+}
+
+void debug_cbmem(char c)
+{
+    if (!CONFIG_DEBUG_COREBOOT)
+        return;
+    if (!cbcon)
+        return;
+    if (cbcon->buffer_cursor == cbcon->buffer_size)
+        return;
+    cbcon->buffer_body[cbcon->buffer_cursor++] = c;
+}
+
+/****************************************************************
+ * BIOS table copying
+ ****************************************************************/
+
+// Attempt to find (and relocate) any standard bios tables found in a
+// given address range.
+static void
+scan_tables(u32 start, u32 size)
+{
+    void *p = (void*)ALIGN(start, 16);
+    void *end = (void*)start + size;
+    for (; p<end; p += 16)
+        copy_table(p);
+}
+
+void
+coreboot_platform_setup(void)
+{
+    if (!CONFIG_COREBOOT)
+        return;
+    pci_probe_devices();
+
+    struct cb_memory *cbm = CBMemTable;
+    if (!cbm)
+        return;
+
+    dprintf(3, "Relocating coreboot bios tables\n");
+
+    // Scan CB_MEM_TABLE areas for bios tables.
+    int i, count = MEM_RANGE_COUNT(cbm);
+    for (i=0; i<count; i++) {
+        struct cb_memory_range *m = &cbm->map[i];
+        if (m->type == CB_MEM_TABLE)
+            scan_tables(m->start, m->size);
+    }
+
+    find_acpi_features();
+}
+
+
+/****************************************************************
+ * ulzma
+ ****************************************************************/
+
+// Uncompress data in flash to an area of memory.
+static int
+ulzma(u8 *dst, u32 maxlen, const u8 *src, u32 srclen)
+{
+    dprintf(3, "Uncompressing data %d@%p to %d@%p\n", srclen, src, maxlen, dst);
+    CLzmaDecoderState state;
+    int ret = LzmaDecodeProperties(&state.Properties, src, LZMA_PROPERTIES_SIZE);
+    if (ret != LZMA_RESULT_OK) {
+        dprintf(1, "LzmaDecodeProperties error - %d\n", ret);
+        return -1;
+    }
+    u8 scratch[15980];
+    int need = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+    if (need > sizeof(scratch)) {
+        dprintf(1, "LzmaDecode need %d have %d\n", need, (unsigned int)sizeof(scratch));
+        return -1;
+    }
+    state.Probs = (CProb *)scratch;
+
+    u32 dstlen = *(u32*)(src + LZMA_PROPERTIES_SIZE);
+    if (dstlen > maxlen) {
+        dprintf(1, "LzmaDecode too large (max %d need %d)\n", maxlen, dstlen);
+        return -1;
+    }
+    u32 inProcessed, outProcessed;
+    ret = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, srclen
+                     , &inProcessed, dst, dstlen, &outProcessed);
+    if (ret) {
+        dprintf(1, "LzmaDecode returned %d\n", ret);
+        return -1;
+    }
+    return dstlen;
+}
+
+
+/****************************************************************
+ * Coreboot flash format
+ ****************************************************************/
+
+#define CBFS_HEADER_MAGIC 0x4F524243
+#define CBFS_HEADPTR_ADDR 0xFFFFFFFc
+#define CBFS_VERSION1 0x31313131
+
+struct cbfs_header {
+    u32 magic;
+    u32 version;
+    u32 romsize;
+    u32 bootblocksize;
+    u32 align;
+    u32 offset;
+    u32 pad[2];
+} PACKED;
+
+#define CBFS_FILE_MAGIC 0x455649484352414cLL // LARCHIVE
+
+struct cbfs_file {
+    u64 magic;
+    u32 len;
+    u32 type;
+    u32 checksum;
+    u32 offset;
+    char filename[0];
+} PACKED;
+
+struct cbfs_romfile_s {
+    struct romfile_s file;
+    struct cbfs_file *fhdr;
+    void *data;
+    u32 rawsize, flags;
+};
+
+// Copy a file to memory (uncompressing if necessary)
+static int
+cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen)
+{
+    if (!CONFIG_COREBOOT_FLASH)
+        return -1;
+
+    struct cbfs_romfile_s *cfile;
+    cfile = container_of(file, struct cbfs_romfile_s, file);
+    u32 size = cfile->rawsize;
+    void *src = cfile->data;
+    if (cfile->flags) {
+        // Compressed - copy to temp ram and uncompress it.
+        void *temp = malloc_tmphigh(size);
+        if (!temp) {
+            warn_noalloc();
+            return -1;
+        }
+        iomemcpy(temp, src, size);
+        int ret = ulzma(dst, maxlen, temp, size);
+        yield();
+        free(temp);
+        return ret;
+    }
+
+    // Not compressed.
+    dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst);
+    if (size > maxlen) {
+        warn_noalloc();
+        return -1;
+    }
+    iomemcpy(dst, src, size);
+    return size;
+}
+
+void
+coreboot_cbfs_init(void)
+{
+    if (!CONFIG_COREBOOT_FLASH)
+        return;
+
+    struct cbfs_header *hdr = *(void **)CBFS_HEADPTR_ADDR;
+    if (hdr->magic != cpu_to_be32(CBFS_HEADER_MAGIC)) {
+        dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n"
+                , hdr, hdr->magic, cpu_to_be32(CBFS_HEADER_MAGIC));
+        return;
+    }
+    dprintf(1, "Found CBFS header at %p\n", hdr);
+
+    struct cbfs_file *fhdr = (void *)(0 - be32_to_cpu(hdr->romsize)
+                                      + be32_to_cpu(hdr->offset));
+    for (;;) {
+        if (fhdr < (struct cbfs_file *)(0xFFFFFFFF - be32_to_cpu(hdr->romsize)))
+            break;
+        u64 magic = fhdr->magic;
+        if (magic != CBFS_FILE_MAGIC)
+            break;
+        struct cbfs_romfile_s *cfile = malloc_tmp(sizeof(*cfile));
+        if (!cfile) {
+            warn_noalloc();
+            break;
+        }
+        memset(cfile, 0, sizeof(*cfile));
+        strtcpy(cfile->file.name, fhdr->filename, sizeof(cfile->file.name));
+        cfile->file.size = cfile->rawsize = be32_to_cpu(fhdr->len);
+        cfile->fhdr = fhdr;
+        cfile->file.copy = cbfs_copyfile;
+        cfile->data = (void*)fhdr + be32_to_cpu(fhdr->offset);
+        int len = strlen(cfile->file.name);
+        if (len > 5 && strcmp(&cfile->file.name[len-5], ".lzma") == 0) {
+            // Using compression.
+            cfile->flags = 1;
+            cfile->file.name[len-5] = '\0';
+            cfile->file.size = *(u32*)(cfile->data + LZMA_PROPERTIES_SIZE);
+        }
+        romfile_add(&cfile->file);
+
+        fhdr = (void*)ALIGN((u32)cfile->data + cfile->rawsize
+                            , be32_to_cpu(hdr->align));
+    }
+}
+
+struct cbfs_payload_segment {
+    u32 type;
+    u32 compression;
+    u32 offset;
+    u64 load_addr;
+    u32 len;
+    u32 mem_len;
+} PACKED;
+
+#define PAYLOAD_SEGMENT_BSS    0x20535342
+#define PAYLOAD_SEGMENT_ENTRY  0x52544E45
+
+#define CBFS_COMPRESS_NONE  0
+#define CBFS_COMPRESS_LZMA  1
+
+struct cbfs_payload {
+    struct cbfs_payload_segment segments[1];
+};
+
+void
+cbfs_run_payload(struct cbfs_file *fhdr)
+{
+    if (!CONFIG_COREBOOT_FLASH || !fhdr)
+        return;
+    dprintf(1, "Run %s\n", fhdr->filename);
+    struct cbfs_payload *pay = (void*)fhdr + be32_to_cpu(fhdr->offset);
+    struct cbfs_payload_segment *seg = pay->segments;
+    for (;;) {
+        void *src = (void*)pay + be32_to_cpu(seg->offset);
+        void *dest = (void*)(u32)be64_to_cpu(seg->load_addr);
+        u32 src_len = be32_to_cpu(seg->len);
+        u32 dest_len = be32_to_cpu(seg->mem_len);
+        switch (seg->type) {
+        case PAYLOAD_SEGMENT_BSS:
+            dprintf(3, "BSS segment %d@%p\n", dest_len, dest);
+            memset(dest, 0, dest_len);
+            break;
+        case PAYLOAD_SEGMENT_ENTRY: {
+            dprintf(1, "Calling addr %p\n", dest);
+            void (*func)() = dest;
+            func();
+            return;
+        }
+        default:
+            dprintf(3, "Segment %x %d@%p -> %d@%p\n"
+                    , seg->type, src_len, src, dest_len, dest);
+            if (seg->compression == cpu_to_be32(CBFS_COMPRESS_NONE)) {
+                if (src_len > dest_len)
+                    src_len = dest_len;
+                memcpy(dest, src, src_len);
+            } else if (CONFIG_LZMA
+                       && seg->compression == cpu_to_be32(CBFS_COMPRESS_LZMA)) {
+                int ret = ulzma(dest, dest_len, src, src_len);
+                if (ret < 0)
+                    return;
+                src_len = ret;
+            } else {
+                dprintf(1, "No support for compression type %x\n"
+                        , seg->compression);
+                return;
+            }
+            if (dest_len > src_len)
+                memset(dest + src_len, 0, dest_len - src_len);
+            break;
+        }
+        seg++;
+    }
+}
+
+// Register payloads in "img/" directory with boot system.
+void
+cbfs_payload_setup(void)
+{
+    if (!CONFIG_COREBOOT_FLASH)
+        return;
+    struct romfile_s *file = NULL;
+    for (;;) {
+        file = romfile_findprefix("img/", file);
+        if (!file)
+            break;
+        struct cbfs_romfile_s *cfile;
+        cfile = container_of(file, struct cbfs_romfile_s, file);
+        const char *filename = file->name;
+        char *desc = znprintf(MAXDESCSIZE, "Payload [%s]", &filename[4]);
+        boot_add_cbfs(cfile->fhdr, desc, bootprio_find_named_rom(filename, 0));
+    }
+}
diff --git a/src/fw/csm.c b/src/fw/csm.c
new file mode 100644 (file)
index 0000000..0093bee
--- /dev/null
@@ -0,0 +1,330 @@
+// Compatibility Support Module (CSM) for UEFI / EDK-II
+//
+// Copyright Â© 2013 Intel Corporation
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_*
+#include "csm.h"
+#include "util.h" // checksum
+#include "bregs.h"
+#include "optionroms.h"
+#include "hw/pci.h"
+#include "memmap.h"
+#include "biosvar.h"
+#include "post.h"
+#include "acpi.h"
+#include "boot.h"
+#include "smbios.h"
+#include "hw/pic.h"
+
+struct rsdp_descriptor csm_rsdp VARFSEG __aligned(16);
+
+EFI_COMPATIBILITY16_TABLE csm_compat_table VARFSEG __aligned(16) = {
+    .Signature = 0x24454649,
+    .TableChecksum = 0 /* Filled in by checkrom.py */,
+    .TableLength = sizeof(csm_compat_table),
+    .Compatibility16CallSegment = SEG_BIOS,
+    .Compatibility16CallOffset = 0 /* Filled in by checkrom.py */,
+    .OemIdStringPointer = (u32)"SeaBIOS",
+    .AcpiRsdPtrPointer = (u32)&csm_rsdp,
+};
+
+EFI_TO_COMPATIBILITY16_INIT_TABLE *csm_init_table;
+EFI_TO_COMPATIBILITY16_BOOT_TABLE *csm_boot_table;
+
+static u16 PICMask = PIC_IRQMASK_DEFAULT;
+
+extern void __csm_return(struct bregs *regs) __noreturn;
+
+static void
+csm_return(struct bregs *regs)
+{
+    dprintf(3, "handle_csm returning AX=%04x\n", regs->ax);
+
+    PICMask = pic_irqmask_read();
+    __csm_return(regs);
+}
+
+static void
+csm_maininit(struct bregs *regs)
+{
+    interface_init();
+    pci_probe_devices();
+
+    csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS;
+    csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();
+
+    regs->ax = 0;
+
+    csm_return(regs);
+}
+
+/* Legacy16InitializeYourself */
+static void
+handle_csm_0000(struct bregs *regs)
+{
+    dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es,
+            regs->bx);
+
+    csm_init_table = MAKE_FLATPTR(regs->es, regs->bx);
+
+    dprintf(3, "BiosLessThan1MB %08x\n", csm_init_table->BiosLessThan1MB);
+    dprintf(3, "HiPmmMemory     %08x\n", csm_init_table->HiPmmMemory);
+    dprintf(3, "HiPmmMemorySize %08x\n", csm_init_table->HiPmmMemorySizeInBytes);
+    dprintf(3, "ReverseThunk    %04x:%04x\n", csm_init_table->ReverseThunkCallSegment,
+            csm_init_table->ReverseThunkCallOffset);
+    dprintf(3, "NumE820Entries  %08x\n", csm_init_table->NumberE820Entries);
+    dprintf(3, "OsMemoryAbove1M %08x\n", csm_init_table->OsMemoryAbove1Mb);
+    dprintf(3, "ThunkStart      %08x\n", csm_init_table->ThunkStart);
+    dprintf(3, "ThunkSize       %08x\n", csm_init_table->ThunkSizeInBytes);
+    dprintf(3, "LoPmmMemory     %08x\n", csm_init_table->LowPmmMemory);
+    dprintf(3, "LoPmmMemorySize %08x\n", csm_init_table->LowPmmMemorySizeInBytes);
+
+    csm_malloc_preinit(csm_init_table->LowPmmMemory,
+                       csm_init_table->LowPmmMemorySizeInBytes,
+                       csm_init_table->HiPmmMemory,
+                       csm_init_table->HiPmmMemorySizeInBytes);
+    reloc_preinit(csm_maininit, regs);
+}
+
+/* Legacy16UpdateBbs */
+static void
+handle_csm_0001(struct bregs *regs)
+{
+    if (!CONFIG_BOOT) {
+        regs->ax = 1;
+        return;
+    }
+
+    dprintf(3, "Legacy16UpdateBbs table %04x:%04x\n", regs->es, regs->bx);
+
+    csm_boot_table = MAKE_FLATPTR(regs->es, regs->bx);
+    dprintf(3, "MajorVersion %04x\n", csm_boot_table->MajorVersion);
+    dprintf(3, "MinorVersion %04x\n", csm_boot_table->MinorVersion);
+    dprintf(3, "AcpiTable %08x\n", csm_boot_table->AcpiTable);
+    dprintf(3, "SmbiosTable %08x\n", csm_boot_table->SmbiosTable);
+    dprintf(3, "SmbiosTableLength %08x\n", csm_boot_table->SmbiosTableLength);
+//    dprintf(3, "SioData %08x\n", csm_boot_table->SioData);
+    dprintf(3, "DevicePathType %04x\n", csm_boot_table->DevicePathType);
+    dprintf(3, "PciIrqMask %04x\n", csm_boot_table->PciIrqMask);
+    dprintf(3, "NumberE820Entries %08x\n", csm_boot_table->NumberE820Entries);
+//    dprintf(3, "HddInfo %08x\n", csm_boot_table->HddInfo);
+    dprintf(3, "NumberBbsEntries %08x\n", csm_boot_table->NumberBbsEntries);
+    dprintf(3, "BBsTable %08x\n", csm_boot_table->BbsTable);
+    dprintf(3, "SmmTable %08x\n", csm_boot_table->SmmTable);
+    dprintf(3, "OsMemoryAbove1Mb %08x\n", csm_boot_table->OsMemoryAbove1Mb);
+    dprintf(3, "UnconventionalDeviceTable %08x\n", csm_boot_table->UnconventionalDeviceTable);
+
+    regs->ax = 0;
+}
+
+/* PrepareToBoot */
+static void
+handle_csm_0002(struct bregs *regs)
+{
+    if (!CONFIG_BOOT) {
+        regs->ax = 1;
+        return;
+    }
+
+    dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx);
+
+    struct e820entry *p = (void *)csm_compat_table.E820Pointer;
+    int i;
+    for (i=0; i < csm_compat_table.E820Length / sizeof(struct e820entry); i++)
+        add_e820(p[i].start, p[i].size, p[i].type);
+
+    if (csm_init_table->HiPmmMemorySizeInBytes > BUILD_MAX_HIGHTABLE) {
+        u32 hi_pmm_end = csm_init_table->HiPmmMemory + csm_init_table->HiPmmMemorySizeInBytes;
+        add_e820(hi_pmm_end - BUILD_MAX_HIGHTABLE, BUILD_MAX_HIGHTABLE, E820_RESERVED);
+    }
+
+    // For PCIBIOS 1ab10e
+    if (csm_compat_table.IrqRoutingTablePointer &&
+        csm_compat_table.IrqRoutingTableLength) {
+        PirAddr = (void *)csm_compat_table.IrqRoutingTablePointer;
+        dprintf(3, "CSM PIRQ table at %p\n", PirAddr);
+    }
+
+    // For find_resume_vector()... and find_acpi_features()
+    if (csm_rsdp.signature == RSDP_SIGNATURE) {
+        RsdpAddr = &csm_rsdp;
+        dprintf(3, "CSM ACPI RSDP at %p\n", RsdpAddr);
+
+        find_acpi_features();
+    }
+
+    // SMBIOS table needs to be copied into the f-seg
+    // XX: OVMF doesn't seem to set SmbiosTableLength so don't check it
+    if (csm_boot_table->SmbiosTable && !SMBiosAddr)
+        copy_smbios((void *)csm_boot_table->SmbiosTable);
+
+    // MPTABLE is just there; we don't care where.
+
+    // EFI may have reinitialised the video using its *own* driver.
+    enable_vga_console();
+
+    // EFI fills this in for us. Zero it for now...
+    struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0);
+    bda->hdcount = 0;
+
+    mathcp_setup();
+    timer_setup();
+    clock_setup();
+    device_hardware_setup();
+    wait_threads();
+    interactive_bootmenu();
+
+    prepareboot();
+
+    regs->ax = 0;
+}
+
+/* Boot */
+static void
+handle_csm_0003(struct bregs *regs)
+{
+    if (!CONFIG_BOOT) {
+        regs->ax = 1;
+        return;
+    }
+
+    dprintf(3, "Boot\n");
+
+    startBoot();
+
+    regs->ax = 1;
+}
+
+/* Legacy16DispatchOprom */
+static void
+handle_csm_0005(struct bregs *regs)
+{
+    EFI_DISPATCH_OPROM_TABLE *table = MAKE_FLATPTR(regs->es, regs->bx);
+    struct rom_header *rom;
+    u16 bdf;
+
+    if (!CONFIG_OPTIONROMS) {
+        regs->ax = 1;
+        return;
+    }
+
+    dprintf(3, "Legacy16DispatchOprom rom %p\n", table);
+
+    dprintf(3, "OpromSegment   %04x\n", table->OpromSegment);
+    dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment);
+    dprintf(3, "PnPInstallationCheck %04x:%04x\n",
+            table->PnPInstallationCheckSegment,
+            table->PnPInstallationCheckOffset);
+    dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment);
+
+    rom = MAKE_FLATPTR(table->OpromSegment, 0);
+    bdf = pci_bus_devfn_to_bdf(table->PciBus, table->PciDeviceFunction);
+
+    rom_reserve(rom->size * 512);
+
+    // XX PnP seg/ofs should never be other than default
+    callrom(rom, bdf);
+
+    rom_confirm(rom->size * 512);
+
+    regs->bx = 0; // FIXME
+    regs->ax = 0;
+}
+
+/* Legacy16GetTableAddress */
+static void
+handle_csm_0006(struct bregs *regs)
+{
+    u16 size = regs->cx;
+    u16 align = regs->dx;
+    u16 region = regs->bx; // (1 for F000 seg, 2 for E000 seg, 0 for either)
+    void *chunk = NULL;
+
+    if (!region)
+        region = 3;
+
+    dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n",
+        size, align, region);
+
+    if (region & 2)
+        chunk = pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align);
+    if (!chunk && (region & 1))
+        chunk = pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, align);
+
+    dprintf(3, "Legacy16GetTableAddress size %x align %x region %d yields %p\n",
+        size, align, region, chunk);
+    if (chunk) {
+        regs->ds = FLATPTR_TO_SEG(chunk);
+        regs->bx = FLATPTR_TO_OFFSET(chunk);
+        regs->ax = 0;
+    } else {
+        regs->ax = 1;
+    }
+}
+
+void VISIBLE32INIT
+handle_csm(struct bregs *regs)
+{
+    ASSERT32FLAT();
+
+    if (!CONFIG_CSM)
+        return;
+
+    dprintf(3, "handle_csm regs %p AX=%04x\n", regs, regs->ax);
+
+    pic_irqmask_write(PICMask);
+
+    switch(regs->ax) {
+    case 0000: handle_csm_0000(regs); break;
+    case 0001: handle_csm_0001(regs); break;
+    case 0002: handle_csm_0002(regs); break;
+    case 0003: handle_csm_0003(regs); break;
+//    case 0004: handle_csm_0004(regs); break;
+    case 0005: handle_csm_0005(regs); break;
+    case 0006: handle_csm_0006(regs); break;
+//    case 0007: handle_csm_0007(regs); break;
+//    case 0008: hamdle_csm_0008(regs); break;
+    default: regs->al = 1;
+    }
+
+    csm_return(regs);
+}
+
+int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave)
+{
+    if (!csm_boot_table)
+        return -1;
+    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
+    int index = 1 + (chanid * 2) + slave;
+    dprintf(3, "CSM bootprio for ATA%d,%d (index %d) is %d\n", chanid, slave,
+            index, bbs[index].BootPriority);
+    return bbs[index].BootPriority;
+}
+
+int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid)
+{
+    if (!csm_boot_table)
+        return -1;
+    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
+    dprintf(3, "CSM bootprio for FDC is %d\n", bbs[0].BootPriority);
+    return bbs[0].BootPriority;
+}
+
+int csm_bootprio_pci(struct pci_device *pci)
+{
+    if (!csm_boot_table)
+        return -1;
+    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
+    int i;
+
+    for (i = 5; i < csm_boot_table->NumberBbsEntries; i++) {
+        if (pci->bdf == pci_to_bdf(bbs[i].Bus, bbs[i].Device, bbs[i].Function)) {
+            dprintf(3, "CSM bootprio for PCI(%d,%d,%d) is %d\n", bbs[i].Bus,
+                    bbs[i].Device, bbs[i].Function, bbs[i].BootPriority);
+            return bbs[i].BootPriority;
+        }
+    }
+    return -1;
+}
diff --git a/src/fw/csm.h b/src/fw/csm.h
new file mode 100644 (file)
index 0000000..997e3f7
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __CSM_H
+#define __CSM_H
+
+#include "types.h"
+
+#define UINT8 u8
+#define UINT16 u16
+#define UINT32 u32
+
+// csm.c
+struct pci_device;
+int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid);
+int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave);
+int csm_bootprio_pci(struct pci_device *pci);
+
+#include "LegacyBios.h"
+
+#endif // __CSM_H
diff --git a/src/fw/dev-q35.h b/src/fw/dev-q35.h
new file mode 100644 (file)
index 0000000..6ae039f
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __DEV_Q35_H
+#define __DEV_Q35_H
+
+#include "types.h"      // u16
+
+#define PCI_DEVICE_ID_INTEL_Q35_MCH     0x29c0
+#define Q35_HOST_BRIDGE_PAM0            0x90
+#define Q35_HOST_BRIDGE_SMRAM           0x9d
+#define Q35_HOST_BRIDGE_PCIEXBAR        0x60
+#define Q35_HOST_BRIDGE_PCIEXBAR_SIZE   (256 * 1024 * 1024)
+#define Q35_HOST_BRIDGE_PCIEXBAR_ADDR   0xb0000000
+#define Q35_HOST_BRIDGE_PCIEXBAREN      ((u64)1)
+#define Q35_HOST_PCIE_PCI_SEGMENT       0
+#define Q35_HOST_PCIE_START_BUS_NUMBER  0
+#define Q35_HOST_PCIE_END_BUS_NUMBER    255
+
+#define PCI_DEVICE_ID_INTEL_ICH9_LPC    0x2918
+#define ICH9_LPC_PMBASE                 0x40
+#define ICH9_LPC_PMBASE_RTE             0x1
+
+#define ICH9_LPC_ACPI_CTRL             0x44
+#define ICH9_LPC_ACPI_CTRL_ACPI_EN     0x80
+#define ICH9_LPC_PIRQA_ROUT            0x60
+#define ICH9_LPC_PIRQE_ROUT            0x68
+#define ICH9_LPC_PIRQ_ROUT_IRQEN       0x80
+#define ICH9_LPC_PORT_ELCR1            0x4d0
+#define ICH9_LPC_PORT_ELCR2            0x4d1
+#define PCI_DEVICE_ID_INTEL_ICH9_SMBUS 0x2930
+#define ICH9_SMB_SMB_BASE              0x20
+#define ICH9_SMB_HOSTC                 0x40
+#define ICH9_SMB_HOSTC_HST_EN          0x01
+
+#define ICH9_ACPI_ENABLE               0x2
+#define ICH9_ACPI_DISABLE              0x3
+
+/* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */
+#define ICH9_PMIO_GPE0_STS             0x20
+#define ICH9_PMIO_GPE0_BLK_LEN         0x10
+#define ICH9_PMIO_SMI_EN               0x30
+#define ICH9_PMIO_SMI_EN_APMC_EN       (1 << 5)
+
+/* FADT ACPI_ENABLE/ACPI_DISABLE */
+#define ICH9_APM_ACPI_ENABLE           0x2
+#define ICH9_APM_ACPI_DISABLE          0x3
+
+#endif // dev-q35.h
diff --git a/src/fw/lzmadecode.c b/src/fw/lzmadecode.c
new file mode 100644 (file)
index 0000000..65819b5
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder (optimized for Speed version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "lzmadecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *cp = probs + res; RC_GET_BIT(cp, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+    return LZMA_RESULT_DATA_ERROR;
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+
+  *inSizeProcessed = 0;
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  RC_INIT(inStream, inSize);
+
+
+  while(nowPos < outSize)
+  {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)(
+        (nowPos 
+        )
+        & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        matchByte = outStream[nowPos - rep0];
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (Byte)symbol;
+
+      outStream[nowPos++] = previousByte;
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            
+            if (nowPos == 0)
+              return LZMA_RESULT_DATA_ERROR;
+            
+            state = state < kNumLitStates ? 9 : 11;
+            previousByte = outStream[nowPos - rep0];
+            outStream[nowPos++] = previousByte;
+
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      if (rep0 > nowPos)
+        return LZMA_RESULT_DATA_ERROR;
+
+
+      do
+      {
+        previousByte = outStream[nowPos - rep0];
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+  RC_NORMALIZE;
+
+
+  *inSizeProcessed = (SizeT)(Buffer - inStream);
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
diff --git a/src/fw/lzmadecode.h b/src/fw/lzmadecode.h
new file mode 100644 (file)
index 0000000..dedde0d
--- /dev/null
@@ -0,0 +1,67 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+typedef unsigned char Byte;
+typedef unsigned short UInt16;
+typedef unsigned int UInt32;
+typedef UInt32 SizeT;
+
+#define CProb UInt16
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+
+
+} CLzmaDecoderState;
+
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/src/fw/mptable.c b/src/fw/mptable.c
new file mode 100644 (file)
index 0000000..2d12865
--- /dev/null
@@ -0,0 +1,205 @@
+// MPTable generation (on emulators)
+//
+// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "util.h" // dprintf
+#include "config.h" // CONFIG_*
+#include "mptable.h" // MPTABLE_SIGNATURE
+#include "hw/pci.h"
+#include "hw/pci_regs.h"
+
+void
+mptable_setup(void)
+{
+    if (! CONFIG_MPTABLE)
+        return;
+
+    dprintf(3, "init MPTable\n");
+
+    // Config structure in temp area.
+    struct mptable_config_s *config = malloc_tmp(32*1024);
+    if (!config) {
+        warn_noalloc();
+        return;
+    }
+    memset(config, 0, sizeof(*config));
+    config->signature = MPCONFIG_SIGNATURE;
+    config->spec = 4;
+    memcpy(config->oemid, BUILD_CPUNAME8, sizeof(config->oemid));
+    memcpy(config->productid, "0.1         ", sizeof(config->productid));
+    config->lapic = BUILD_APIC_ADDR;
+
+    // Detect cpu info
+    u32 cpuid_signature, ebx, ecx, cpuid_features;
+    cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
+    if (! cpuid_signature) {
+        // Use default values.
+        cpuid_signature = 0x600;
+        cpuid_features = 0x201;
+    }
+    int pkgcpus = 1;
+    if (cpuid_features & (1 << 28)) {
+        /* Only populate the MPS tables with the first logical CPU in
+           each package */
+        pkgcpus = (ebx >> 16) & 0xff;
+        pkgcpus = 1 << (__fls(pkgcpus - 1) + 1); /* round up to power of 2 */
+    }
+    u8 apic_version = readl((u8*)BUILD_APIC_ADDR + 0x30) & 0xff;
+
+    // CPU definitions.
+    struct mpt_cpu *cpus = (void*)&config[1], *cpu = cpus;
+    int i;
+    for (i = 0; i < MaxCountCPUs; i+=pkgcpus) {
+        memset(cpu, 0, sizeof(*cpu));
+        cpu->type = MPT_TYPE_CPU;
+        cpu->apicid = i;
+        cpu->apicver = apic_version;
+        /* cpu flags: enabled, bootstrap cpu */
+        cpu->cpuflag = (apic_id_is_present(i) ? 0x01 : 0x00) | ((i==0) ? 0x02 : 0x00);
+        cpu->cpusignature = cpuid_signature;
+        cpu->featureflag = cpuid_features;
+        cpu++;
+    }
+    int entrycount = cpu - cpus;
+
+    // PCI bus
+    struct mpt_bus *buses = (void*)cpu, *bus = buses;
+    if (!hlist_empty(&PCIDevices)) {
+        memset(bus, 0, sizeof(*bus));
+        bus->type = MPT_TYPE_BUS;
+        bus->busid = 0;
+        memcpy(bus->bustype, "PCI   ", sizeof(bus->bustype));
+        bus++;
+        entrycount++;
+    }
+
+    /* isa bus */
+    int isabusid = bus - buses;
+    memset(bus, 0, sizeof(*bus));
+    bus->type = MPT_TYPE_BUS;
+    bus->busid = isabusid;
+    memcpy(bus->bustype, "ISA   ", sizeof(bus->bustype));
+    bus++;
+    entrycount++;
+
+    /* ioapic */
+    u8 ioapic_id = BUILD_IOAPIC_ID;
+    struct mpt_ioapic *ioapic = (void*)bus;
+    memset(ioapic, 0, sizeof(*ioapic));
+    ioapic->type = MPT_TYPE_IOAPIC;
+    ioapic->apicid = ioapic_id;
+    ioapic->apicver = 0x11;
+    ioapic->flags = 1; // enable
+    ioapic->apicaddr = BUILD_IOAPIC_ADDR;
+    entrycount++;
+
+    /* irqs */
+    struct mpt_intsrc *intsrcs = (void*)&ioapic[1], *intsrc = intsrcs;
+    int dev = -1;
+    unsigned short pinmask = 0;
+
+    struct pci_device *pci;
+    foreachpci(pci) {
+        u16 bdf = pci->bdf;
+        if (pci_bdf_to_bus(bdf) != 0)
+            break;
+        int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
+        int irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
+        if (pin == 0)
+            continue;
+        if (dev != pci_bdf_to_busdev(bdf)) {
+            dev = pci_bdf_to_busdev(bdf);
+            pinmask = 0;
+        }
+        if (pinmask & (1 << pin)) /* pin was seen already */
+            continue;
+        pinmask |= (1 << pin);
+        memset(intsrc, 0, sizeof(*intsrc));
+        intsrc->type = MPT_TYPE_INTSRC;
+        intsrc->irqtype = 0; /* INT */
+        intsrc->irqflag = 1; /* active high */
+        intsrc->srcbus = pci_bdf_to_bus(bdf); /* PCI bus */
+        intsrc->srcbusirq = (pci_bdf_to_dev(bdf) << 2) | (pin - 1);
+        intsrc->dstapic = ioapic_id;
+        intsrc->dstirq = irq;
+        intsrc++;
+    }
+
+    int irq0_override = romfile_loadint("etc/irq0-override", 0);
+    for (i = 0; i < 16; i++) {
+        memset(intsrc, 0, sizeof(*intsrc));
+        if (BUILD_PCI_IRQS & (1 << i))
+            continue;
+        intsrc->type = MPT_TYPE_INTSRC;
+        intsrc->irqtype = 0; /* INT */
+        intsrc->irqflag = 0; /* conform to bus spec */
+        intsrc->srcbus = isabusid; /* ISA bus */
+        intsrc->srcbusirq = i;
+        intsrc->dstapic = ioapic_id;
+        intsrc->dstirq = i;
+        if (irq0_override) {
+            /* Destination 2 is covered by irq0->inti2 override (i ==
+               0). Source IRQ 2 is unused */
+            if (i == 0)
+                intsrc->dstirq = 2;
+            else if (i == 2)
+                intsrc--;
+        }
+        intsrc++;
+    }
+
+    /* Local interrupt assignment */
+    intsrc->type = MPT_TYPE_LOCAL_INT;
+    intsrc->irqtype = 3; /* ExtINT */
+    intsrc->irqflag = 0; /* PO, EL default */
+    intsrc->srcbus = isabusid; /* ISA */
+    intsrc->srcbusirq = 0;
+    intsrc->dstapic = 0; /* BSP == APIC #0 */
+    intsrc->dstirq = 0; /* LINTIN0 */
+    intsrc++;
+
+    intsrc->type = MPT_TYPE_LOCAL_INT;
+    intsrc->irqtype = 1; /* NMI */
+    intsrc->irqflag = 0; /* PO, EL default */
+    intsrc->srcbus = isabusid; /* ISA */
+    intsrc->srcbusirq = 0;
+    intsrc->dstapic = 0xff; /* to all local APICs */
+    intsrc->dstirq = 1; /* LINTIN1 */
+    intsrc++;
+    entrycount += intsrc - intsrcs;
+
+    // Finalize config structure.
+    int length = (void*)intsrc - (void*)config;
+    config->entrycount = entrycount;
+    config->length = length;
+    config->checksum -= checksum(config, length);
+
+    // Allocate final memory locations.  (In theory the config
+    // structure can go in high memory, but Linux kernels before
+    // v2.6.30 crash with that.)
+    struct mptable_config_s *finalconfig = malloc_fseg(length);
+    struct mptable_floating_s *floating = malloc_fseg(sizeof(*floating));
+    if (!finalconfig || !floating) {
+        warn_noalloc();
+        free(config);
+        free(finalconfig);
+        free(floating);
+        return;
+    }
+    memcpy(finalconfig, config, length);
+    free(config);
+
+    /* floating pointer structure */
+    memset(floating, 0, sizeof(*floating));
+    floating->signature = MPTABLE_SIGNATURE;
+    floating->physaddr = (u32)finalconfig;
+    floating->length = 1;
+    floating->spec_rev = 4;
+    floating->checksum -= checksum(floating, sizeof(*floating));
+
+    dprintf(1, "MP table addr=%p MPC table addr=%p size=%d\n",
+            floating, finalconfig, length);
+}
diff --git a/src/fw/mptable.h b/src/fw/mptable.h
new file mode 100644 (file)
index 0000000..6252854
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef __MPTABLE_H
+#define __MPTABLE_H
+
+#include "types.h" // u32
+
+#define MPTABLE_SIGNATURE 0x5f504d5f  // "_MP_"
+
+struct mptable_floating_s {
+    u32 signature;
+    u32 physaddr;
+    u8 length;
+    u8 spec_rev;
+    u8 checksum;
+    u8 feature1;
+    u8 feature2;
+    u8 reserved[3];
+};
+
+#define MPCONFIG_SIGNATURE 0x504d4350  // "PCMP"
+
+struct mptable_config_s {
+    u32 signature;
+    u16 length;
+    u8 spec;
+    u8 checksum;
+    char oemid[8];
+    char productid[12];
+    u32 oemptr;
+    u16 oemsize;
+    u16 entrycount;
+    u32 lapic;
+    u16 exttable_length;
+    u8 exttable_checksum;
+    u8 reserved;
+} PACKED;
+
+#define MPT_TYPE_CPU 0
+#define MPT_TYPE_BUS 1
+#define MPT_TYPE_IOAPIC 2
+#define MPT_TYPE_INTSRC 3
+#define MPT_TYPE_LOCAL_INT 4
+
+struct mpt_cpu {
+    u8 type;
+    u8 apicid;
+    u8 apicver;
+    u8 cpuflag;
+    u32 cpusignature;
+    u32 featureflag;
+    u32 reserved[2];
+} PACKED;
+
+struct mpt_bus {
+    u8 type;
+    u8 busid;
+    char bustype[6];
+} PACKED;
+
+struct mpt_ioapic {
+    u8 type;
+    u8 apicid;
+    u8 apicver;
+    u8 flags;
+    u32 apicaddr;
+} PACKED;
+
+struct mpt_intsrc {
+    u8 type;
+    u8 irqtype;
+    u16 irqflag;
+    u8 srcbus;
+    u8 srcbusirq;
+    u8 dstapic;
+    u8 dstirq;
+} PACKED;
+
+// mptable.c
+void mptable_setup(void);
+
+#endif // mptable.h
diff --git a/src/fw/mtrr.c b/src/fw/mtrr.c
new file mode 100644 (file)
index 0000000..001e275
--- /dev/null
@@ -0,0 +1,104 @@
+// Initialize MTRRs - mostly useful on KVM.
+//
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "util.h" // dprintf
+#include "config.h" // CONFIG_*
+#include "hw/pci.h" // pcimem_start
+#include "paravirt.h" // RamSize
+
+#define MSR_MTRRcap                    0x000000fe
+#define MSR_MTRRfix64K_00000           0x00000250
+#define MSR_MTRRfix16K_80000           0x00000258
+#define MSR_MTRRfix16K_A0000           0x00000259
+#define MSR_MTRRfix4K_C0000            0x00000268
+#define MSR_MTRRfix4K_C8000            0x00000269
+#define MSR_MTRRfix4K_D0000            0x0000026a
+#define MSR_MTRRfix4K_D8000            0x0000026b
+#define MSR_MTRRfix4K_E0000            0x0000026c
+#define MSR_MTRRfix4K_E8000            0x0000026d
+#define MSR_MTRRfix4K_F0000            0x0000026e
+#define MSR_MTRRfix4K_F8000            0x0000026f
+#define MSR_MTRRdefType                0x000002ff
+
+#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+#define MTRR_MEMTYPE_UC 0
+#define MTRR_MEMTYPE_WC 1
+#define MTRR_MEMTYPE_WT 4
+#define MTRR_MEMTYPE_WP 5
+#define MTRR_MEMTYPE_WB 6
+
+void mtrr_setup(void)
+{
+    if (!CONFIG_MTRR_INIT)
+        return;
+
+    u32 eax, ebx, ecx, edx, cpuid_features;
+    cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
+    if (!(cpuid_features & CPUID_MTRR))
+        return;
+    if (!(cpuid_features & CPUID_MSR))
+        return;
+
+    dprintf(3, "init mtrr\n");
+
+    u32 mtrr_cap = rdmsr(MSR_MTRRcap);
+    int vcnt = mtrr_cap & 0xff;
+    int fix = mtrr_cap & 0x100;
+    if (!vcnt || !fix)
+       return;
+
+    // Disable MTRRs
+    wrmsr_smp(MSR_MTRRdefType, 0);
+
+    // Set fixed MTRRs
+    union u64b {
+        u8 valb[8];
+        u64 val;
+    } u;
+    u.val = 0;
+    int i;
+    for (i = 0; i < 8; i++)
+        if (RamSize >= 65536 * (i + 1))
+            u.valb[i] = MTRR_MEMTYPE_WB;
+    wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
+    u.val = 0;
+    for (i = 0; i < 8; i++)
+        if (RamSize >= 0x80000 + 16384 * (i + 1))
+            u.valb[i] = MTRR_MEMTYPE_WB;
+    wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
+    wrmsr_smp(MSR_MTRRfix16K_A0000, 0);   // 0xA0000-0xC0000 is uncached
+    int j;
+    for (j = 0; j < 8; j++) {
+        u.val = 0;
+        for (i = 0; i < 8; i++)
+            if (RamSize >= 0xC0000 + j * 0x8000 + 4096 * (i + 1))
+                u.valb[i] = MTRR_MEMTYPE_WP;
+        wrmsr_smp(MSR_MTRRfix4K_C0000 + j, u.val);
+    }
+
+    // Set variable MTRRs
+    int phys_bits = 36;
+    cpuid(0x80000000u, &eax, &ebx, &ecx, &edx);
+    if (eax >= 0x80000008) {
+        /* Get physical bits from leaf 0x80000008 (if available) */
+        cpuid(0x80000008u, &eax, &ebx, &ecx, &edx);
+        phys_bits = eax & 0xff;
+    }
+    u64 phys_mask = ((1ull << phys_bits) - 1);
+    for (i=0; i<vcnt; i++) {
+        wrmsr_smp(MTRRphysBase_MSR(i), 0);
+        wrmsr_smp(MTRRphysMask_MSR(i), 0);
+    }
+    /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
+    wrmsr_smp(MTRRphysBase_MSR(0), pcimem_start | MTRR_MEMTYPE_UC);
+    wrmsr_smp(MTRRphysMask_MSR(0)
+              , (-((1ull<<32)-pcimem_start) & phys_mask) | 0x800);
+
+    // Enable fixed and variable MTRRs; set default type.
+    wrmsr_smp(MSR_MTRRdefType, 0xc00 | MTRR_MEMTYPE_WB);
+}
diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c
new file mode 100644 (file)
index 0000000..b1dd8b0
--- /dev/null
@@ -0,0 +1,333 @@
+// Paravirtualization support.
+//
+// Copyright (C) 2013  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2009 Red Hat Inc.
+//
+// Authors:
+//  Gleb Natapov <gnatapov@redhat.com>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_QEMU
+#include "util.h" // dprintf
+#include "byteorder.h" // be32_to_cpu
+#include "ioport.h" // outw
+#include "paravirt.h" // qemu_cfg_preinit
+#include "smbios.h" // smbios_setup
+#include "memmap.h" // add_e820
+#include "hw/cmos.h" // CMOS_*
+#include "acpi.h" // acpi_setup
+#include "mptable.h" // mptable_setup
+#include "hw/pci.h" // create_pirtable
+#include "xen.h" // xen_biostable_setup
+
+// Amount of continuous ram under 4Gig
+u32 RamSize;
+// Amount of continuous ram >4Gig
+u64 RamSizeOver4G;
+// Type of emulator platform.
+int PlatformRunningOn VARFSEG;
+
+/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
+ * should be used to determine that a VM is running under KVM.
+ */
+#define KVM_CPUID_SIGNATURE     0x40000000
+
+static void kvm_preinit(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+    unsigned int eax, ebx, ecx, edx;
+    char signature[13];
+
+    cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
+    memcpy(signature + 0, &ebx, 4);
+    memcpy(signature + 4, &ecx, 4);
+    memcpy(signature + 8, &edx, 4);
+    signature[12] = 0;
+
+    if (strcmp(signature, "KVMKVMKVM") == 0) {
+        dprintf(1, "Running on KVM\n");
+        PlatformRunningOn |= PF_KVM;
+    }
+}
+
+void
+qemu_preinit(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    if (runningOnXen()) {
+        xen_ramsize_preinit();
+        return;
+    }
+
+    PlatformRunningOn = PF_QEMU;
+    kvm_preinit();
+
+    // On emulators, get memory size from nvram.
+    u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16)
+              | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24));
+    if (rs)
+        rs += 16 * 1024 * 1024;
+    else
+        rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10)
+               | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18))
+              + 1 * 1024 * 1024);
+    RamSize = rs;
+    add_e820(0, rs, E820_RAM);
+
+    // Check for memory over 4Gig
+    u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16)
+                | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24)
+                | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32));
+    RamSizeOver4G = high;
+    add_e820(0x100000000ull, high, E820_RAM);
+
+    /* reserve 256KB BIOS area at the end of 4 GB */
+    add_e820(0xfffc0000, 256*1024, E820_RESERVED);
+
+    dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G);
+}
+
+void
+qemu_platform_setup(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    if (runningOnXen()) {
+        pci_probe_devices();
+        xen_hypercall_setup();
+        xen_biostable_setup();
+        return;
+    }
+
+    // Initialize pci
+    pci_setup();
+    smm_device_setup();
+    smm_setup();
+
+    // Initialize mtrr and smp
+    mtrr_setup();
+    smp_setup();
+
+    // Create bios tables
+    pirtable_setup();
+    mptable_setup();
+    smbios_setup();
+    acpi_setup();
+}
+
+
+/****************************************************************
+ * QEMU firmware config (fw_cfg) interface
+ ****************************************************************/
+
+// List of QEMU fw_cfg entries.  DO NOT ADD MORE.  (All new content
+// should be passed via the fw_cfg "file" interface.)
+#define QEMU_CFG_SIGNATURE              0x00
+#define QEMU_CFG_ID                     0x01
+#define QEMU_CFG_UUID                   0x02
+#define QEMU_CFG_NUMA                   0x0d
+#define QEMU_CFG_BOOT_MENU              0x0e
+#define QEMU_CFG_MAX_CPUS               0x0f
+#define QEMU_CFG_FILE_DIR               0x19
+#define QEMU_CFG_ARCH_LOCAL             0x8000
+#define QEMU_CFG_ACPI_TABLES            (QEMU_CFG_ARCH_LOCAL + 0)
+#define QEMU_CFG_SMBIOS_ENTRIES         (QEMU_CFG_ARCH_LOCAL + 1)
+#define QEMU_CFG_IRQ0_OVERRIDE          (QEMU_CFG_ARCH_LOCAL + 2)
+#define QEMU_CFG_E820_TABLE             (QEMU_CFG_ARCH_LOCAL + 3)
+
+static void
+qemu_cfg_select(u16 f)
+{
+    outw(f, PORT_QEMU_CFG_CTL);
+}
+
+static void
+qemu_cfg_read(void *buf, int len)
+{
+    insb(PORT_QEMU_CFG_DATA, buf, len);
+}
+
+static void
+qemu_cfg_skip(int len)
+{
+    while (len--)
+        inb(PORT_QEMU_CFG_DATA);
+}
+
+static void
+qemu_cfg_read_entry(void *buf, int e, int len)
+{
+    qemu_cfg_select(e);
+    qemu_cfg_read(buf, len);
+}
+
+struct qemu_romfile_s {
+    struct romfile_s file;
+    int select, skip;
+};
+
+static int
+qemu_cfg_read_file(struct romfile_s *file, void *dst, u32 maxlen)
+{
+    if (file->size > maxlen)
+        return -1;
+    struct qemu_romfile_s *qfile;
+    qfile = container_of(file, struct qemu_romfile_s, file);
+    qemu_cfg_select(qfile->select);
+    qemu_cfg_skip(qfile->skip);
+    qemu_cfg_read(dst, file->size);
+    return file->size;
+}
+
+static void
+qemu_romfile_add(char *name, int select, int skip, int size)
+{
+    struct qemu_romfile_s *qfile = malloc_tmp(sizeof(*qfile));
+    if (!qfile) {
+        warn_noalloc();
+        return;
+    }
+    memset(qfile, 0, sizeof(*qfile));
+    strtcpy(qfile->file.name, name, sizeof(qfile->file.name));
+    qfile->file.size = size;
+    qfile->select = select;
+    qfile->skip = skip;
+    qfile->file.copy = qemu_cfg_read_file;
+    romfile_add(&qfile->file);
+}
+
+struct e820_reservation {
+    u64 address;
+    u64 length;
+    u32 type;
+};
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+struct qemu_smbios_header {
+    u16 length;
+    u8 headertype;
+    u8 tabletype;
+    u16 fieldoffset;
+} PACKED;
+
+// Populate romfile entries for legacy fw_cfg ports (that predate the
+// "file" interface).
+static void
+qemu_cfg_legacy(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    // Misc config items.
+    qemu_romfile_add("etc/show-boot-menu", QEMU_CFG_BOOT_MENU, 0, 2);
+    qemu_romfile_add("etc/irq0-override", QEMU_CFG_IRQ0_OVERRIDE, 0, 1);
+    qemu_romfile_add("etc/max-cpus", QEMU_CFG_MAX_CPUS, 0, 2);
+
+    // NUMA data
+    u64 numacount;
+    qemu_cfg_read_entry(&numacount, QEMU_CFG_NUMA, sizeof(numacount));
+    int max_cpu = romfile_loadint("etc/max-cpus", 0);
+    qemu_romfile_add("etc/numa-cpu-map", QEMU_CFG_NUMA, sizeof(numacount)
+                     , max_cpu*sizeof(u64));
+    qemu_romfile_add("etc/numa-nodes", QEMU_CFG_NUMA
+                     , sizeof(numacount) + max_cpu*sizeof(u64)
+                     , numacount*sizeof(u64));
+
+    // e820 data
+    u32 count32;
+    qemu_cfg_read_entry(&count32, QEMU_CFG_E820_TABLE, sizeof(count32));
+    if (count32) {
+        struct e820_reservation entry;
+        int i;
+        for (i = 0; i < count32; i++) {
+            qemu_cfg_read(&entry, sizeof(entry));
+            add_e820(entry.address, entry.length, entry.type);
+        }
+    } else if (runningOnKVM()) {
+        // Backwards compatibility - provide hard coded range.
+        // 4 pages before the bios, 3 pages for vmx tss pages, the
+        // other page for EPT real mode pagetable
+        add_e820(0xfffbc000, 4*4096, E820_RESERVED);
+    }
+
+    // ACPI tables
+    char name[128];
+    u16 cnt;
+    qemu_cfg_read_entry(&cnt, QEMU_CFG_ACPI_TABLES, sizeof(cnt));
+    int i, offset = sizeof(cnt);
+    for (i = 0; i < cnt; i++) {
+        u16 len;
+        qemu_cfg_read(&len, sizeof(len));
+        offset += sizeof(len);
+        snprintf(name, sizeof(name), "acpi/table%d", i);
+        qemu_romfile_add(name, QEMU_CFG_ACPI_TABLES, offset, len);
+        qemu_cfg_skip(len);
+        offset += len;
+    }
+
+    // SMBIOS info
+    qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt));
+    offset = sizeof(cnt);
+    for (i = 0; i < cnt; i++) {
+        struct qemu_smbios_header header;
+        qemu_cfg_read(&header, sizeof(header));
+        if (header.headertype == SMBIOS_FIELD_ENTRY) {
+            snprintf(name, sizeof(name), "smbios/field%d-%d"
+                     , header.tabletype, header.fieldoffset);
+            qemu_romfile_add(name, QEMU_CFG_SMBIOS_ENTRIES
+                             , offset + sizeof(header)
+                             , header.length - sizeof(header));
+        } else {
+            snprintf(name, sizeof(name), "smbios/table%d-%d"
+                     , header.tabletype, i);
+            qemu_romfile_add(name, QEMU_CFG_SMBIOS_ENTRIES
+                             , offset + 3, header.length - 3);
+        }
+        qemu_cfg_skip(header.length - sizeof(header));
+        offset += header.length;
+    }
+}
+
+struct QemuCfgFile {
+    u32  size;        /* file size */
+    u16  select;      /* write this to 0x510 to read it */
+    u16  reserved;
+    char name[56];
+};
+
+void qemu_cfg_init(void)
+{
+    if (!runningOnQEMU())
+        return;
+
+    // Detect fw_cfg interface.
+    qemu_cfg_select(QEMU_CFG_SIGNATURE);
+    char *sig = "QEMU";
+    int i;
+    for (i = 0; i < 4; i++)
+        if (inb(PORT_QEMU_CFG_DATA) != sig[i])
+            return;
+    dprintf(1, "Found QEMU fw_cfg\n");
+
+    // Populate romfiles for legacy fw_cfg entries
+    qemu_cfg_legacy();
+
+    // Load files found in the fw_cfg file directory
+    u32 count;
+    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
+    count = be32_to_cpu(count);
+    u32 e;
+    for (e = 0; e < count; e++) {
+        struct QemuCfgFile qfile;
+        qemu_cfg_read(&qfile, sizeof(qfile));
+        qemu_romfile_add(qfile.name, be16_to_cpu(qfile.select)
+                         , 0, be32_to_cpu(qfile.size));
+    }
+}
diff --git a/src/fw/paravirt.h b/src/fw/paravirt.h
new file mode 100644 (file)
index 0000000..fce5af9
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __PV_H
+#define __PV_H
+
+#include "config.h" // CONFIG_*
+#include "biosvar.h" // GET_GLOBAL
+
+// Types of paravirtualized platforms.
+#define PF_QEMU     (1<<0)
+#define PF_XEN      (1<<1)
+#define PF_KVM      (1<<2)
+
+extern u32 RamSize;
+extern u64 RamSizeOver4G;
+extern int PlatformRunningOn;
+
+static inline int runningOnQEMU(void) {
+    return CONFIG_QEMU || (
+        CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU);
+}
+static inline int runningOnXen(void) {
+    return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN;
+}
+static inline int runningOnKVM(void) {
+    return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM;
+}
+
+void qemu_preinit(void);
+void qemu_platform_setup(void);
+void qemu_cfg_init(void);
+
+#endif
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
new file mode 100644 (file)
index 0000000..ca32d43
--- /dev/null
@@ -0,0 +1,843 @@
+// Initialize PCI devices (on emulators)
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "util.h" // dprintf
+#include "hw/pci.h" // pci_config_readl
+#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
+#include "hw/pci_regs.h" // PCI_COMMAND
+#include "ioport.h" // PORT_ATA1_CMD_BASE
+#include "config.h" // CONFIG_*
+#include "memmap.h" // add_e820
+#include "paravirt.h" // RamSize
+#include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR
+#include "list.h" // struct hlist_node
+#include "acpi.h" // acpi_pm1a_cnt
+
+#define PCI_DEVICE_MEM_MIN     0x1000
+#define PCI_BRIDGE_IO_MIN      0x1000
+#define PCI_BRIDGE_MEM_MIN   0x100000
+
+enum pci_region_type {
+    PCI_REGION_TYPE_IO,
+    PCI_REGION_TYPE_MEM,
+    PCI_REGION_TYPE_PREFMEM,
+    PCI_REGION_TYPE_COUNT,
+};
+
+static const char *region_type_name[] = {
+    [ PCI_REGION_TYPE_IO ]      = "io",
+    [ PCI_REGION_TYPE_MEM ]     = "mem",
+    [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
+};
+
+u64 pcimem_start   = BUILD_PCIMEM_START;
+u64 pcimem_end     = BUILD_PCIMEM_END;
+u64 pcimem64_start = BUILD_PCIMEM64_START;
+u64 pcimem64_end   = BUILD_PCIMEM64_END;
+
+struct pci_region_entry {
+    struct pci_device *dev;
+    int bar;
+    u64 size;
+    u64 align;
+    int is64;
+    enum pci_region_type type;
+    struct hlist_node node;
+};
+
+struct pci_region {
+    /* pci region assignments */
+    u64 base;
+    struct hlist_head list;
+};
+
+struct pci_bus {
+    struct pci_region r[PCI_REGION_TYPE_COUNT];
+    struct pci_device *bus_dev;
+};
+
+static u32 pci_bar(struct pci_device *pci, int region_num)
+{
+    if (region_num != PCI_ROM_SLOT) {
+        return PCI_BASE_ADDRESS_0 + region_num * 4;
+    }
+
+#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
+    u8 type = pci->header_type & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
+    return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
+}
+
+static void
+pci_set_io_region_addr(struct pci_device *pci, int bar, u64 addr, int is64)
+{
+    u32 ofs = pci_bar(pci, bar);
+    pci_config_writel(pci->bdf, ofs, addr);
+    if (is64)
+        pci_config_writel(pci->bdf, ofs + 4, addr >> 32);
+}
+
+
+/****************************************************************
+ * Misc. device init
+ ****************************************************************/
+
+/* host irqs corresponding to PCI irqs A-D */
+const u8 pci_irqs[4] = {
+    10, 10, 11, 11
+};
+
+static int dummy_pci_slot_get_irq(struct pci_device *pci, int pin)
+{
+    dprintf(1, "pci_slot_get_irq called with unknown routing\n");
+
+    return 0xff; /* PCI defined "unknown" or "no connection" for x86 */
+}
+
+static int (*pci_slot_get_irq)(struct pci_device *pci, int pin) =
+    dummy_pci_slot_get_irq;
+
+// Return the global irq number corresponding to a host bus device irq pin.
+static int piix_pci_slot_get_irq(struct pci_device *pci, int pin)
+{
+    int slot_addend = 0;
+
+    while (pci->parent != NULL) {
+        slot_addend += pci_bdf_to_dev(pci->bdf);
+        pci = pci->parent;
+    }
+    slot_addend += pci_bdf_to_dev(pci->bdf) - 1;
+    return pci_irqs[(pin - 1 + slot_addend) & 3];
+}
+
+static int mch_pci_slot_get_irq(struct pci_device *pci, int pin)
+{
+    int irq, slot, pin_addend = 0;
+
+    while (pci->parent != NULL) {
+        pin_addend += pci_bdf_to_dev(pci->bdf);
+        pci = pci->parent;
+    }
+    slot = pci_bdf_to_dev(pci->bdf);
+
+    switch (slot) {
+    /* Slots 0-24 rotate slot:pin mapping similar to piix above, but
+       with a different starting index - see q35-acpi-dsdt.dsl */
+    case 0 ... 24:
+        irq = pci_irqs[(pin - 1 + pin_addend + slot) & 3];
+        break;
+    /* Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H) */
+    case 25 ... 31:
+        irq = pci_irqs[(pin - 1 + pin_addend) & 3];
+        break;
+    }
+
+    return irq;
+}
+
+/* PIIX3/PIIX4 PCI to ISA bridge */
+static void piix_isa_bridge_setup(struct pci_device *pci, void *arg)
+{
+    int i, irq;
+    u8 elcr[2];
+
+    elcr[0] = 0x00;
+    elcr[1] = 0x00;
+    for (i = 0; i < 4; i++) {
+        irq = pci_irqs[i];
+        /* set to trigger level */
+        elcr[irq >> 3] |= (1 << (irq & 7));
+        /* activate irq remapping in PIIX */
+        pci_config_writeb(pci->bdf, 0x60 + i, irq);
+    }
+    outb(elcr[0], 0x4d0);
+    outb(elcr[1], 0x4d1);
+    dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
+}
+
+/* ICH9 LPC PCI to ISA bridge */
+/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
+void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
+{
+    u16 bdf = dev->bdf;
+    int i, irq;
+    u8 elcr[2];
+
+    elcr[0] = 0x00;
+    elcr[1] = 0x00;
+
+    for (i = 0; i < 4; i++) {
+        irq = pci_irqs[i];
+        /* set to trigger level */
+        elcr[irq >> 3] |= (1 << (irq & 7));
+
+        /* activate irq remapping in LPC */
+
+        /* PIRQ[A-D] routing */
+        pci_config_writeb(bdf, ICH9_LPC_PIRQA_ROUT + i, irq);
+        /* PIRQ[E-H] routing */
+        pci_config_writeb(bdf, ICH9_LPC_PIRQE_ROUT + i, irq);
+    }
+    outb(elcr[0], ICH9_LPC_PORT_ELCR1);
+    outb(elcr[1], ICH9_LPC_PORT_ELCR2);
+    dprintf(1, "Q35 LPC init: elcr=%02x %02x\n", elcr[0], elcr[1]);
+
+    /* pm io base */
+    pci_config_writel(bdf, ICH9_LPC_PMBASE,
+                      PORT_ACPI_PM_BASE | ICH9_LPC_PMBASE_RTE);
+
+    /* acpi enable, SCI: IRQ9 000b = irq9*/
+    pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
+
+    acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04;
+    pmtimer_setup(PORT_ACPI_PM_BASE + 0x08);
+}
+
+static void storage_ide_setup(struct pci_device *pci, void *arg)
+{
+    /* IDE: we map it as in ISA mode */
+    pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE, 0);
+    pci_set_io_region_addr(pci, 1, PORT_ATA1_CTRL_BASE, 0);
+    pci_set_io_region_addr(pci, 2, PORT_ATA2_CMD_BASE, 0);
+    pci_set_io_region_addr(pci, 3, PORT_ATA2_CTRL_BASE, 0);
+}
+
+/* PIIX3/PIIX4 IDE */
+static void piix_ide_setup(struct pci_device *pci, void *arg)
+{
+    u16 bdf = pci->bdf;
+    pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0
+    pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1
+}
+
+static void pic_ibm_setup(struct pci_device *pci, void *arg)
+{
+    /* PIC, IBM, MPIC & MPIC2 */
+    pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000, 0);
+}
+
+static void apple_macio_setup(struct pci_device *pci, void *arg)
+{
+    /* macio bridge */
+    pci_set_io_region_addr(pci, 0, 0x80800000, 0);
+}
+
+/* PIIX4 Power Management device (for ACPI) */
+static void piix4_pm_setup(struct pci_device *pci, void *arg)
+{
+    u16 bdf = pci->bdf;
+    // acpi sci is hardwired to 9
+    pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
+
+    pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1);
+    pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
+    pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
+    pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
+
+    acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04;
+    pmtimer_setup(PORT_ACPI_PM_BASE + 0x08);
+}
+
+/* ICH9 SMBUS */
+/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
+void ich9_smbus_setup(struct pci_device *dev, void *arg)
+{
+    u16 bdf = dev->bdf;
+    /* map smbus into io space */
+    pci_config_writel(bdf, ICH9_SMB_SMB_BASE,
+                      PORT_SMB_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+
+    /* enable SMBus */
+    pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9_SMB_HOSTC_HST_EN);
+}
+
+static const struct pci_device_id pci_device_tbl[] = {
+    /* PIIX3/PIIX4 PCI to ISA bridge */
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
+               piix_isa_bridge_setup),
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+               piix_isa_bridge_setup),
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
+               mch_isa_bridge_setup),
+
+    /* STORAGE IDE */
+    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1,
+                     PCI_CLASS_STORAGE_IDE, piix_ide_setup),
+    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
+                     PCI_CLASS_STORAGE_IDE, piix_ide_setup),
+    PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
+                     storage_ide_setup),
+
+    /* PIC, IBM, MIPC & MPIC2 */
+    PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC,
+                     pic_ibm_setup),
+    PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC,
+                     pic_ibm_setup),
+
+    /* PIIX4 Power Management device (for ACPI) */
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
+               piix4_pm_setup),
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_SMBUS,
+               ich9_smbus_setup),
+
+    /* 0xff00 */
+    PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_setup),
+    PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_setup),
+
+    PCI_DEVICE_END,
+};
+
+static void pci_bios_init_device(struct pci_device *pci)
+{
+    u16 bdf = pci->bdf;
+    dprintf(1, "PCI: init bdf=%02x:%02x.%x id=%04x:%04x\n"
+            , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)
+            , pci->vendor, pci->device);
+
+    /* map the interrupt */
+    int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
+    if (pin != 0)
+        pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pci, pin));
+
+    pci_init_device(pci_device_tbl, pci, NULL);
+
+    /* enable memory mappings */
+    pci_config_maskw(bdf, PCI_COMMAND, 0,
+                     PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR);
+}
+
+static void pci_bios_init_devices(void)
+{
+    struct pci_device *pci;
+    foreachpci(pci) {
+        pci_bios_init_device(pci);
+    }
+}
+
+static void pci_enable_default_vga(void)
+{
+    struct pci_device *pci;
+
+    foreachpci(pci) {
+        if (is_pci_vga(pci)) {
+            dprintf(1, "PCI: Using %02x:%02x.%x for primary VGA\n",
+                    pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+                    pci_bdf_to_fn(pci->bdf));
+            return;
+        }
+    }
+
+    pci = pci_find_class(PCI_CLASS_DISPLAY_VGA);
+    if (!pci) {
+        dprintf(1, "PCI: No VGA devices found\n");
+        return;
+    }
+
+    dprintf(1, "PCI: Enabling %02x:%02x.%x for primary VGA\n",
+            pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+            pci_bdf_to_fn(pci->bdf));
+
+    pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
+                     PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+    while (pci->parent) {
+        pci = pci->parent;
+
+        dprintf(1, "PCI: Setting VGA enable on bridge %02x:%02x.%x\n",
+                pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+                pci_bdf_to_fn(pci->bdf));
+
+        pci_config_maskw(pci->bdf, PCI_BRIDGE_CONTROL, 0, PCI_BRIDGE_CTL_VGA);
+        pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
+                         PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+    }
+}
+
+/****************************************************************
+ * Platform device initialization
+ ****************************************************************/
+
+void i440fx_mem_addr_setup(struct pci_device *dev, void *arg)
+{
+    if (RamSize <= 0x80000000)
+        pcimem_start = 0x80000000;
+    else if (RamSize <= 0xc0000000)
+        pcimem_start = 0xc0000000;
+
+    pci_slot_get_irq = piix_pci_slot_get_irq;
+}
+
+void mch_mem_addr_setup(struct pci_device *dev, void *arg)
+{
+    u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
+    u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
+
+    /* setup mmconfig */
+    u16 bdf = dev->bdf;
+    u32 upper = addr >> 32;
+    u32 lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
+    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0);
+    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
+    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);
+    add_e820(addr, size, E820_RESERVED);
+
+    /* setup pci i/o window (above mmconfig) */
+    pcimem_start = addr + size;
+
+    pci_slot_get_irq = mch_pci_slot_get_irq;
+}
+
+static const struct pci_device_id pci_platform_tbl[] = {
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
+               i440fx_mem_addr_setup),
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH,
+               mch_mem_addr_setup),
+    PCI_DEVICE_END
+};
+
+static void pci_bios_init_platform(void)
+{
+    struct pci_device *pci;
+    foreachpci(pci) {
+        pci_init_device(pci_platform_tbl, pci, NULL);
+    }
+}
+
+
+/****************************************************************
+ * Bus initialization
+ ****************************************************************/
+
+static void
+pci_bios_init_bus_rec(int bus, u8 *pci_bus)
+{
+    int bdf;
+    u16 class;
+
+    dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus);
+
+    /* prevent accidental access to unintended devices */
+    foreachbdf(bdf, bus) {
+        class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
+        if (class == PCI_CLASS_BRIDGE_PCI) {
+            pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255);
+            pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0);
+        }
+    }
+
+    foreachbdf(bdf, bus) {
+        class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
+        if (class != PCI_CLASS_BRIDGE_PCI) {
+            continue;
+        }
+        dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf);
+
+        u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS);
+        if (pribus != bus) {
+            dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus);
+            pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus);
+        } else {
+            dprintf(1, "PCI: primary bus = 0x%x\n", pribus);
+        }
+
+        u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
+        (*pci_bus)++;
+        if (*pci_bus != secbus) {
+            dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n",
+                    secbus, *pci_bus);
+            secbus = *pci_bus;
+            pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus);
+        } else {
+            dprintf(1, "PCI: secondary bus = 0x%x\n", secbus);
+        }
+
+        /* set to max for access to all subordinate buses.
+           later set it to accurate value */
+        u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS);
+        pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255);
+
+        pci_bios_init_bus_rec(secbus, pci_bus);
+
+        if (subbus != *pci_bus) {
+            dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n",
+                    subbus, *pci_bus);
+            subbus = *pci_bus;
+        } else {
+            dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus);
+        }
+        pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus);
+    }
+}
+
+static void
+pci_bios_init_bus(void)
+{
+    u8 pci_bus = 0;
+    pci_bios_init_bus_rec(0 /* host bus */, &pci_bus);
+}
+
+
+/****************************************************************
+ * Bus sizing
+ ****************************************************************/
+
+static void
+pci_bios_get_bar(struct pci_device *pci, int bar,
+                 int *ptype, u64 *psize, int *pis64)
+{
+    u32 ofs = pci_bar(pci, bar);
+    u16 bdf = pci->bdf;
+    u32 old = pci_config_readl(bdf, ofs);
+    int is64 = 0, type = PCI_REGION_TYPE_MEM;
+    u64 mask;
+
+    if (bar == PCI_ROM_SLOT) {
+        mask = PCI_ROM_ADDRESS_MASK;
+        pci_config_writel(bdf, ofs, mask);
+    } else {
+        if (old & PCI_BASE_ADDRESS_SPACE_IO) {
+            mask = PCI_BASE_ADDRESS_IO_MASK;
+            type = PCI_REGION_TYPE_IO;
+        } else {
+            mask = PCI_BASE_ADDRESS_MEM_MASK;
+            if (old & PCI_BASE_ADDRESS_MEM_PREFETCH)
+                type = PCI_REGION_TYPE_PREFMEM;
+            is64 = ((old & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+                    == PCI_BASE_ADDRESS_MEM_TYPE_64);
+        }
+        pci_config_writel(bdf, ofs, ~0);
+    }
+    u64 val = pci_config_readl(bdf, ofs);
+    pci_config_writel(bdf, ofs, old);
+    if (is64) {
+        u32 hold = pci_config_readl(bdf, ofs + 4);
+        pci_config_writel(bdf, ofs + 4, ~0);
+        u32 high = pci_config_readl(bdf, ofs + 4);
+        pci_config_writel(bdf, ofs + 4, hold);
+        val |= ((u64)high << 32);
+        mask |= ((u64)0xffffffff << 32);
+        *psize = (~(val & mask)) + 1;
+    } else {
+        *psize = ((~(val & mask)) + 1) & 0xffffffff;
+    }
+    *ptype = type;
+    *pis64 = is64;
+}
+
+static int pci_bios_bridge_region_is64(struct pci_region *r,
+                                 struct pci_device *pci, int type)
+{
+    if (type != PCI_REGION_TYPE_PREFMEM)
+        return 0;
+    u32 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
+    if (!pmem) {
+        pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0);
+        pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
+        pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0);
+    }
+    if ((pmem & PCI_PREF_RANGE_TYPE_MASK) != PCI_PREF_RANGE_TYPE_64)
+       return 0;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry(entry, &r->list, node) {
+        if (!entry->is64)
+            return 0;
+    }
+    return 1;
+}
+
+static u64 pci_region_align(struct pci_region *r)
+{
+    struct pci_region_entry *entry;
+    hlist_for_each_entry(entry, &r->list, node) {
+        // The first entry in the sorted list has the largest alignment
+        return entry->align;
+    }
+    return 1;
+}
+
+static u64 pci_region_sum(struct pci_region *r)
+{
+    u64 sum = 0;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry(entry, &r->list, node) {
+        sum += entry->size;
+    }
+    return sum;
+}
+
+static void pci_region_migrate_64bit_entries(struct pci_region *from,
+                                             struct pci_region *to)
+{
+    struct hlist_node *n, **last = &to->list.first;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry_safe(entry, n, &from->list, node) {
+        if (!entry->is64)
+            continue;
+        // Move from source list to destination list.
+        hlist_del(&entry->node);
+        hlist_add(&entry->node, last);
+    }
+}
+
+static struct pci_region_entry *
+pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
+                        int bar, u64 size, u64 align, int type, int is64)
+{
+    struct pci_region_entry *entry = malloc_tmp(sizeof(*entry));
+    if (!entry) {
+        warn_noalloc();
+        return NULL;
+    }
+    memset(entry, 0, sizeof(*entry));
+    entry->dev = dev;
+    entry->bar = bar;
+    entry->size = size;
+    entry->align = align;
+    entry->is64 = is64;
+    entry->type = type;
+    // Insert into list in sorted order.
+    struct hlist_node **pprev;
+    struct pci_region_entry *pos;
+    hlist_for_each_entry_pprev(pos, pprev, &bus->r[type].list, node) {
+        if (pos->align < align || (pos->align == align && pos->size < size))
+            break;
+    }
+    hlist_add(&entry->node, pprev);
+    return entry;
+}
+
+static int pci_bios_check_devices(struct pci_bus *busses)
+{
+    dprintf(1, "PCI: check devices\n");
+
+    // Calculate resources needed for regular (non-bus) devices.
+    struct pci_device *pci;
+    foreachpci(pci) {
+        if (pci->class == PCI_CLASS_BRIDGE_PCI)
+            busses[pci->secondary_bus].bus_dev = pci;
+
+        struct pci_bus *bus = &busses[pci_bdf_to_bus(pci->bdf)];
+        int i;
+        for (i = 0; i < PCI_NUM_REGIONS; i++) {
+            if ((pci->class == PCI_CLASS_BRIDGE_PCI) &&
+                (i >= PCI_BRIDGE_NUM_REGIONS && i < PCI_ROM_SLOT))
+                continue;
+            int type, is64;
+            u64 size;
+            pci_bios_get_bar(pci, i, &type, &size, &is64);
+            if (size == 0)
+                continue;
+
+            if (type != PCI_REGION_TYPE_IO && size < PCI_DEVICE_MEM_MIN)
+                size = PCI_DEVICE_MEM_MIN;
+            struct pci_region_entry *entry = pci_region_create_entry(
+                bus, pci, i, size, size, type, is64);
+            if (!entry)
+                return -1;
+
+            if (is64)
+                i++;
+        }
+    }
+
+    // Propagate required bus resources to parent busses.
+    int secondary_bus;
+    for (secondary_bus=MaxPCIBus; secondary_bus>0; secondary_bus--) {
+        struct pci_bus *s = &busses[secondary_bus];
+        if (!s->bus_dev)
+            continue;
+        struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
+        int type;
+        for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+            u64 align = (type == PCI_REGION_TYPE_IO) ?
+                PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+            if (pci_region_align(&s->r[type]) > align)
+                 align = pci_region_align(&s->r[type]);
+            u64 sum = pci_region_sum(&s->r[type]);
+            u64 size = ALIGN(sum, align);
+            int is64 = pci_bios_bridge_region_is64(&s->r[type],
+                                            s->bus_dev, type);
+            // entry->bar is -1 if the entry represents a bridge region
+            struct pci_region_entry *entry = pci_region_create_entry(
+                parent, s->bus_dev, -1, size, align, type, is64);
+            if (!entry)
+                return -1;
+            dprintf(1, "PCI: secondary bus %d size %08llx type %s\n",
+                      entry->dev->secondary_bus, size,
+                      region_type_name[entry->type]);
+        }
+    }
+    return 0;
+}
+
+
+/****************************************************************
+ * BAR assignment
+ ****************************************************************/
+
+// Setup region bases (given the regions' size and alignment)
+static int pci_bios_init_root_regions(struct pci_bus *bus)
+{
+    bus->r[PCI_REGION_TYPE_IO].base = 0xc000;
+
+    struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM];
+    struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM];
+
+    if (pci_region_align(r_start) < pci_region_align(r_end)) {
+        // Swap regions to improve alignment.
+        r_end = r_start;
+        r_start = &bus->r[PCI_REGION_TYPE_PREFMEM];
+    }
+    u64 sum = pci_region_sum(r_end);
+    u64 align = pci_region_align(r_end);
+    r_end->base = ALIGN_DOWN((pcimem_end - sum), align);
+    sum = pci_region_sum(r_start);
+    align = pci_region_align(r_start);
+    r_start->base = ALIGN_DOWN((r_end->base - sum), align);
+
+    if ((r_start->base < pcimem_start) ||
+         (r_start->base > pcimem_end))
+        // Memory range requested is larger than available.
+        return -1;
+    return 0;
+}
+
+#define PCI_IO_SHIFT            8
+#define PCI_MEMORY_SHIFT        16
+#define PCI_PREF_MEMORY_SHIFT   16
+
+static void
+pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr)
+{
+    u16 bdf = entry->dev->bdf;
+    if (entry->bar >= 0) {
+        dprintf(1, "PCI: map device bdf=%02x:%02x.%x"
+                "  bar %d, addr %08llx, size %08llx [%s]\n",
+                pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
+                entry->bar, addr, entry->size, region_type_name[entry->type]);
+
+        pci_set_io_region_addr(entry->dev, entry->bar, addr, entry->is64);
+        return;
+    }
+
+    u64 limit = addr + entry->size - 1;
+    if (entry->type == PCI_REGION_TYPE_IO) {
+        pci_config_writeb(bdf, PCI_IO_BASE, addr >> PCI_IO_SHIFT);
+        pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
+        pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
+        pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
+    }
+    if (entry->type == PCI_REGION_TYPE_MEM) {
+        pci_config_writew(bdf, PCI_MEMORY_BASE, addr >> PCI_MEMORY_SHIFT);
+        pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
+    }
+    if (entry->type == PCI_REGION_TYPE_PREFMEM) {
+        pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, addr >> PCI_PREF_MEMORY_SHIFT);
+        pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
+        pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, addr >> 32);
+        pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, limit >> 32);
+    }
+}
+
+static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)
+{
+    struct hlist_node *n;
+    struct pci_region_entry *entry;
+    hlist_for_each_entry_safe(entry, n, &r->list, node) {
+        u64 addr = r->base;
+        r->base += entry->size;
+        if (entry->bar == -1)
+            // Update bus base address if entry is a bridge region
+            busses[entry->dev->secondary_bus].r[entry->type].base = addr;
+        pci_region_map_one_entry(entry, addr);
+        hlist_del(&entry->node);
+        free(entry);
+    }
+}
+
+static void pci_bios_map_devices(struct pci_bus *busses)
+{
+    if (pci_bios_init_root_regions(busses)) {
+        struct pci_region r64_mem, r64_pref;
+        r64_mem.list.first = NULL;
+        r64_pref.list.first = NULL;
+        pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_MEM],
+                                         &r64_mem);
+        pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM],
+                                         &r64_pref);
+
+        if (pci_bios_init_root_regions(busses))
+            panic("PCI: out of 32bit address space\n");
+
+        u64 sum_mem = pci_region_sum(&r64_mem);
+        u64 sum_pref = pci_region_sum(&r64_pref);
+        u64 align_mem = pci_region_align(&r64_mem);
+        u64 align_pref = pci_region_align(&r64_pref);
+
+        r64_mem.base = ALIGN(0x100000000LL + RamSizeOver4G, align_mem);
+        r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref);
+        pcimem64_start = r64_mem.base;
+        pcimem64_end = r64_pref.base + sum_pref;
+
+        pci_region_map_entries(busses, &r64_mem);
+        pci_region_map_entries(busses, &r64_pref);
+    } else {
+        // no bars mapped high -> drop 64bit window (see dsdt)
+        pcimem64_start = 0;
+    }
+    // Map regions on each device.
+    int bus;
+    for (bus = 0; bus<=MaxPCIBus; bus++) {
+        int type;
+        for (type = 0; type < PCI_REGION_TYPE_COUNT; type++)
+            pci_region_map_entries(busses, &busses[bus].r[type]);
+    }
+}
+
+
+/****************************************************************
+ * Main setup code
+ ****************************************************************/
+
+void
+pci_setup(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    dprintf(3, "pci setup\n");
+
+    dprintf(1, "=== PCI bus & bridge init ===\n");
+    if (pci_probe_host() != 0) {
+        return;
+    }
+    pci_bios_init_bus();
+
+    dprintf(1, "=== PCI device probing ===\n");
+    pci_probe_devices();
+
+    pcimem_start = RamSize;
+    pci_bios_init_platform();
+
+    dprintf(1, "=== PCI new allocation pass #1 ===\n");
+    struct pci_bus *busses = malloc_tmp(sizeof(*busses) * (MaxPCIBus + 1));
+    if (!busses) {
+        warn_noalloc();
+        return;
+    }
+    memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1));
+    if (pci_bios_check_devices(busses))
+        return;
+
+    dprintf(1, "=== PCI new allocation pass #2 ===\n");
+    pci_bios_map_devices(busses);
+
+    pci_bios_init_devices();
+
+    free(busses);
+
+    pci_enable_default_vga();
+}
diff --git a/src/fw/pirtable.c b/src/fw/pirtable.c
new file mode 100644 (file)
index 0000000..57fb48f
--- /dev/null
@@ -0,0 +1,105 @@
+// PIR table generation (for emulators)
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2002  MandrakeSoft S.A.
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "hw/pci.h" // struct pir_header
+#include "config.h" // CONFIG_*
+#include "util.h" // checksum
+
+struct pir_header *PirAddr VARFSEG;
+
+struct pir_table {
+    struct pir_header pir;
+    struct pir_slot slots[6];
+} PACKED;
+
+extern struct pir_table PIR_TABLE;
+#if CONFIG_PIRTABLE
+struct pir_table PIR_TABLE __aligned(16) VARFSEG = {
+    .pir = {
+        .version = 0x0100,
+        .size = sizeof(struct pir_table),
+        .router_devfunc = 0x08,
+        .compatible_devid = 0x122e8086,
+    },
+    .slots = {
+        {
+            // first slot entry PCI-to-ISA (embedded)
+            .dev = 1<<3,
+            .links = {
+                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 0, // embedded
+        }, {
+            // second slot entry: 1st PCI slot
+            .dev = 2<<3,
+            .links = {
+                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 1,
+        }, {
+            // third slot entry: 2nd PCI slot
+            .dev = 3<<3,
+            .links = {
+                {.link = 0x62, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 2,
+        }, {
+            // 4th slot entry: 3rd PCI slot
+            .dev = 4<<3,
+            .links = {
+                {.link = 0x63, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 3,
+        }, {
+            // 5th slot entry: 4rd PCI slot
+            .dev = 5<<3,
+            .links = {
+                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 4,
+        }, {
+            // 6th slot entry: 5rd PCI slot
+            .dev = 6<<3,
+            .links = {
+                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 5,
+        },
+    }
+};
+#endif // CONFIG_PIRTABLE
+
+void
+pirtable_setup(void)
+{
+    if (! CONFIG_PIRTABLE)
+        return;
+
+    dprintf(3, "init PIR table\n");
+
+    PIR_TABLE.pir.signature = PIR_SIGNATURE;
+    PIR_TABLE.pir.checksum -= checksum(&PIR_TABLE, sizeof(PIR_TABLE));
+    PirAddr = &PIR_TABLE.pir;
+}
diff --git a/src/fw/q35-acpi-dsdt.dsl b/src/fw/q35-acpi-dsdt.dsl
new file mode 100644 (file)
index 0000000..c031d83
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Bochs/QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * Copyright (c) 2010 Isaku Yamahata
+ *                    yamahata at valinux co jp
+ * Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
+ */
+
+DefinitionBlock (
+    "q35-acpi-dsdt.aml",// Output Filename
+    "DSDT",             // Signature
+    0x01,               // DSDT Compliance Revision
+    "BXPC",             // OEMID
+    "BXDSDT",           // TABLE ID
+    0x2                 // OEM Revision
+    )
+{
+
+#include "acpi-dsdt-dbug.dsl"
+
+    Scope(\_SB) {
+        OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
+        OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
+        Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
+            PCIB, 8,
+        }
+    }
+
+
+/****************************************************************
+ * PCI Bus definition
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Device(PCI0) {
+            Name(_HID, EisaId("PNP0A08"))
+            Name(_CID, EisaId("PNP0A03"))
+            Name(_ADR, 0x00)
+            Name(_UID, 1)
+
+            // _OSC: based on sample of ACPI3.0b spec
+            Name(SUPP, 0) // PCI _OSC Support Field value
+            Name(CTRL, 0) // PCI _OSC Control Field value
+            Method(_OSC, 4) {
+                // Create DWORD-addressable fields from the Capabilities Buffer
+                CreateDWordField(Arg3, 0, CDW1)
+
+                // Check for proper UUID
+                If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+                    // Create DWORD-addressable fields from the Capabilities Buffer
+                    CreateDWordField(Arg3, 4, CDW2)
+                    CreateDWordField(Arg3, 8, CDW3)
+
+                    // Save Capabilities DWORD2 & 3
+                    Store(CDW2, SUPP)
+                    Store(CDW3, CTRL)
+
+                    // Always allow native PME, AER (no dependencies)
+                    // Never allow SHPC (no SHPC controller in this system)
+                    And(CTRL, 0x1D, CTRL)
+
+#if 0 // For now, nothing to do
+                    If (Not(And(CDW1, 1))) { // Query flag clear?
+                        // Disable GPEs for features granted native control.
+                        If (And(CTRL, 0x01)) { // Hot plug control granted?
+                            Store(0, HPCE) // clear the hot plug SCI enable bit
+                            Store(1, HPCS) // clear the hot plug SCI status bit
+                        }
+                        If (And(CTRL, 0x04)) { // PME control granted?
+                            Store(0, PMCE) // clear the PME SCI enable bit
+                            Store(1, PMCS) // clear the PME SCI status bit
+                        }
+                        If (And(CTRL, 0x10)) { // OS restoring PCI Express cap structure?
+                            // Set status to not restore PCI Express cap structure
+                            // upon resume from S3
+                            Store(1, S3CR)
+                        }
+                    }
+#endif
+                    If (LNotEqual(Arg1, One)) {
+                        // Unknown revision
+                        Or(CDW1, 0x08, CDW1)
+                    }
+                    If (LNotEqual(CDW3, CTRL)) {
+                        // Capabilities bits were masked
+                        Or(CDW1, 0x10, CDW1)
+                    }
+                    // Update DWORD3 in the buffer
+                    Store(CTRL, CDW3)
+                } Else {
+                    Or(CDW1, 4, CDW1) // Unrecognized UUID
+                }
+                Return (Arg3)
+            }
+        }
+    }
+
+#include "acpi-dsdt-pci-crs.dsl"
+#include "acpi-dsdt-hpet.dsl"
+
+
+/****************************************************************
+ * VGA
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(VGA) {
+            Name(_ADR, 0x00010000)
+            Method(_S1D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S2D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S3D, 0, NotSerialized) {
+                Return (0x00)
+            }
+        }
+    }
+
+
+/****************************************************************
+ * LPC ISA bridge
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        /* PCI D31:f0 LPC ISA bridge */
+        Device(ISA) {
+            /* PCI D31:f0 */
+            Name(_ADR, 0x001f0000)
+
+            /* ICH9 PCI to ISA irq remapping */
+            OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
+
+            OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
+            Field(LPCD, AnyAcc, NoLock, Preserve) {
+                COMA,   3,
+                    ,   1,
+                COMB,   3,
+
+                Offset(0x01),
+                LPTD,   2,
+                    ,   2,
+                FDCD,   2
+            }
+            OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
+            Field(LPCE, AnyAcc, NoLock, Preserve) {
+                CAEN,   1,
+                CBEN,   1,
+                LPEN,   1,
+                FDEN,   1
+            }
+        }
+    }
+
+#include "acpi-dsdt-isa.dsl"
+
+
+/****************************************************************
+ * PCI IRQs
+ ****************************************************************/
+
+    /* Zero => PIC mode, One => APIC Mode */
+    Name(\PICF, Zero)
+    Method(\_PIC, 1, NotSerialized) {
+        Store(Arg0, \PICF)
+    }
+
+    Scope(\_SB) {
+        Scope(PCI0) {
+#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3)  \
+    Package() { nr##ffff, 0, lnk0, 0 },           \
+    Package() { nr##ffff, 1, lnk1, 0 },           \
+    Package() { nr##ffff, 2, lnk2, 0 },           \
+    Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
+#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
+
+#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
+#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
+#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
+#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
+
+            Name(PRTP, package() {
+                prt_slot_lnkE(0x0000),
+                prt_slot_lnkF(0x0001),
+                prt_slot_lnkG(0x0002),
+                prt_slot_lnkH(0x0003),
+                prt_slot_lnkE(0x0004),
+                prt_slot_lnkF(0x0005),
+                prt_slot_lnkG(0x0006),
+                prt_slot_lnkH(0x0007),
+                prt_slot_lnkE(0x0008),
+                prt_slot_lnkF(0x0009),
+                prt_slot_lnkG(0x000a),
+                prt_slot_lnkH(0x000b),
+                prt_slot_lnkE(0x000c),
+                prt_slot_lnkF(0x000d),
+                prt_slot_lnkG(0x000e),
+                prt_slot_lnkH(0x000f),
+                prt_slot_lnkE(0x0010),
+                prt_slot_lnkF(0x0011),
+                prt_slot_lnkG(0x0012),
+                prt_slot_lnkH(0x0013),
+                prt_slot_lnkE(0x0014),
+                prt_slot_lnkF(0x0015),
+                prt_slot_lnkG(0x0016),
+                prt_slot_lnkH(0x0017),
+                prt_slot_lnkE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31
+                   see the default value of D<N>IR */
+                prt_slot_lnkA(0x0019),
+                prt_slot_lnkA(0x001a),
+                prt_slot_lnkA(0x001b),
+                prt_slot_lnkA(0x001c),
+                prt_slot_lnkA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_lnkE(0x001e),
+
+                prt_slot_lnkA(0x001f)
+            })
+
+#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3)  \
+    Package() { nr##ffff, 0, gsi0, 0 },           \
+    Package() { nr##ffff, 1, gsi1, 0 },           \
+    Package() { nr##ffff, 2, gsi2, 0 },           \
+    Package() { nr##ffff, 3, gsi3, 0 }
+
+#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
+#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
+#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
+#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
+
+#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
+#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
+#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
+#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
+
+            Name(PRTA, package() {
+                prt_slot_gsiE(0x0000),
+                prt_slot_gsiF(0x0001),
+                prt_slot_gsiG(0x0002),
+                prt_slot_gsiH(0x0003),
+                prt_slot_gsiE(0x0004),
+                prt_slot_gsiF(0x0005),
+                prt_slot_gsiG(0x0006),
+                prt_slot_gsiH(0x0007),
+                prt_slot_gsiE(0x0008),
+                prt_slot_gsiF(0x0009),
+                prt_slot_gsiG(0x000a),
+                prt_slot_gsiH(0x000b),
+                prt_slot_gsiE(0x000c),
+                prt_slot_gsiF(0x000d),
+                prt_slot_gsiG(0x000e),
+                prt_slot_gsiH(0x000f),
+                prt_slot_gsiE(0x0010),
+                prt_slot_gsiF(0x0011),
+                prt_slot_gsiG(0x0012),
+                prt_slot_gsiH(0x0013),
+                prt_slot_gsiE(0x0014),
+                prt_slot_gsiF(0x0015),
+                prt_slot_gsiG(0x0016),
+                prt_slot_gsiH(0x0017),
+                prt_slot_gsiE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31, but 30
+                   see the default value of D<N>IR */
+                prt_slot_gsiA(0x0019),
+                prt_slot_gsiA(0x001a),
+                prt_slot_gsiA(0x001b),
+                prt_slot_gsiA(0x001c),
+                prt_slot_gsiA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_gsiE(0x001e),
+
+                prt_slot_gsiA(0x001f)
+            })
+
+            Method(_PRT, 0, NotSerialized) {
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
+                   section 6.2.8.1 */
+                /* Note: we provide the same info as the PCI routing
+                   table of the Bochs BIOS */
+                If (LEqual(\PICF, Zero)) {
+                    Return (PRTP)
+                } Else {
+                    Return (PRTA)
+                }
+            }
+        }
+
+        Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
+            PRQA,   8,
+            PRQB,   8,
+            PRQC,   8,
+            PRQD,   8,
+
+            Offset(0x08),
+            PRQE,   8,
+            PRQF,   8,
+            PRQG,   8,
+            PRQH,   8
+        }
+
+        Method(IQST, 1, NotSerialized) {
+            // _STA method - get status
+            If (And(0x80, Arg0)) {
+                Return (0x09)
+            }
+            Return (0x0B)
+        }
+        Method(IQCR, 1, NotSerialized) {
+            // _CRS method - get current settings
+            Name(PRR0, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
+            })
+            CreateDWordField(PRR0, 0x05, PRRI)
+            Store(And(Arg0, 0x0F), PRRI)
+            Return (PRR0)
+        }
+
+#define define_link(link, uid, reg)                             \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    5, 10, 11                                   \
+                }                                               \
+            })                                                  \
+            Method(_STA, 0, NotSerialized) {                    \
+                Return (IQST(reg))                              \
+            }                                                   \
+            Method(_DIS, 0, NotSerialized) {                    \
+                Or(reg, 0x80, reg)                              \
+            }                                                   \
+            Method(_CRS, 0, NotSerialized) {                    \
+                Return (IQCR(reg))                              \
+            }                                                   \
+            Method(_SRS, 1, NotSerialized) {                    \
+                CreateDWordField(Arg0, 0x05, PRRI)              \
+                Store(PRRI, reg)                                \
+            }                                                   \
+        }
+
+        define_link(LNKA, 0, PRQA)
+        define_link(LNKB, 1, PRQB)
+        define_link(LNKC, 2, PRQC)
+        define_link(LNKD, 3, PRQD)
+        define_link(LNKE, 4, PRQE)
+        define_link(LNKF, 5, PRQF)
+        define_link(LNKG, 6, PRQG)
+        define_link(LNKH, 7, PRQH)
+
+#define define_gsi_link(link, uid, gsi)                         \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Name(_CRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Method(_SRS, 1, NotSerialized) {                    \
+            }                                                   \
+        }
+
+        define_gsi_link(GSIA, 0, 0x10)
+        define_gsi_link(GSIB, 0, 0x11)
+        define_gsi_link(GSIC, 0, 0x12)
+        define_gsi_link(GSID, 0, 0x13)
+        define_gsi_link(GSIE, 0, 0x14)
+        define_gsi_link(GSIF, 0, 0x15)
+        define_gsi_link(GSIG, 0, 0x16)
+        define_gsi_link(GSIH, 0, 0x17)
+    }
+
+#include "acpi-dsdt-cpu-hotplug.dsl"
+
+
+/****************************************************************
+ * General purpose events
+ ****************************************************************/
+
+    Scope(\_GPE) {
+        Name(_HID, "ACPI0006")
+
+        Method(_L00) {
+        }
+        Method(_L01) {
+            // CPU hotplug event
+            \_SB.PRSC()
+        }
+        Method(_L02) {
+        }
+        Method(_L03) {
+        }
+        Method(_L04) {
+        }
+        Method(_L05) {
+        }
+        Method(_L06) {
+        }
+        Method(_L07) {
+        }
+        Method(_L08) {
+        }
+        Method(_L09) {
+        }
+        Method(_L0A) {
+        }
+        Method(_L0B) {
+        }
+        Method(_L0C) {
+        }
+        Method(_L0D) {
+        }
+        Method(_L0E) {
+        }
+        Method(_L0F) {
+        }
+    }
+}
diff --git a/src/fw/shadow.c b/src/fw/shadow.c
new file mode 100644 (file)
index 0000000..67e943f
--- /dev/null
@@ -0,0 +1,168 @@
+// Support for enabling/disabling BIOS ram shadowing.
+//
+// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "util.h" // memcpy
+#include "hw/pci.h" // pci_config_writeb
+#include "config.h" // CONFIG_*
+#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
+#include "hw/pci_regs.h" // PCI_VENDOR_ID
+#include "paravirt.h" // runningOnXen
+#include "dev-q35.h" // PCI_VENDOR_ID_INTEL
+
+// On the emulators, the bios at 0xf0000 is also at 0xffff0000
+#define BIOS_SRC_OFFSET 0xfff00000
+
+#define I440FX_PAM0     0x59
+
+// Enable shadowing and copy bios.
+static void
+__make_bios_writable_intel(u16 bdf, u32 pam0)
+{
+    // Make ram from 0xc0000-0xf0000 writable
+    int clear = 0;
+    int i;
+    for (i=0; i<6; i++) {
+        u32 pam = pam0 + 1 + i;
+        int reg = pci_config_readb(bdf, pam);
+        if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
+            // Need to copy optionroms to work around qemu implementation
+            void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
+            memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
+            pci_config_writeb(bdf, pam, 0x33);
+            memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
+            clear = 1;
+        } else {
+            pci_config_writeb(bdf, pam, 0x33);
+        }
+    }
+    if (clear)
+        memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
+
+    // Make ram from 0xf0000-0x100000 writable
+    int reg = pci_config_readb(bdf, pam0);
+    pci_config_writeb(bdf, pam0, 0x30);
+    if (reg & 0x10)
+        // Ram already present.
+        return;
+
+    // Copy bios.
+    extern u8 code32flat_start[], code32flat_end[];
+    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
+           , code32flat_end - code32flat_start);
+}
+
+static void
+make_bios_writable_intel(u16 bdf, u32 pam0)
+{
+    int reg = pci_config_readb(bdf, pam0);
+    if (!(reg & 0x10)) {
+        // QEMU doesn't fully implement the piix shadow capabilities -
+        // if ram isn't backing the bios segment when shadowing is
+        // disabled, the code itself wont be in memory.  So, run the
+        // code from the high-memory flash location.
+        u32 pos = (u32)__make_bios_writable_intel + BIOS_SRC_OFFSET;
+        void (*func)(u16 bdf, u32 pam0) = (void*)pos;
+        func(bdf, pam0);
+        return;
+    }
+    // Ram already present - just enable writes
+    __make_bios_writable_intel(bdf, pam0);
+}
+
+static void
+make_bios_readonly_intel(u16 bdf, u32 pam0)
+{
+    // Flush any pending writes before locking memory.
+    wbinvd();
+
+    // Write protect roms from 0xc0000-0xf0000
+    u32 romlast = BUILD_BIOS_ADDR, rommax = BUILD_BIOS_ADDR;
+    if (CONFIG_WRITABLE_UPPERMEMORY)
+        romlast = rom_get_last();
+    if (CONFIG_MALLOC_UPPERMEMORY)
+        rommax = rom_get_max();
+    int i;
+    for (i=0; i<6; i++) {
+        u32 mem = BUILD_ROM_START + i * 32*1024;
+        u32 pam = pam0 + 1 + i;
+        if (romlast < mem + 16*1024 || rommax < mem + 32*1024) {
+            if (romlast >= mem && rommax >= mem + 16*1024)
+                pci_config_writeb(bdf, pam, 0x31);
+            break;
+        }
+        pci_config_writeb(bdf, pam, 0x11);
+    }
+
+    // Write protect 0xf0000-0x100000
+    pci_config_writeb(bdf, pam0, 0x10);
+}
+
+static int ShadowBDF = -1;
+
+// Make the 0xc0000-0x100000 area read/writable.
+void
+make_bios_writable(void)
+{
+    if (!CONFIG_QEMU || runningOnXen())
+        return;
+
+    dprintf(3, "enabling shadow ram\n");
+
+    // At this point, statically allocated variables can't be written,
+    // so do this search manually.
+    int bdf;
+    foreachbdf(bdf, 0) {
+        u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
+        u16 vendor = vendev & 0xffff, device = vendev >> 16;
+        if (vendor == PCI_VENDOR_ID_INTEL
+            && device == PCI_DEVICE_ID_INTEL_82441) {
+            make_bios_writable_intel(bdf, I440FX_PAM0);
+            ShadowBDF = bdf;
+            return;
+        }
+        if (vendor == PCI_VENDOR_ID_INTEL
+            && device == PCI_DEVICE_ID_INTEL_Q35_MCH) {
+            make_bios_writable_intel(bdf, Q35_HOST_BRIDGE_PAM0);
+            ShadowBDF = bdf;
+            return;
+        }
+    }
+    dprintf(1, "Unable to unlock ram - bridge not found\n");
+}
+
+// Make the BIOS code segment area (0xf0000) read-only.
+void
+make_bios_readonly(void)
+{
+    if (!CONFIG_QEMU || runningOnXen())
+        return;
+    dprintf(3, "locking shadow ram\n");
+
+    if (ShadowBDF < 0) {
+        dprintf(1, "Unable to lock ram - bridge not found\n");
+        return;
+    }
+
+    u16 device = pci_config_readw(ShadowBDF, PCI_DEVICE_ID);
+    if (device == PCI_DEVICE_ID_INTEL_82441)
+        make_bios_readonly_intel(ShadowBDF, I440FX_PAM0);
+    else
+        make_bios_readonly_intel(ShadowBDF, Q35_HOST_BRIDGE_PAM0);
+}
+
+void
+qemu_prep_reset(void)
+{
+    if (!CONFIG_QEMU || runningOnXen())
+        return;
+    // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
+    // reset, so do that manually before invoking a hard reset.
+    make_bios_writable();
+    extern u8 code32flat_start[], code32flat_end[];
+    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
+           , code32flat_end - code32flat_start);
+}
diff --git a/src/fw/smbios.c b/src/fw/smbios.c
new file mode 100644 (file)
index 0000000..fd63afb
--- /dev/null
@@ -0,0 +1,649 @@
+// smbios table generation (on emulators)
+//
+// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "util.h" // dprintf
+#include "config.h" // CONFIG_*
+#include "paravirt.h" // RamSize
+#include "smbios.h" // struct smbios_entry_point
+
+struct smbios_entry_point *SMBiosAddr;
+
+static void
+smbios_entry_point_setup(u16 max_structure_size,
+                         u16 structure_table_length,
+                         void *structure_table_address,
+                         u16 number_of_structures)
+{
+    struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep));
+    void *finaltable;
+    if (structure_table_length <= BUILD_MAX_SMBIOS_FSEG)
+        // Table is small enough for f-seg - allocate there.  This
+        // works around a bug in JunOS (at least for small SMBIOS tables).
+        finaltable = malloc_fseg(structure_table_length);
+    else
+        finaltable = malloc_high(structure_table_length);
+    if (!ep || !finaltable) {
+        warn_noalloc();
+        free(ep);
+        free(finaltable);
+        return;
+    }
+    memcpy(finaltable, structure_table_address, structure_table_length);
+
+    memcpy(ep->anchor_string, "_SM_", 4);
+    ep->length = 0x1f;
+    ep->smbios_major_version = 2;
+    ep->smbios_minor_version = 4;
+    ep->max_structure_size = max_structure_size;
+    ep->entry_point_revision = 0;
+    memset(ep->formatted_area, 0, 5);
+    memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
+
+    ep->structure_table_length = structure_table_length;
+    ep->structure_table_address = (u32)finaltable;
+    ep->number_of_structures = number_of_structures;
+    ep->smbios_bcd_revision = 0x24;
+
+    ep->checksum -= checksum(ep, 0x10);
+
+    ep->intermediate_checksum -= checksum((void*)ep + 0x10, ep->length - 0x10);
+
+    SMBiosAddr = ep;
+    dprintf(1, "SMBIOS ptr=%p table=%p size=%d\n"
+            , ep, finaltable, structure_table_length);
+}
+
+static int
+get_field(int type, int offset, void *dest)
+{
+    char name[128];
+    snprintf(name, sizeof(name), "smbios/field%d-%d", type, offset);
+    struct romfile_s *file = romfile_find(name);
+    if (!file)
+        return 0;
+    file->copy(file, dest, file->size);
+    return file->size;
+}
+
+static int
+get_external(int type, char **p, unsigned *nr_structs,
+             unsigned *max_struct_size, char *end)
+{
+    static u64 used_bitmap[4] = { 0 };
+    char *start = *p;
+
+    /* Check if we've already reported these tables */
+    if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
+        return 1;
+
+    /* Don't introduce spurious end markers */
+    if (type == 127)
+        return 0;
+
+    char prefix[128];
+    snprintf(prefix, sizeof(prefix), "smbios/table%d-", type);
+    struct romfile_s *file = NULL;
+    for (;;) {
+        file = romfile_findprefix(prefix, file);
+        if (!file)
+            break;
+
+        if (end - *p < file->size) {
+            warn_noalloc();
+            break;
+        }
+
+        struct smbios_structure_header *header = (void*)*p;
+        file->copy(file, header, file->size);
+        *p += file->size;
+
+        /* Entries end with a double NULL char, if there's a string at
+         * the end (length is greater than formatted length), the string
+         * terminator provides the first NULL. */
+        *((u8*)*p) = 0;
+        (*p)++;
+        if (header->length >= file->size) {
+            *((u8*)*p) = 0;
+            (*p)++;
+        }
+
+        (*nr_structs)++;
+        if (*p - (char*)header > *max_struct_size)
+            *max_struct_size = *p - (char*)header;
+    }
+
+    if (start == *p)
+        return 0;
+
+    /* Mark that we've reported on this type */
+    used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
+    return 1;
+}
+
+#define load_str_field_with_default(type, field, def)                   \
+    do {                                                                \
+        size = get_field(type, offsetof(struct smbios_type_##type,      \
+                                        field), end);                   \
+        if (size > 0) {                                                 \
+            end += size;                                                \
+        } else {                                                        \
+            memcpy(end, def, sizeof(def));                              \
+            end += sizeof(def);                                         \
+        }                                                               \
+        p->field = ++str_index;                                         \
+    } while (0)
+
+#define load_str_field_or_skip(type, field)                             \
+    do {                                                                \
+        size = get_field(type, offsetof(struct smbios_type_##type,      \
+                                        field), end);                   \
+        if (size > 0) {                                                 \
+            end += size;                                                \
+            p->field = ++str_index;                                     \
+        } else {                                                        \
+            p->field = 0;                                               \
+        }                                                               \
+    } while (0)
+
+#define set_field_with_default(type, field, def)                        \
+    do {                                                                \
+        if (!get_field(type, offsetof(struct smbios_type_##type,        \
+                                      field), &p->field)) {             \
+            p->field = def;                                             \
+        }                                                               \
+    } while (0)
+
+/* Type 0 -- BIOS Information */
+#define RELEASE_DATE_STR "01/01/2011"
+static void *
+smbios_init_type_0(void *start)
+{
+    struct smbios_type_0 *p = (struct smbios_type_0 *)start;
+    char *end = (char *)start + sizeof(struct smbios_type_0);
+    size_t size;
+    int str_index = 0;
+
+    p->header.type = 0;
+    p->header.length = sizeof(struct smbios_type_0);
+    p->header.handle = 0;
+
+    load_str_field_with_default(0, vendor_str, BUILD_APPNAME);
+    load_str_field_with_default(0, bios_version_str, BUILD_APPNAME);
+
+    p->bios_starting_address_segment = 0xe800;
+
+    load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR);
+
+    p->bios_rom_size = 0; /* FIXME */
+
+    if (!get_field(0, offsetof(struct smbios_type_0, bios_characteristics),
+                   &p->bios_characteristics)) {
+        memset(p->bios_characteristics, 0, 8);
+        /* BIOS characteristics not supported */
+        p->bios_characteristics[0] = 0x08;
+    }
+
+    if (!get_field(0, offsetof(struct smbios_type_0,
+                               bios_characteristics_extension_bytes),
+                   &p->bios_characteristics_extension_bytes)) {
+        p->bios_characteristics_extension_bytes[0] = 0;
+        /* Enable targeted content distribution. Needed for SVVP */
+        p->bios_characteristics_extension_bytes[1] = 4;
+    }
+
+    set_field_with_default(0, system_bios_major_release, 1);
+    set_field_with_default(0, system_bios_minor_release, 0);
+    set_field_with_default(0, embedded_controller_major_release, 0xff);
+    set_field_with_default(0, embedded_controller_minor_release, 0xff);
+
+    *end = 0;
+    end++;
+
+    return end;
+}
+
+/* Type 1 -- System Information */
+static void *
+smbios_init_type_1(void *start)
+{
+    struct smbios_type_1 *p = (struct smbios_type_1 *)start;
+    char *end = (char *)start + sizeof(struct smbios_type_1);
+    size_t size;
+    int str_index = 0;
+
+    p->header.type = 1;
+    p->header.length = sizeof(struct smbios_type_1);
+    p->header.handle = 0x100;
+
+    load_str_field_with_default(1, manufacturer_str, BUILD_APPNAME);
+    load_str_field_with_default(1, product_name_str, BUILD_APPNAME);
+    load_str_field_or_skip(1, version_str);
+    load_str_field_or_skip(1, serial_number_str);
+
+    if (!get_field(1, offsetof(struct smbios_type_1, uuid), &p->uuid))
+        memset(p->uuid, 0, 16);
+
+    set_field_with_default(1, wake_up_type, 0x06); /* power switch */
+
+    load_str_field_or_skip(1, sku_number_str);
+    load_str_field_or_skip(1, family_str);
+
+    *end = 0;
+    end++;
+    if (!str_index) {
+        *end = 0;
+        end++;
+    }
+
+    return end;
+}
+
+/* Type 3 -- System Enclosure */
+static void *
+smbios_init_type_3(void *start)
+{
+    struct smbios_type_3 *p = (struct smbios_type_3 *)start;
+    char *end = (char *)start + sizeof(struct smbios_type_3);
+    size_t size;
+    int str_index = 0;
+
+    p->header.type = 3;
+    p->header.length = sizeof(struct smbios_type_3);
+    p->header.handle = 0x300;
+
+    load_str_field_with_default(3, manufacturer_str, BUILD_APPNAME);
+    set_field_with_default(3, type, 0x01); /* other */
+
+    load_str_field_or_skip(3, version_str);
+    load_str_field_or_skip(3, serial_number_str);
+    load_str_field_or_skip(3, asset_tag_number_str);
+
+    set_field_with_default(3, boot_up_state, 0x03); /* safe */
+    set_field_with_default(3, power_supply_state, 0x03); /* safe */
+    set_field_with_default(3, thermal_state, 0x03); /* safe */
+    set_field_with_default(3, security_status, 0x02); /* unknown */
+
+    set_field_with_default(3, oem_defined, 0);
+    set_field_with_default(3, height, 0);
+    set_field_with_default(3, number_of_power_cords, 0);
+    set_field_with_default(3, contained_element_count, 0);
+
+    *end = 0;
+    end++;
+    if (!str_index) {
+        *end = 0;
+        end++;
+    }
+
+    return end;
+}
+
+/* Type 4 -- Processor Information */
+static void *
+smbios_init_type_4(void *start, unsigned int cpu_number)
+{
+    struct smbios_type_4 *p = (struct smbios_type_4 *)start;
+    char *end = (char *)start + sizeof(struct smbios_type_4);
+    size_t size;
+    int str_index = 0;
+    char name[1024];
+
+    p->header.type = 4;
+    p->header.length = sizeof(struct smbios_type_4);
+    p->header.handle = 0x400 + cpu_number;
+
+    size = get_field(4, offsetof(struct smbios_type_4, socket_designation_str),
+                     name);
+    if (size)
+        snprintf(name + size - 1, sizeof(name) - size, "%2x", cpu_number);
+    else
+        snprintf(name, sizeof(name), "CPU%2x", cpu_number);
+
+    memcpy(end, name, strlen(name) + 1);
+    end += strlen(name) + 1;
+    p->socket_designation_str = ++str_index;
+
+    set_field_with_default(4, processor_type, 0x03); /* CPU */
+    set_field_with_default(4, processor_family, 0x01); /* other */
+
+    load_str_field_with_default(4, processor_manufacturer_str, BUILD_APPNAME);
+
+    if (!get_field(4, offsetof(struct smbios_type_4, processor_id)
+                   , p->processor_id)) {
+        u32 cpuid_signature, ebx, ecx, cpuid_features;
+        cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
+        p->processor_id[0] = cpuid_signature;
+        p->processor_id[1] = cpuid_features;
+    }
+
+    load_str_field_or_skip(4, processor_version_str);
+    set_field_with_default(4, voltage, 0);
+    set_field_with_default(4, external_clock, 0);
+
+    set_field_with_default(4, max_speed, 2000);
+    set_field_with_default(4, current_speed, 2000);
+
+    set_field_with_default(4, status, 0x41); /* socket populated, CPU enabled */
+    set_field_with_default(4, processor_upgrade, 0x01); /* other */
+
+    /* cache information structure not provided */
+    p->l1_cache_handle =  0xffff;
+    p->l2_cache_handle =  0xffff;
+    p->l3_cache_handle =  0xffff;
+
+    *end = 0;
+    end++;
+    if (!str_index) {
+        *end = 0;
+        end++;
+    }
+
+    return end;
+}
+
+/* Type 16 -- Physical Memory Array */
+static void *
+smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs)
+{
+    struct smbios_type_16 *p = (struct smbios_type_16*)start;
+
+    p->header.type = 16;
+    p->header.length = sizeof(struct smbios_type_16);
+    p->header.handle = 0x1000;
+
+    set_field_with_default(16, location, 0x01); /* other */
+    set_field_with_default(16, use, 0x03); /* system memory */
+    /* Multi-bit ECC to make Microsoft happy */
+    set_field_with_default(16, error_correction, 0x06);
+    /* 0x80000000 = unknown, accept sizes < 2TB - TODO multiple arrays */
+    p->maximum_capacity = memory_size_mb < 2 << 20 ?
+                          memory_size_mb << 10 : 0x80000000;
+    p->memory_error_information_handle = 0xfffe; /* none provided */
+    p->number_of_memory_devices = nr_mem_devs;
+
+    start += sizeof(struct smbios_type_16);
+    *((u16 *)start) = 0;
+
+    return start + 2;
+}
+
+/* Type 17 -- Memory Device */
+static void *
+smbios_init_type_17(void *start, u32 size_mb, int instance)
+{
+    struct smbios_type_17 *p = (struct smbios_type_17 *)start;
+    char *end = (char *)start + sizeof(struct smbios_type_17);
+    size_t size;
+    int str_index = 0;
+    char name[1024];
+
+    p->header.type = 17;
+    p->header.length = sizeof(struct smbios_type_17);
+    p->header.handle = 0x1100 + instance;
+
+    p->physical_memory_array_handle = 0x1000;
+    set_field_with_default(17, total_width, 64);
+    set_field_with_default(17, data_width, 64);
+/* TODO: should assert in case something is wrong   ASSERT((memory_size_mb & ~0x7fff) == 0); */
+    p->size = size_mb;
+    set_field_with_default(17, form_factor, 0x09); /* DIMM */
+    p->device_set = 0;
+
+    size = get_field(17, offsetof(struct smbios_type_17, device_locator_str),
+                     name);
+    if (size)
+        snprintf(name + size - 1, sizeof(name) - size, "%d", instance);
+    else
+        snprintf(name, sizeof(name), "DIMM %d", instance);
+
+    memcpy(end, name, strlen(name) + 1);
+    end += strlen(name) + 1;
+    p->device_locator_str = ++str_index;
+
+    load_str_field_or_skip(17, bank_locator_str);
+    set_field_with_default(17, memory_type, 0x07); /* RAM */
+    set_field_with_default(17, type_detail, 0);
+
+    *end = 0;
+    end++;
+    if (!str_index) {
+        *end = 0;
+        end++;
+    }
+
+    return end;
+}
+
+/* Type 19 -- Memory Array Mapped Address */
+static void *
+smbios_init_type_19(void *start, u32 start_mb, u32 size_mb, int instance)
+{
+    struct smbios_type_19 *p = (struct smbios_type_19 *)start;
+
+    p->header.type = 19;
+    p->header.length = sizeof(struct smbios_type_19);
+    p->header.handle = 0x1300 + instance;
+
+    p->starting_address = start_mb << 10;
+    p->ending_address = p->starting_address + (size_mb << 10) - 1;
+    p->memory_array_handle = 0x1000;
+    p->partition_width = 1;
+
+    start += sizeof(struct smbios_type_19);
+    *((u16 *)start) = 0;
+
+    return start + 2;
+}
+
+/* Type 20 -- Memory Device Mapped Address */
+static void *
+smbios_init_type_20(void *start, u32 start_mb, u32 size_mb, int instance,
+                    int dev_handle, int array_handle)
+{
+    struct smbios_type_20 *p = (struct smbios_type_20 *)start;
+
+    p->header.type = 20;
+    p->header.length = sizeof(struct smbios_type_20);
+    p->header.handle = 0x1400 + instance;
+
+    p->starting_address = start_mb << 10;
+    p->ending_address = p->starting_address + (size_mb << 10) - 1;
+    p->memory_device_handle = 0x1100 + dev_handle;
+    p->memory_array_mapped_address_handle = 0x1300 + array_handle;
+    p->partition_row_position = 1;
+    p->interleave_position = 0;
+    p->interleaved_data_depth = 0;
+
+    start += sizeof(struct smbios_type_20);
+
+    *((u16 *)start) = 0;
+    return start+2;
+}
+
+/* Type 32 -- System Boot Information */
+static void *
+smbios_init_type_32(void *start)
+{
+    struct smbios_type_32 *p = (struct smbios_type_32 *)start;
+
+    p->header.type = 32;
+    p->header.length = sizeof(struct smbios_type_32);
+    p->header.handle = 0x2000;
+    memset(p->reserved, 0, 6);
+    set_field_with_default(32, boot_status, 0); /* no errors detected */
+
+    start += sizeof(struct smbios_type_32);
+    *((u16 *)start) = 0;
+
+    return start+2;
+}
+
+/* Type 127 -- End of Table */
+static void *
+smbios_init_type_127(void *start)
+{
+    struct smbios_type_127 *p = (struct smbios_type_127 *)start;
+
+    p->header.type = 127;
+    p->header.length = sizeof(struct smbios_type_127);
+    p->header.handle = 0x7f00;
+
+    start += sizeof(struct smbios_type_127);
+    *((u16 *)start) = 0;
+
+    return start + 2;
+}
+
+#define TEMPSMBIOSSIZE (32 * 1024)
+
+void
+smbios_setup(void)
+{
+    if (! CONFIG_SMBIOS)
+        return;
+
+    dprintf(3, "init SMBIOS tables\n");
+
+    char *start = malloc_tmphigh(TEMPSMBIOSSIZE);
+    if (! start) {
+        warn_noalloc();
+        return;
+    }
+
+    u32 nr_structs = 0, max_struct_size = 0;
+    char *q, *p = start;
+    char *end = start + TEMPSMBIOSSIZE - sizeof(struct smbios_type_127);
+
+#define add_struct(type, args...)                                       \
+    do {                                                                \
+        if (!get_external(type, &p, &nr_structs, &max_struct_size, end)) { \
+            q = smbios_init_type_##type(args);                          \
+            nr_structs++;                                               \
+            if ((q - p) > max_struct_size)                              \
+                max_struct_size = q - p;                                \
+            p = q;                                                      \
+        }                                                               \
+    } while (0)
+
+    add_struct(0, p);
+    add_struct(1, p);
+    add_struct(3, p);
+
+    int cpu_num;
+    for (cpu_num = 1; cpu_num <= MaxCountCPUs; cpu_num++)
+        add_struct(4, p, cpu_num);
+
+    int ram_mb = (RamSize + RamSizeOver4G) >> 20;
+    int nr_mem_devs = (ram_mb + 0x3fff) >> 14;
+    add_struct(16, p, ram_mb, nr_mem_devs);
+
+    int i, j;
+    for (i = 0; i < nr_mem_devs; i++) {
+        u32 dev_mb = ((i == (nr_mem_devs - 1))
+                      ? (((ram_mb - 1) & 0x3fff) + 1)
+                      : 16384);
+        add_struct(17, p, dev_mb, i);
+    }
+
+    add_struct(19, p, 0, RamSize >> 20, 0);
+    if (RamSizeOver4G)
+        add_struct(19, p, 4096, RamSizeOver4G >> 20, 1);
+
+    add_struct(20, p, 0, RamSize >> 20, 0, 0, 0);
+    if (RamSizeOver4G) {
+        u32 start_mb = 4096;
+        for (j = 1, i = 0; i < nr_mem_devs; i++, j++) {
+            u32 dev_mb = ((i == (nr_mem_devs - 1))
+                               ? (((ram_mb - 1) & 0x3fff) + 1)
+                               : 16384);
+            if (i == 0)
+                dev_mb -= RamSize >> 20;
+
+            add_struct(20, p, start_mb, dev_mb, j, i, 1);
+            start_mb += dev_mb;
+        }
+    }
+
+    add_struct(32, p);
+    /* Add any remaining provided entries before the end marker */
+    for (i = 0; i < 256; i++)
+        get_external(i, &p, &nr_structs, &max_struct_size, end);
+    add_struct(127, p);
+
+#undef add_struct
+
+    smbios_entry_point_setup(max_struct_size, p - start, start, nr_structs);
+    free(start);
+}
+
+void
+display_uuid(void)
+{
+    u32 addr, end;
+    u8 *uuid;
+    u8 empty_uuid[16] = { 0 };
+
+    if (SMBiosAddr == NULL)
+        return;
+
+    addr =        SMBiosAddr->structure_table_address;
+    end  = addr + SMBiosAddr->structure_table_length;
+
+    /* the following takes care of any initial wraparound too */
+    while (addr < end) {
+        const struct smbios_structure_header *hdr;
+
+        /* partial structure header */
+        if (end - addr < sizeof(struct smbios_structure_header))
+            return;
+
+        hdr = (struct smbios_structure_header *)addr;
+
+        /* partial structure */
+        if (end - addr < hdr->length)
+            return;
+
+        /* any Type 1 structure version will do that has the UUID */
+        if (hdr->type == 1 &&
+            hdr->length >= offsetof(struct smbios_type_1, uuid) + 16)
+            break;
+
+        /* done with formatted area, skip string-set */
+        addr += hdr->length;
+
+        while (end - addr >= 2 &&
+               (*(u8 *)addr     != '\0' ||
+                *(u8 *)(addr+1) != '\0'))
+            ++addr;
+
+        /* structure terminator not found */
+        if (end - addr < 2)
+            return;
+
+        addr += 2;
+    }
+
+    /* parsing finished or skipped entirely, UUID not found */
+    if (addr >= end)
+        return;
+
+    uuid = (u8 *)(addr + offsetof(struct smbios_type_1, uuid));
+    if (memcmp(uuid, empty_uuid, sizeof empty_uuid) == 0)
+        return;
+
+    printf("Machine UUID"
+             " %02x%02x%02x%02x"
+             "-%02x%02x"
+             "-%02x%02x"
+             "-%02x%02x"
+             "-%02x%02x%02x%02x%02x%02x\n"
+           , uuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3]
+           , uuid[ 4], uuid[ 5]
+           , uuid[ 6], uuid[ 7]
+           , uuid[ 8], uuid[ 9]
+           , uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
+}
diff --git a/src/fw/smbios.h b/src/fw/smbios.h
new file mode 100644 (file)
index 0000000..a4c1444
--- /dev/null
@@ -0,0 +1,169 @@
+#ifndef __SMBIOS_H
+#define __SMBIOS_H
+
+// smbios.c
+void smbios_setup(void);
+
+/* SMBIOS entry point -- must be written to a 16-bit aligned address
+   between 0xf0000 and 0xfffff.
+ */
+struct smbios_entry_point {
+    char anchor_string[4];
+    u8 checksum;
+    u8 length;
+    u8 smbios_major_version;
+    u8 smbios_minor_version;
+    u16 max_structure_size;
+    u8 entry_point_revision;
+    u8 formatted_area[5];
+    char intermediate_anchor_string[5];
+    u8 intermediate_checksum;
+    u16 structure_table_length;
+    u32 structure_table_address;
+    u16 number_of_structures;
+    u8 smbios_bcd_revision;
+} PACKED;
+
+extern struct smbios_entry_point *SMBiosAddr;
+
+/* This goes at the beginning of every SMBIOS structure. */
+struct smbios_structure_header {
+    u8 type;
+    u8 length;
+    u16 handle;
+} PACKED;
+
+/* SMBIOS type 0 - BIOS Information */
+struct smbios_type_0 {
+    struct smbios_structure_header header;
+    u8 vendor_str;
+    u8 bios_version_str;
+    u16 bios_starting_address_segment;
+    u8 bios_release_date_str;
+    u8 bios_rom_size;
+    u8 bios_characteristics[8];
+    u8 bios_characteristics_extension_bytes[2];
+    u8 system_bios_major_release;
+    u8 system_bios_minor_release;
+    u8 embedded_controller_major_release;
+    u8 embedded_controller_minor_release;
+} PACKED;
+
+/* SMBIOS type 1 - System Information */
+struct smbios_type_1 {
+    struct smbios_structure_header header;
+    u8 manufacturer_str;
+    u8 product_name_str;
+    u8 version_str;
+    u8 serial_number_str;
+    u8 uuid[16];
+    u8 wake_up_type;
+    u8 sku_number_str;
+    u8 family_str;
+} PACKED;
+
+/* SMBIOS type 3 - System Enclosure (v2.3) */
+struct smbios_type_3 {
+    struct smbios_structure_header header;
+    u8 manufacturer_str;
+    u8 type;
+    u8 version_str;
+    u8 serial_number_str;
+    u8 asset_tag_number_str;
+    u8 boot_up_state;
+    u8 power_supply_state;
+    u8 thermal_state;
+    u8 security_status;
+    u32 oem_defined;
+    u8 height;
+    u8 number_of_power_cords;
+    u8 contained_element_count;
+    // contained elements follow
+} PACKED;
+
+/* SMBIOS type 4 - Processor Information (v2.0) */
+struct smbios_type_4 {
+    struct smbios_structure_header header;
+    u8 socket_designation_str;
+    u8 processor_type;
+    u8 processor_family;
+    u8 processor_manufacturer_str;
+    u32 processor_id[2];
+    u8 processor_version_str;
+    u8 voltage;
+    u16 external_clock;
+    u16 max_speed;
+    u16 current_speed;
+    u8 status;
+    u8 processor_upgrade;
+    u16 l1_cache_handle;
+    u16 l2_cache_handle;
+    u16 l3_cache_handle;
+} PACKED;
+
+/* SMBIOS type 16 - Physical Memory Array
+ *   Associated with one type 17 (Memory Device).
+ */
+struct smbios_type_16 {
+    struct smbios_structure_header header;
+    u8 location;
+    u8 use;
+    u8 error_correction;
+    u32 maximum_capacity;
+    u16 memory_error_information_handle;
+    u16 number_of_memory_devices;
+} PACKED;
+
+/* SMBIOS type 17 - Memory Device
+ *   Associated with one type 19
+ */
+struct smbios_type_17 {
+    struct smbios_structure_header header;
+    u16 physical_memory_array_handle;
+    u16 memory_error_information_handle;
+    u16 total_width;
+    u16 data_width;
+    u16 size;
+    u8 form_factor;
+    u8 device_set;
+    u8 device_locator_str;
+    u8 bank_locator_str;
+    u8 memory_type;
+    u16 type_detail;
+} PACKED;
+
+/* SMBIOS type 19 - Memory Array Mapped Address */
+struct smbios_type_19 {
+    struct smbios_structure_header header;
+    u32 starting_address;
+    u32 ending_address;
+    u16 memory_array_handle;
+    u8 partition_width;
+} PACKED;
+
+/* SMBIOS type 20 - Memory Device Mapped Address */
+struct smbios_type_20 {
+    struct smbios_structure_header header;
+    u32 starting_address;
+    u32 ending_address;
+    u16 memory_device_handle;
+    u16 memory_array_mapped_address_handle;
+    u8 partition_row_position;
+    u8 interleave_position;
+    u8 interleaved_data_depth;
+} PACKED;
+
+/* SMBIOS type 32 - System Boot Information */
+struct smbios_type_32 {
+    struct smbios_structure_header header;
+    u8 reserved[6];
+    u8 boot_status;
+} PACKED;
+
+/* SMBIOS type 127 -- End-of-table */
+struct smbios_type_127 {
+    struct smbios_structure_header header;
+} PACKED;
+
+void display_uuid(void);
+#endif // smbios.h
diff --git a/src/fw/smm.c b/src/fw/smm.c
new file mode 100644 (file)
index 0000000..3f01207
--- /dev/null
@@ -0,0 +1,196 @@
+// System Management Mode support (on emulators)
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "hw/pci.h" // pci_config_writel
+#include "hw/pci_regs.h" // PCI_DEVICE_ID
+#include "util.h" // wbinvd
+#include "config.h" // CONFIG_*
+#include "ioport.h" // outb
+#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
+#include "dev-q35.h"
+
+extern u8 smm_relocation_start, smm_relocation_end;
+ASM32FLAT(
+    ".global smm_relocation_start, smm_relocation_end\n"
+    "  .code16gcc\n"
+
+    /* code to relocate SMBASE to 0xa0000 */
+    "smm_relocation_start:\n"
+    "  movl $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7efc, %ebx\n"
+    "  addr32 movb (%ebx), %al\n"  /* revision ID to see if x86_64 or x86 */
+    "  cmpb $0x64, %al\n"
+    "  je 1f\n"
+    "  movl $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7ef8, %ebx\n"
+    "  jmp 2f\n"
+    "1:\n"
+    "  movl $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7f00, %ebx\n"
+    "2:\n"
+    "  movl $" __stringify(BUILD_SMM_ADDR) " - 0x8000, %eax\n"
+    "  addr32 movl %eax, (%ebx)\n"
+    /* indicate to the BIOS that the SMM code was executed */
+    "  movb $0x00, %al\n"
+    "  movw $" __stringify(PORT_SMI_STATUS) ", %dx\n"
+    "  outb %al, %dx\n"
+    "  rsm\n"
+    "smm_relocation_end:\n"
+    "  .code32\n"
+    );
+
+extern u8 smm_code_start, smm_code_end;
+ASM32FLAT(
+    /* minimal SMM code to enable or disable ACPI */
+    ".global smm_code_start, smm_code_end\n"
+    "  .code16gcc\n"
+    "smm_code_start:\n"
+    "  movw $" __stringify(PORT_SMI_CMD) ", %dx\n"
+    "  inb %dx, %al\n"
+    "  cmpb $0xf0, %al\n"
+    "  jne 1f\n"
+
+    /* ACPI disable */
+    "  movw $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */
+    "  inw %dx, %ax\n"
+    "  andw $~1, %ax\n"
+    "  outw %ax, %dx\n"
+
+    "  jmp 2f\n"
+
+    "1:\n"
+    "  cmpb $0xf1, %al\n"
+    "  jne 2f\n"
+
+    /* ACPI enable */
+    "  movw $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */
+    "  inw %dx, %ax\n"
+    "  orw $1, %ax\n"
+    "  outw %ax, %dx\n"
+
+    "2:\n"
+    "  rsm\n"
+    "smm_code_end:\n"
+    "  .code32\n"
+    );
+
+static void
+smm_save_and_copy(void)
+{
+    /* save original memory content */
+    memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE);
+
+    /* copy the SMM relocation code */
+    memcpy((void *)BUILD_SMM_INIT_ADDR, &smm_relocation_start,
+           &smm_relocation_end - &smm_relocation_start);
+}
+
+static void
+smm_relocate_and_restore(void)
+{
+    /* init APM status port */
+    outb(0x01, PORT_SMI_STATUS);
+
+    /* raise an SMI interrupt */
+    outb(0x00, PORT_SMI_CMD);
+
+    /* wait until SMM code executed */
+    while (inb(PORT_SMI_STATUS) != 0x00)
+        ;
+
+    /* restore original memory content */
+    memcpy((void *)BUILD_SMM_INIT_ADDR, (void *)BUILD_SMM_ADDR, BUILD_SMM_SIZE);
+
+    /* copy the SMM code */
+    memcpy((void *)BUILD_SMM_ADDR, &smm_code_start
+           , &smm_code_end - &smm_code_start);
+    wbinvd();
+}
+
+#define I440FX_SMRAM    0x72
+#define PIIX_DEVACTB    0x58
+#define PIIX_APMC_EN    (1 << 25)
+
+// This code is hardcoded for PIIX4 Power Management device.
+static void piix4_apmc_smm_setup(int isabdf, int i440_bdf)
+{
+    /* check if SMM init is already done */
+    u32 value = pci_config_readl(isabdf, PIIX_DEVACTB);
+    if (value & PIIX_APMC_EN)
+        return;
+
+    /* enable the SMM memory window */
+    pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x48);
+
+    smm_save_and_copy();
+
+    /* enable SMI generation when writing to the APMC register */
+    pci_config_writel(isabdf, PIIX_DEVACTB, value | PIIX_APMC_EN);
+
+    smm_relocate_and_restore();
+
+    /* close the SMM memory window and enable normal SMM */
+    pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x08);
+}
+
+/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
+void ich9_lpc_apmc_smm_setup(int isabdf, int mch_bdf)
+{
+    /* check if SMM init is already done */
+    u32 value = inl(PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN);
+    if (value & ICH9_PMIO_SMI_EN_APMC_EN)
+        return;
+
+    /* enable the SMM memory window */
+    pci_config_writeb(mch_bdf, Q35_HOST_BRIDGE_SMRAM, 0x02 | 0x48);
+
+    smm_save_and_copy();
+
+    /* enable SMI generation when writing to the APMC register */
+    outl(value | ICH9_PMIO_SMI_EN_APMC_EN,
+         PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN);
+
+    smm_relocate_and_restore();
+
+    /* close the SMM memory window and enable normal SMM */
+    pci_config_writeb(mch_bdf, Q35_HOST_BRIDGE_SMRAM, 0x02 | 0x08);
+}
+
+static int SMMISADeviceBDF = -1, SMMPMDeviceBDF = -1;
+
+void
+smm_device_setup(void)
+{
+    if (!CONFIG_USE_SMM)
+       return;
+
+    struct pci_device *isapci, *pmpci;
+    isapci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3);
+    pmpci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
+    if (isapci && pmpci) {
+        SMMISADeviceBDF = isapci->bdf;
+        SMMPMDeviceBDF = pmpci->bdf;
+        return;
+    }
+    isapci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC);
+    pmpci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH);
+    if (isapci && pmpci) {
+        SMMISADeviceBDF = isapci->bdf;
+        SMMPMDeviceBDF = pmpci->bdf;
+    }
+}
+
+void
+smm_setup(void)
+{
+    if (!CONFIG_USE_SMM || SMMISADeviceBDF < 0)
+       return;
+
+    dprintf(3, "init smm\n");
+    u16 device = pci_config_readw(SMMISADeviceBDF, PCI_DEVICE_ID);
+    if (device == PCI_DEVICE_ID_INTEL_82371AB_3)
+        piix4_apmc_smm_setup(SMMISADeviceBDF, SMMPMDeviceBDF);
+    else
+        ich9_lpc_apmc_smm_setup(SMMISADeviceBDF, SMMPMDeviceBDF);
+}
diff --git a/src/fw/smp.c b/src/fw/smp.c
new file mode 100644 (file)
index 0000000..6379d36
--- /dev/null
@@ -0,0 +1,144 @@
+// CPU count detection
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2006 Fabrice Bellard
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "util.h" // dprintf
+#include "config.h" // CONFIG_*
+#include "hw/cmos.h" // CMOS_BIOS_SMP_COUNT
+
+#define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300)
+#define APIC_SVR     ((u8*)BUILD_APIC_ADDR + 0x0F0)
+#define APIC_LINT0   ((u8*)BUILD_APIC_ADDR + 0x350)
+#define APIC_LINT1   ((u8*)BUILD_APIC_ADDR + 0x360)
+
+#define APIC_ENABLED 0x0100
+
+struct { u32 ecx, eax, edx; } smp_mtrr[32] VARFSEG;
+u32 smp_mtrr_count VARFSEG;
+
+void
+wrmsr_smp(u32 index, u64 val)
+{
+    wrmsr(index, val);
+    if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr)) {
+        warn_noalloc();
+        return;
+    }
+    smp_mtrr[smp_mtrr_count].ecx = index;
+    smp_mtrr[smp_mtrr_count].eax = val;
+    smp_mtrr[smp_mtrr_count].edx = val >> 32;
+    smp_mtrr_count++;
+}
+
+u32 CountCPUs VARFSEG;
+u32 MaxCountCPUs;
+// 256 bits for the found APIC IDs
+u32 FoundAPICIDs[256/32] VARFSEG;
+extern void smp_ap_boot_code(void);
+ASM16(
+    "  .global smp_ap_boot_code\n"
+    "smp_ap_boot_code:\n"
+
+    // Setup data segment
+    "  movw $" __stringify(SEG_BIOS) ", %ax\n"
+    "  movw %ax, %ds\n"
+
+    // MTRR setup
+    "  movl $smp_mtrr, %esi\n"
+    "  movl smp_mtrr_count, %ebx\n"
+    "1:testl %ebx, %ebx\n"
+    "  jz 2f\n"
+    "  movl 0(%esi), %ecx\n"
+    "  movl 4(%esi), %eax\n"
+    "  movl 8(%esi), %edx\n"
+    "  wrmsr\n"
+    "  addl $12, %esi\n"
+    "  decl %ebx\n"
+    "  jmp 1b\n"
+    "2:\n"
+
+    // get apic ID on EBX, set bit on FoundAPICIDs
+    "  movl $1, %eax\n"
+    "  cpuid\n"
+    "  shrl $24, %ebx\n"
+    "  lock btsl %ebx, FoundAPICIDs\n"
+
+    // Increment the cpu counter
+    "  lock incl CountCPUs\n"
+
+    // Halt the processor.
+    "1:hlt\n"
+    "  jmp 1b\n"
+    );
+
+int apic_id_is_present(u8 apic_id)
+{
+    return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32)));
+}
+
+// find and initialize the CPUs by launching a SIPI to them
+void
+smp_setup(void)
+{
+    if (!CONFIG_QEMU)
+        return;
+
+    ASSERT32FLAT();
+    u32 eax, ebx, ecx, cpuid_features;
+    cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
+    if (eax < 1 || !(cpuid_features & CPUID_APIC)) {
+        // No apic - only the main cpu is present.
+        dprintf(1, "No apic - only the main cpu is present.\n");
+        CountCPUs= 1;
+        MaxCountCPUs = 1;
+        return;
+    }
+
+    // mark the BSP initial APIC ID as found, too:
+    u8 apic_id = ebx>>24;
+    FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
+
+    // Init the counter.
+    writel(&CountCPUs, 1);
+
+    // Setup jump trampoline to counter code.
+    u64 old = *(u64*)BUILD_AP_BOOT_ADDR;
+    // ljmpw $SEG_BIOS, $(smp_ap_boot_code - BUILD_BIOS_ADDR)
+    u64 new = (0xea | ((u64)SEG_BIOS<<24)
+               | (((u32)smp_ap_boot_code - BUILD_BIOS_ADDR) << 8));
+    *(u64*)BUILD_AP_BOOT_ADDR = new;
+
+    // enable local APIC
+    u32 val = readl(APIC_SVR);
+    writel(APIC_SVR, val | APIC_ENABLED);
+
+    /* Set LINT0 as Ext_INT, level triggered */
+    writel(APIC_LINT0, 0x8700);
+
+    /* Set LINT1 as NMI, level triggered */
+    writel(APIC_LINT1, 0x8400);
+
+    // broadcast SIPI
+    barrier();
+    writel(APIC_ICR_LOW, 0x000C4500);
+    u32 sipi_vector = BUILD_AP_BOOT_ADDR >> 12;
+    writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
+
+    // Wait for other CPUs to process the SIPI.
+    u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT);
+    while (cmos_smp_count + 1 != readl(&CountCPUs))
+        yield();
+
+    // Restore memory.
+    *(u64*)BUILD_AP_BOOT_ADDR = old;
+
+    MaxCountCPUs = romfile_loadint("etc/max-cpus", 0);
+    if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
+        MaxCountCPUs = CountCPUs;
+
+    dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", readl(&CountCPUs),
+        MaxCountCPUs);
+}
diff --git a/src/fw/ssdt-misc.dsl b/src/fw/ssdt-misc.dsl
new file mode 100644 (file)
index 0000000..acc850e
--- /dev/null
@@ -0,0 +1,104 @@
+ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
+
+DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
+{
+
+/****************************************************************
+ * PCI memory ranges
+ ****************************************************************/
+
+    Scope(\) {
+       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
+       Name(P0S, 0x12345678)
+       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
+       Name(P0E, 0x12345678)
+       ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
+       Name(P1V, 0x12)
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start
+       Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end
+       Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
+       Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+    }
+
+
+/****************************************************************
+ * Suspend
+ ****************************************************************/
+
+    Scope(\) {
+    /*
+     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
+     * must match piix4 emulation.
+     */
+
+        ACPI_EXTRACT_NAME_STRING acpi_s3_name
+        Name(_S3, Package(0x04) {
+            One,  /* PM1a_CNT.SLP_TYP */
+            One,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+        ACPI_EXTRACT_NAME_STRING acpi_s4_name
+        ACPI_EXTRACT_PKG_START acpi_s4_pkg
+        Name(_S4, Package(0x04) {
+            0x2,  /* PM1a_CNT.SLP_TYP */
+            0x2,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+        Name(_S5, Package(0x04) {
+            Zero,  /* PM1a_CNT.SLP_TYP */
+            Zero,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+    }
+
+    External(\_SB.PCI0, DeviceObj)
+    External(\_SB.PCI0.ISA, DeviceObj)
+
+    Scope(\_SB.PCI0.ISA) {
+        Device(PEVT) {
+            Name(_HID, "QEMU0001")
+            /* PEST will be patched to be Zero if no such device */
+            ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest
+            Name(PEST, 0xFFFF)
+            OperationRegion(PEOR, SystemIO, PEST, 0x01)
+            Field(PEOR, ByteAcc, NoLock, Preserve) {
+                PEPT,   8,
+            }
+
+            Method(_STA, 0, NotSerialized) {
+                Store(PEST, Local0)
+                If (LEqual(Local0, Zero)) {
+                    Return (0x00)
+                } Else {
+                    Return (0x0F)
+                }
+            }
+
+            Method(RDPT, 0, NotSerialized) {
+                Store(PEPT, Local0)
+                Return (Local0)
+            }
+
+            Method(WRPT, 1, NotSerialized) {
+                Store(Arg0, PEPT)
+            }
+
+            Name(_CRS, ResourceTemplate() {
+                IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
+            })
+
+            CreateWordField(_CRS, IO._MIN, IOMN)
+            CreateWordField(_CRS, IO._MAX, IOMX)
+
+            Method(_INI, 0, NotSerialized) {
+                Store(PEST, IOMN)
+                Store(PEST, IOMX)
+            }
+        }
+    }
+}
diff --git a/src/fw/ssdt-pcihp.dsl b/src/fw/ssdt-pcihp.dsl
new file mode 100644 (file)
index 0000000..67e485f
--- /dev/null
@@ -0,0 +1,36 @@
+ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml
+
+DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
+{
+
+/****************************************************************
+ * PCI hotplug
+ ****************************************************************/
+
+    /* Objects supplied by DSDT */
+    External(\_SB.PCI0, DeviceObj)
+    External(\_SB.PCI0.PCEJ, MethodObj)
+
+    Scope(\_SB.PCI0) {
+
+        /* Bulk generated PCI hotplug devices */
+        ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start
+        ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end
+        ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name
+
+        // Method _EJ0 can be patched by BIOS to EJ0_
+        // at runtime, if the slot is detected to not support hotplug.
+        // Extract the offset of the address dword and the
+        // _EJ0 name to allow this patching.
+        Device(SAA) {
+            ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id
+            Name(_SUN, 0xAA)
+            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr
+            Name(_ADR, 0xAA0000)
+            ACPI_EXTRACT_METHOD_STRING ssdt_pcihp_ej0
+            Method(_EJ0, 1) {
+                Return (PCEJ(_SUN))
+            }
+        }
+    }
+}
diff --git a/src/fw/ssdt-proc.dsl b/src/fw/ssdt-proc.dsl
new file mode 100644 (file)
index 0000000..407d61e
--- /dev/null
@@ -0,0 +1,48 @@
+/* This file is the basis for the ssdt table generated in src/acpi.c.
+ * It defines the contents of the per-cpu Processor() object.  At
+ * runtime, a dynamically generated SSDT will contain one copy of this
+ * AML snippet for every possible cpu in the system.  The objects will
+ * be placed in the \_SB_ namespace.
+ *
+ * In addition to the aml code generated from this file, the
+ * src/acpi.c file creates a NTFY method with an entry for each cpu:
+ *     Method(NTFY, 2) {
+ *         If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) }
+ *         If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) }
+ *         ...
+ *     }
+ * and a CPON array with the list of active and inactive cpus:
+ *     Name(CPON, Package() { One, One, ..., Zero, Zero, ... })
+ */
+
+ACPI_EXTRACT_ALL_CODE ssdp_proc_aml
+
+DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1)
+{
+    ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start
+    ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end
+    ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name
+    Processor(CPAA, 0xAA, 0x0000b010, 0x06) {
+        ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id
+        Name(ID, 0xAA)
+/*
+ * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update
+ * CPAA and 0xAA with the appropriate CPU id (see
+ * SD_OFFSET_CPUHEX/CPUID1/CPUID2).  Don't change the above without
+ * also updating the C code.
+ */
+        Name(_HID, "ACPI0007")
+        External(CPMA, MethodObj)
+        External(CPST, MethodObj)
+        External(CPEJ, MethodObj)
+        Method(_MAT, 0) {
+            Return (CPMA(ID))
+        }
+        Method(_STA, 0) {
+            Return (CPST(ID))
+        }
+        Method(_EJ0, 1, NotSerialized) {
+            CPEJ(ID, Arg0)
+        }
+    }
+}
diff --git a/src/fw/xen.c b/src/fw/xen.c
new file mode 100644 (file)
index 0000000..5dfee9e
--- /dev/null
@@ -0,0 +1,144 @@
+// Xen HVM support
+//
+// Copyright (C) 2011 Citrix Systems.
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h"
+#include "xen.h"
+#include "paravirt.h" // PlatformRunningOn
+#include "memmap.h" // add_e820
+#include "types.h" // ASM32FLAT
+#include "util.h" // copy_acpi_rsdp
+#include "acpi.h" // find_acpi_features
+
+#define INFO_PHYSICAL_ADDRESS 0x00001000
+
+u32 xen_cpuid_base = 0;
+unsigned long xen_hypercall_page = 0;
+
+struct xen_seabios_info {
+    char signature[14]; /* XenHVMSeaBIOS\0 */
+    u8 length;     /* Length of this struct */
+    u8 checksum;   /* Set such that the sum over bytes 0..length == 0 */
+    /*
+     * Physical address of an array of tables_nr elements.
+     *
+     * Each element is a 32 bit value contianing the physical address
+     * of a BIOS table.
+     */
+    u32 tables;
+    u32 tables_nr;
+    /*
+     * Physical address of the e820 table, contains e820_nr entries.
+     */
+    u32 e820;
+    u32 e820_nr;
+} PACKED;
+
+static void validate_info(struct xen_seabios_info *t)
+{
+    if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) )
+        panic("Bad Xen info signature\n");
+
+    if ( t->length < sizeof(struct xen_seabios_info) )
+        panic("Bad Xen info length\n");
+
+    if (checksum(t, t->length) != 0)
+        panic("Bad Xen info checksum\n");
+}
+
+void xen_preinit(void)
+{
+    u32 base, eax, ebx, ecx, edx;
+    char signature[13];
+
+    if (!CONFIG_XEN)
+        return;
+
+    for (base = 0x40000000; base < 0x40010000; base += 0x100) {
+        cpuid(base, &eax, &ebx, &ecx, &edx);
+        memcpy(signature + 0, &ebx, 4);
+        memcpy(signature + 4, &ecx, 4);
+        memcpy(signature + 8, &edx, 4);
+        signature[12] = 0;
+
+        dprintf(9, "Found hypervisor signature \"%s\" at %x\n",
+                signature, base);
+        if (strcmp(signature, "XenVMMXenVMM") == 0) {
+            /* Set debug_io_port first, so the following messages work. */
+            DebugOutputPort = 0xe9;
+            dprintf(1, "SeaBIOS (version %s)\n\n", VERSION);
+            dprintf(1, "Found Xen hypervisor signature at %x\n", base);
+            if ((eax - base) < 2)
+                panic("Insufficient Xen cpuid leaves. eax=%x at base %x\n",
+                      eax, base);
+            xen_cpuid_base = base;
+            break;
+        }
+    }
+    if (!xen_cpuid_base) {
+        dprintf(1, "No Xen hypervisor found.\n");
+        return;
+    }
+    PlatformRunningOn = PF_QEMU|PF_XEN;
+}
+
+static int hypercall_xen_version( int cmd, void *arg)
+{
+    return _hypercall2(int, xen_version, cmd, arg);
+}
+
+/* Fill in hypercall transfer pages. */
+void xen_hypercall_setup(void)
+{
+    u32 eax, ebx, ecx, edx;
+    xen_extraversion_t extraversion;
+    unsigned long i;
+
+    if (!runningOnXen())
+        return;
+
+    cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx);
+
+    xen_hypercall_page = (unsigned long)memalign_high(PAGE_SIZE, eax*PAGE_SIZE);
+    if (!xen_hypercall_page)
+        panic("unable to allocate Xen hypercall page\n");
+
+    dprintf(1, "Allocated Xen hypercall page at %lx\n", xen_hypercall_page);
+    for ( i = 0; i < eax; i++ )
+        wrmsr(ebx, xen_hypercall_page + (i << 12) + i);
+
+    /* Print version information. */
+    cpuid(xen_cpuid_base + 1, &eax, &ebx, &ecx, &edx);
+    hypercall_xen_version(XENVER_extraversion, extraversion);
+    dprintf(1, "Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
+}
+
+void xen_biostable_setup(void)
+{
+    struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS;
+    void **tables = (void*)info->tables;
+    int i;
+
+    dprintf(1, "xen: copy BIOS tables...\n");
+    for (i=0; i<info->tables_nr; i++)
+        copy_table(tables[i]);
+
+    find_acpi_features();
+}
+
+void xen_ramsize_preinit(void)
+{
+    int i;
+    struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS;
+    struct e820entry *e820 = (struct e820entry *)info->e820;
+    validate_info(info);
+
+    dprintf(1, "xen: copy e820...\n");
+
+    for (i = 0; i < info->e820_nr; i++) {
+        struct e820entry *e = &e820[i];
+        add_e820(e->start, e->size, e->type);
+    }
+}
diff --git a/src/fw/xen.h b/src/fw/xen.h
new file mode 100644 (file)
index 0000000..f00f840
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef __XEN_H
+#define __XEN_H
+
+void xen_preinit(void);
+void xen_ramsize_preinit(void);
+void xen_hypercall_setup(void);
+void xen_biostable_setup(void);
+
+extern unsigned long xen_hypercall_page;
+
+#define _hypercall0(type, name)                                         \
+({                                                                      \
+    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
+    long __res;                                                         \
+    asm volatile (                                                      \
+        "call *%%eax"                                                   \
+        : "=a" (__res)                                                  \
+        : "0" (__hentry)                                                \
+        : "memory" );                                                   \
+    (type)__res;                                                        \
+})
+
+#define _hypercall1(type, name, a1)                                     \
+({                                                                      \
+    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
+    long __res, __ign1;                                                 \
+    asm volatile (                                                      \
+        "call *%%eax"                                                   \
+        : "=a" (__res), "=b" (__ign1)                                   \
+        : "0" (__hentry), "1" ((long)(a1))                              \
+        : "memory" );                                                   \
+    (type)__res;                                                        \
+})
+
+#define _hypercall2(type, name, a1, a2)                                 \
+({                                                                      \
+    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
+    long __res, __ign1, __ign2;                                         \
+    asm volatile (                                                      \
+        "call *%%eax"                                                   \
+        : "=a" (__res), "=b" (__ign1), "=c" (__ign2)                    \
+        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2))            \
+        : "memory" );                                                   \
+    (type)__res;                                                        \
+})
+
+#define _hypercall3(type, name, a1, a2, a3)                             \
+({                                                                      \
+    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
+    long __res, __ign1, __ign2, __ign3;                                 \
+    asm volatile (                                                      \
+        "call *%%eax"                                                   \
+        : "=a" (__res), "=b" (__ign1), "=c" (__ign2),                   \
+          "=d" (__ign3)                                                 \
+        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2)),           \
+          "3" ((long)(a3))                                              \
+        : "memory" );                                                   \
+    (type)__res;                                                        \
+})
+
+#define _hypercall4(type, name, a1, a2, a3, a4)                         \
+({                                                                      \
+    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
+    long __res, __ign1, __ign2, __ign3, __ign4;                         \
+    asm volatile (                                                      \
+        "call *%%eax"                                                   \
+        : "=a" (__res), "=b" (__ign1), "=c" (__ign2),                   \
+          "=d" (__ign3), "=S" (__ign4)                                  \
+        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2)),           \
+          "3" ((long)(a3)), "4" ((long)(a4))                            \
+        : "memory" );                                                   \
+    (type)__res;                                                        \
+})
+
+#define _hypercall5(type, name, a1, a2, a3, a4, a5)                     \
+({                                                                      \
+    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
+    long __res, __ign1, __ign2, __ign3, __ign4, __ign5;                 \
+    asm volatile (                                                      \
+        "call *%%eax"                                                   \
+        : "=a" (__res), "=b" (__ign1), "=c" (__ign2),                   \
+          "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)                   \
+        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2)),           \
+          "3" ((long)(a3)), "4" ((long)(a4)),                           \
+          "5" ((long)(a5))                                              \
+        : "memory" );                                                   \
+    (type)__res;                                                        \
+})
+
+/******************************************************************************
+ *
+ * The following interface definitions are taken from Xen and have the
+ * following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* xen.h */
+
+#define __HYPERVISOR_xen_version          17
+
+/* version.h */
+
+/* arg == xen_extraversion_t. */
+#define XENVER_extraversion 1
+typedef char xen_extraversion_t[16];
+#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))
+
+#endif
index fe7036693e4dd2f6b7c5fb6d800f0694cd81d824..42a790f9c9c06424721e3373d5030e60c776e966 100644 (file)
@@ -18,7 +18,7 @@
 #include "pci_regs.h" // PCI_VENDOR_ID
 #include "boot.h" // bootprio_find_scsi_device
 #include "blockcmd.h" // scsi_drive_setup
-#include "paravirt.h" // runningOnQEMU
+#include "fw/paravirt.h" // runningOnQEMU
 #include "disk.h"
 
 #define ESP_TCLO      0x00
index 305610a5acaa2762422e3f9ca80a183628484474..cebe9674440d3a8777e7bc7ffd13909d4468415f 100644 (file)
@@ -18,7 +18,7 @@
 #include "pci_regs.h" // PCI_VENDOR_ID
 #include "boot.h" // bootprio_find_scsi_device
 #include "blockcmd.h" // scsi_drive_setup
-#include "paravirt.h" // runningOnQEMU
+#include "fw/paravirt.h" // runningOnQEMU
 #include "disk.h"
 
 #define LSI_REG_DSTAT     0x0c
diff --git a/src/lzmadecode.c b/src/lzmadecode.c
deleted file mode 100644 (file)
index 65819b5..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
-  LzmaDecode.c
-  LZMA Decoder (optimized for Speed version)
-  
-  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
-  http://www.7-zip.org/
-
-  LZMA SDK is licensed under two licenses:
-  1) GNU Lesser General Public License (GNU LGPL)
-  2) Common Public License (CPL)
-  It means that you can select one of these two licenses and 
-  follow rules of that license.
-
-  SPECIAL EXCEPTION:
-  Igor Pavlov, as the author of this Code, expressly permits you to 
-  statically or dynamically link your Code (or bind by name) to the 
-  interfaces of this file without subjecting your linked Code to the 
-  terms of the CPL or GNU LGPL. Any modifications or additions 
-  to this file, however, are subject to the LGPL or CPL terms.
-*/
-
-#include "lzmadecode.h"
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_READ_BYTE (*Buffer++)
-
-#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
-  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
-
-
-#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
-
-#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
-
-#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
-
-#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
-#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
-#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
-
-#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
-  { UpdateBit0(p); mi <<= 1; A0; } else \
-  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
-  
-#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
-
-#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
-  { int i = numLevels; res = 1; \
-  do { CProb *cp = probs + res; RC_GET_BIT(cp, res) } while(--i != 0); \
-  res -= (1 << numLevels); }
-
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
-
-
-#define kNumStates 12
-#define kNumLitStates 7
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-#if Literal != LZMA_BASE_SIZE
-StopCompilingDueBUG
-#endif
-
-int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
-{
-  unsigned char prop0;
-  if (size < LZMA_PROPERTIES_SIZE)
-    return LZMA_RESULT_DATA_ERROR;
-  prop0 = propsData[0];
-  if (prop0 >= (9 * 5 * 5))
-    return LZMA_RESULT_DATA_ERROR;
-  {
-    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
-    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
-    propsRes->lc = prop0;
-    /*
-    unsigned char remainder = (unsigned char)(prop0 / 9);
-    propsRes->lc = prop0 % 9;
-    propsRes->pb = remainder / 5;
-    propsRes->lp = remainder % 5;
-    */
-  }
-
-  return LZMA_RESULT_OK;
-}
-
-#define kLzmaStreamWasFinishedId (-1)
-
-int LzmaDecode(CLzmaDecoderState *vs,
-    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
-    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
-{
-  CProb *p = vs->Probs;
-  SizeT nowPos = 0;
-  Byte previousByte = 0;
-  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
-  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
-  int lc = vs->Properties.lc;
-
-
-  int state = 0;
-  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
-  int len = 0;
-  const Byte *Buffer;
-  const Byte *BufferLim;
-  UInt32 Range;
-  UInt32 Code;
-
-  *inSizeProcessed = 0;
-  *outSizeProcessed = 0;
-
-  {
-    UInt32 i;
-    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
-    for (i = 0; i < numProbs; i++)
-      p[i] = kBitModelTotal >> 1;
-  }
-  
-  RC_INIT(inStream, inSize);
-
-
-  while(nowPos < outSize)
-  {
-    CProb *prob;
-    UInt32 bound;
-    int posState = (int)(
-        (nowPos 
-        )
-        & posStateMask);
-
-    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
-    IfBit0(prob)
-    {
-      int symbol = 1;
-      UpdateBit0(prob)
-      prob = p + Literal + (LZMA_LIT_SIZE * 
-        (((
-        (nowPos 
-        )
-        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
-
-      if (state >= kNumLitStates)
-      {
-        int matchByte;
-        matchByte = outStream[nowPos - rep0];
-        do
-        {
-          int bit;
-          CProb *probLit;
-          matchByte <<= 1;
-          bit = (matchByte & 0x100);
-          probLit = prob + 0x100 + bit + symbol;
-          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
-        }
-        while (symbol < 0x100);
-      }
-      while (symbol < 0x100)
-      {
-        CProb *probLit = prob + symbol;
-        RC_GET_BIT(probLit, symbol)
-      }
-      previousByte = (Byte)symbol;
-
-      outStream[nowPos++] = previousByte;
-      if (state < 4) state = 0;
-      else if (state < 10) state -= 3;
-      else state -= 6;
-    }
-    else             
-    {
-      UpdateBit1(prob);
-      prob = p + IsRep + state;
-      IfBit0(prob)
-      {
-        UpdateBit0(prob);
-        rep3 = rep2;
-        rep2 = rep1;
-        rep1 = rep0;
-        state = state < kNumLitStates ? 0 : 3;
-        prob = p + LenCoder;
-      }
-      else
-      {
-        UpdateBit1(prob);
-        prob = p + IsRepG0 + state;
-        IfBit0(prob)
-        {
-          UpdateBit0(prob);
-          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
-          IfBit0(prob)
-          {
-            UpdateBit0(prob);
-            
-            if (nowPos == 0)
-              return LZMA_RESULT_DATA_ERROR;
-            
-            state = state < kNumLitStates ? 9 : 11;
-            previousByte = outStream[nowPos - rep0];
-            outStream[nowPos++] = previousByte;
-
-            continue;
-          }
-          else
-          {
-            UpdateBit1(prob);
-          }
-        }
-        else
-        {
-          UInt32 distance;
-          UpdateBit1(prob);
-          prob = p + IsRepG1 + state;
-          IfBit0(prob)
-          {
-            UpdateBit0(prob);
-            distance = rep1;
-          }
-          else 
-          {
-            UpdateBit1(prob);
-            prob = p + IsRepG2 + state;
-            IfBit0(prob)
-            {
-              UpdateBit0(prob);
-              distance = rep2;
-            }
-            else
-            {
-              UpdateBit1(prob);
-              distance = rep3;
-              rep3 = rep2;
-            }
-            rep2 = rep1;
-          }
-          rep1 = rep0;
-          rep0 = distance;
-        }
-        state = state < kNumLitStates ? 8 : 11;
-        prob = p + RepLenCoder;
-      }
-      {
-        int numBits, offset;
-        CProb *probLen = prob + LenChoice;
-        IfBit0(probLen)
-        {
-          UpdateBit0(probLen);
-          probLen = prob + LenLow + (posState << kLenNumLowBits);
-          offset = 0;
-          numBits = kLenNumLowBits;
-        }
-        else
-        {
-          UpdateBit1(probLen);
-          probLen = prob + LenChoice2;
-          IfBit0(probLen)
-          {
-            UpdateBit0(probLen);
-            probLen = prob + LenMid + (posState << kLenNumMidBits);
-            offset = kLenNumLowSymbols;
-            numBits = kLenNumMidBits;
-          }
-          else
-          {
-            UpdateBit1(probLen);
-            probLen = prob + LenHigh;
-            offset = kLenNumLowSymbols + kLenNumMidSymbols;
-            numBits = kLenNumHighBits;
-          }
-        }
-        RangeDecoderBitTreeDecode(probLen, numBits, len);
-        len += offset;
-      }
-
-      if (state < 4)
-      {
-        int posSlot;
-        state += kNumLitStates;
-        prob = p + PosSlot +
-            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
-            kNumPosSlotBits);
-        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
-        if (posSlot >= kStartPosModelIndex)
-        {
-          int numDirectBits = ((posSlot >> 1) - 1);
-          rep0 = (2 | ((UInt32)posSlot & 1));
-          if (posSlot < kEndPosModelIndex)
-          {
-            rep0 <<= numDirectBits;
-            prob = p + SpecPos + rep0 - posSlot - 1;
-          }
-          else
-          {
-            numDirectBits -= kNumAlignBits;
-            do
-            {
-              RC_NORMALIZE
-              Range >>= 1;
-              rep0 <<= 1;
-              if (Code >= Range)
-              {
-                Code -= Range;
-                rep0 |= 1;
-              }
-            }
-            while (--numDirectBits != 0);
-            prob = p + Align;
-            rep0 <<= kNumAlignBits;
-            numDirectBits = kNumAlignBits;
-          }
-          {
-            int i = 1;
-            int mi = 1;
-            do
-            {
-              CProb *prob3 = prob + mi;
-              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
-              i <<= 1;
-            }
-            while(--numDirectBits != 0);
-          }
-        }
-        else
-          rep0 = posSlot;
-        if (++rep0 == (UInt32)(0))
-        {
-          /* it's for stream version */
-          len = kLzmaStreamWasFinishedId;
-          break;
-        }
-      }
-
-      len += kMatchMinLen;
-      if (rep0 > nowPos)
-        return LZMA_RESULT_DATA_ERROR;
-
-
-      do
-      {
-        previousByte = outStream[nowPos - rep0];
-        len--;
-        outStream[nowPos++] = previousByte;
-      }
-      while(len != 0 && nowPos < outSize);
-    }
-  }
-  RC_NORMALIZE;
-
-
-  *inSizeProcessed = (SizeT)(Buffer - inStream);
-  *outSizeProcessed = nowPos;
-  return LZMA_RESULT_OK;
-}
diff --git a/src/lzmadecode.h b/src/lzmadecode.h
deleted file mode 100644 (file)
index dedde0d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 
-  LzmaDecode.h
-  LZMA Decoder interface
-
-  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
-  http://www.7-zip.org/
-
-  LZMA SDK is licensed under two licenses:
-  1) GNU Lesser General Public License (GNU LGPL)
-  2) Common Public License (CPL)
-  It means that you can select one of these two licenses and 
-  follow rules of that license.
-
-  SPECIAL EXCEPTION:
-  Igor Pavlov, as the author of this code, expressly permits you to 
-  statically or dynamically link your code (or bind by name) to the 
-  interfaces of this file without subjecting your linked code to the 
-  terms of the CPL or GNU LGPL. Any modifications or additions 
-  to this file, however, are subject to the LGPL or CPL terms.
-*/
-
-#ifndef __LZMADECODE_H
-#define __LZMADECODE_H
-
-typedef unsigned char Byte;
-typedef unsigned short UInt16;
-typedef unsigned int UInt32;
-typedef UInt32 SizeT;
-
-#define CProb UInt16
-
-#define LZMA_RESULT_OK 0
-#define LZMA_RESULT_DATA_ERROR 1
-
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LZMA_PROPERTIES_SIZE 5
-
-typedef struct _CLzmaProperties
-{
-  int lc;
-  int lp;
-  int pb;
-}CLzmaProperties;
-
-int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
-
-#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
-
-#define kLzmaNeedInitId (-2)
-
-typedef struct _CLzmaDecoderState
-{
-  CLzmaProperties Properties;
-  CProb *Probs;
-
-
-} CLzmaDecoderState;
-
-
-int LzmaDecode(CLzmaDecoderState *vs,
-    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
-    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
-
-#endif
diff --git a/src/mptable.c b/src/mptable.c
deleted file mode 100644 (file)
index 2d12865..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-// MPTable generation (on emulators)
-//
-// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "util.h" // dprintf
-#include "config.h" // CONFIG_*
-#include "mptable.h" // MPTABLE_SIGNATURE
-#include "hw/pci.h"
-#include "hw/pci_regs.h"
-
-void
-mptable_setup(void)
-{
-    if (! CONFIG_MPTABLE)
-        return;
-
-    dprintf(3, "init MPTable\n");
-
-    // Config structure in temp area.
-    struct mptable_config_s *config = malloc_tmp(32*1024);
-    if (!config) {
-        warn_noalloc();
-        return;
-    }
-    memset(config, 0, sizeof(*config));
-    config->signature = MPCONFIG_SIGNATURE;
-    config->spec = 4;
-    memcpy(config->oemid, BUILD_CPUNAME8, sizeof(config->oemid));
-    memcpy(config->productid, "0.1         ", sizeof(config->productid));
-    config->lapic = BUILD_APIC_ADDR;
-
-    // Detect cpu info
-    u32 cpuid_signature, ebx, ecx, cpuid_features;
-    cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
-    if (! cpuid_signature) {
-        // Use default values.
-        cpuid_signature = 0x600;
-        cpuid_features = 0x201;
-    }
-    int pkgcpus = 1;
-    if (cpuid_features & (1 << 28)) {
-        /* Only populate the MPS tables with the first logical CPU in
-           each package */
-        pkgcpus = (ebx >> 16) & 0xff;
-        pkgcpus = 1 << (__fls(pkgcpus - 1) + 1); /* round up to power of 2 */
-    }
-    u8 apic_version = readl((u8*)BUILD_APIC_ADDR + 0x30) & 0xff;
-
-    // CPU definitions.
-    struct mpt_cpu *cpus = (void*)&config[1], *cpu = cpus;
-    int i;
-    for (i = 0; i < MaxCountCPUs; i+=pkgcpus) {
-        memset(cpu, 0, sizeof(*cpu));
-        cpu->type = MPT_TYPE_CPU;
-        cpu->apicid = i;
-        cpu->apicver = apic_version;
-        /* cpu flags: enabled, bootstrap cpu */
-        cpu->cpuflag = (apic_id_is_present(i) ? 0x01 : 0x00) | ((i==0) ? 0x02 : 0x00);
-        cpu->cpusignature = cpuid_signature;
-        cpu->featureflag = cpuid_features;
-        cpu++;
-    }
-    int entrycount = cpu - cpus;
-
-    // PCI bus
-    struct mpt_bus *buses = (void*)cpu, *bus = buses;
-    if (!hlist_empty(&PCIDevices)) {
-        memset(bus, 0, sizeof(*bus));
-        bus->type = MPT_TYPE_BUS;
-        bus->busid = 0;
-        memcpy(bus->bustype, "PCI   ", sizeof(bus->bustype));
-        bus++;
-        entrycount++;
-    }
-
-    /* isa bus */
-    int isabusid = bus - buses;
-    memset(bus, 0, sizeof(*bus));
-    bus->type = MPT_TYPE_BUS;
-    bus->busid = isabusid;
-    memcpy(bus->bustype, "ISA   ", sizeof(bus->bustype));
-    bus++;
-    entrycount++;
-
-    /* ioapic */
-    u8 ioapic_id = BUILD_IOAPIC_ID;
-    struct mpt_ioapic *ioapic = (void*)bus;
-    memset(ioapic, 0, sizeof(*ioapic));
-    ioapic->type = MPT_TYPE_IOAPIC;
-    ioapic->apicid = ioapic_id;
-    ioapic->apicver = 0x11;
-    ioapic->flags = 1; // enable
-    ioapic->apicaddr = BUILD_IOAPIC_ADDR;
-    entrycount++;
-
-    /* irqs */
-    struct mpt_intsrc *intsrcs = (void*)&ioapic[1], *intsrc = intsrcs;
-    int dev = -1;
-    unsigned short pinmask = 0;
-
-    struct pci_device *pci;
-    foreachpci(pci) {
-        u16 bdf = pci->bdf;
-        if (pci_bdf_to_bus(bdf) != 0)
-            break;
-        int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
-        int irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
-        if (pin == 0)
-            continue;
-        if (dev != pci_bdf_to_busdev(bdf)) {
-            dev = pci_bdf_to_busdev(bdf);
-            pinmask = 0;
-        }
-        if (pinmask & (1 << pin)) /* pin was seen already */
-            continue;
-        pinmask |= (1 << pin);
-        memset(intsrc, 0, sizeof(*intsrc));
-        intsrc->type = MPT_TYPE_INTSRC;
-        intsrc->irqtype = 0; /* INT */
-        intsrc->irqflag = 1; /* active high */
-        intsrc->srcbus = pci_bdf_to_bus(bdf); /* PCI bus */
-        intsrc->srcbusirq = (pci_bdf_to_dev(bdf) << 2) | (pin - 1);
-        intsrc->dstapic = ioapic_id;
-        intsrc->dstirq = irq;
-        intsrc++;
-    }
-
-    int irq0_override = romfile_loadint("etc/irq0-override", 0);
-    for (i = 0; i < 16; i++) {
-        memset(intsrc, 0, sizeof(*intsrc));
-        if (BUILD_PCI_IRQS & (1 << i))
-            continue;
-        intsrc->type = MPT_TYPE_INTSRC;
-        intsrc->irqtype = 0; /* INT */
-        intsrc->irqflag = 0; /* conform to bus spec */
-        intsrc->srcbus = isabusid; /* ISA bus */
-        intsrc->srcbusirq = i;
-        intsrc->dstapic = ioapic_id;
-        intsrc->dstirq = i;
-        if (irq0_override) {
-            /* Destination 2 is covered by irq0->inti2 override (i ==
-               0). Source IRQ 2 is unused */
-            if (i == 0)
-                intsrc->dstirq = 2;
-            else if (i == 2)
-                intsrc--;
-        }
-        intsrc++;
-    }
-
-    /* Local interrupt assignment */
-    intsrc->type = MPT_TYPE_LOCAL_INT;
-    intsrc->irqtype = 3; /* ExtINT */
-    intsrc->irqflag = 0; /* PO, EL default */
-    intsrc->srcbus = isabusid; /* ISA */
-    intsrc->srcbusirq = 0;
-    intsrc->dstapic = 0; /* BSP == APIC #0 */
-    intsrc->dstirq = 0; /* LINTIN0 */
-    intsrc++;
-
-    intsrc->type = MPT_TYPE_LOCAL_INT;
-    intsrc->irqtype = 1; /* NMI */
-    intsrc->irqflag = 0; /* PO, EL default */
-    intsrc->srcbus = isabusid; /* ISA */
-    intsrc->srcbusirq = 0;
-    intsrc->dstapic = 0xff; /* to all local APICs */
-    intsrc->dstirq = 1; /* LINTIN1 */
-    intsrc++;
-    entrycount += intsrc - intsrcs;
-
-    // Finalize config structure.
-    int length = (void*)intsrc - (void*)config;
-    config->entrycount = entrycount;
-    config->length = length;
-    config->checksum -= checksum(config, length);
-
-    // Allocate final memory locations.  (In theory the config
-    // structure can go in high memory, but Linux kernels before
-    // v2.6.30 crash with that.)
-    struct mptable_config_s *finalconfig = malloc_fseg(length);
-    struct mptable_floating_s *floating = malloc_fseg(sizeof(*floating));
-    if (!finalconfig || !floating) {
-        warn_noalloc();
-        free(config);
-        free(finalconfig);
-        free(floating);
-        return;
-    }
-    memcpy(finalconfig, config, length);
-    free(config);
-
-    /* floating pointer structure */
-    memset(floating, 0, sizeof(*floating));
-    floating->signature = MPTABLE_SIGNATURE;
-    floating->physaddr = (u32)finalconfig;
-    floating->length = 1;
-    floating->spec_rev = 4;
-    floating->checksum -= checksum(floating, sizeof(*floating));
-
-    dprintf(1, "MP table addr=%p MPC table addr=%p size=%d\n",
-            floating, finalconfig, length);
-}
diff --git a/src/mptable.h b/src/mptable.h
deleted file mode 100644 (file)
index 6252854..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef __MPTABLE_H
-#define __MPTABLE_H
-
-#include "types.h" // u32
-
-#define MPTABLE_SIGNATURE 0x5f504d5f  // "_MP_"
-
-struct mptable_floating_s {
-    u32 signature;
-    u32 physaddr;
-    u8 length;
-    u8 spec_rev;
-    u8 checksum;
-    u8 feature1;
-    u8 feature2;
-    u8 reserved[3];
-};
-
-#define MPCONFIG_SIGNATURE 0x504d4350  // "PCMP"
-
-struct mptable_config_s {
-    u32 signature;
-    u16 length;
-    u8 spec;
-    u8 checksum;
-    char oemid[8];
-    char productid[12];
-    u32 oemptr;
-    u16 oemsize;
-    u16 entrycount;
-    u32 lapic;
-    u16 exttable_length;
-    u8 exttable_checksum;
-    u8 reserved;
-} PACKED;
-
-#define MPT_TYPE_CPU 0
-#define MPT_TYPE_BUS 1
-#define MPT_TYPE_IOAPIC 2
-#define MPT_TYPE_INTSRC 3
-#define MPT_TYPE_LOCAL_INT 4
-
-struct mpt_cpu {
-    u8 type;
-    u8 apicid;
-    u8 apicver;
-    u8 cpuflag;
-    u32 cpusignature;
-    u32 featureflag;
-    u32 reserved[2];
-} PACKED;
-
-struct mpt_bus {
-    u8 type;
-    u8 busid;
-    char bustype[6];
-} PACKED;
-
-struct mpt_ioapic {
-    u8 type;
-    u8 apicid;
-    u8 apicver;
-    u8 flags;
-    u32 apicaddr;
-} PACKED;
-
-struct mpt_intsrc {
-    u8 type;
-    u8 irqtype;
-    u16 irqflag;
-    u8 srcbus;
-    u8 srcbusirq;
-    u8 dstapic;
-    u8 dstirq;
-} PACKED;
-
-// mptable.c
-void mptable_setup(void);
-
-#endif // mptable.h
diff --git a/src/mtrr.c b/src/mtrr.c
deleted file mode 100644 (file)
index 001e275..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-// Initialize MTRRs - mostly useful on KVM.
-//
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "util.h" // dprintf
-#include "config.h" // CONFIG_*
-#include "hw/pci.h" // pcimem_start
-#include "paravirt.h" // RamSize
-
-#define MSR_MTRRcap                    0x000000fe
-#define MSR_MTRRfix64K_00000           0x00000250
-#define MSR_MTRRfix16K_80000           0x00000258
-#define MSR_MTRRfix16K_A0000           0x00000259
-#define MSR_MTRRfix4K_C0000            0x00000268
-#define MSR_MTRRfix4K_C8000            0x00000269
-#define MSR_MTRRfix4K_D0000            0x0000026a
-#define MSR_MTRRfix4K_D8000            0x0000026b
-#define MSR_MTRRfix4K_E0000            0x0000026c
-#define MSR_MTRRfix4K_E8000            0x0000026d
-#define MSR_MTRRfix4K_F0000            0x0000026e
-#define MSR_MTRRfix4K_F8000            0x0000026f
-#define MSR_MTRRdefType                0x000002ff
-
-#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
-#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
-
-#define MTRR_MEMTYPE_UC 0
-#define MTRR_MEMTYPE_WC 1
-#define MTRR_MEMTYPE_WT 4
-#define MTRR_MEMTYPE_WP 5
-#define MTRR_MEMTYPE_WB 6
-
-void mtrr_setup(void)
-{
-    if (!CONFIG_MTRR_INIT)
-        return;
-
-    u32 eax, ebx, ecx, edx, cpuid_features;
-    cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
-    if (!(cpuid_features & CPUID_MTRR))
-        return;
-    if (!(cpuid_features & CPUID_MSR))
-        return;
-
-    dprintf(3, "init mtrr\n");
-
-    u32 mtrr_cap = rdmsr(MSR_MTRRcap);
-    int vcnt = mtrr_cap & 0xff;
-    int fix = mtrr_cap & 0x100;
-    if (!vcnt || !fix)
-       return;
-
-    // Disable MTRRs
-    wrmsr_smp(MSR_MTRRdefType, 0);
-
-    // Set fixed MTRRs
-    union u64b {
-        u8 valb[8];
-        u64 val;
-    } u;
-    u.val = 0;
-    int i;
-    for (i = 0; i < 8; i++)
-        if (RamSize >= 65536 * (i + 1))
-            u.valb[i] = MTRR_MEMTYPE_WB;
-    wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
-    u.val = 0;
-    for (i = 0; i < 8; i++)
-        if (RamSize >= 0x80000 + 16384 * (i + 1))
-            u.valb[i] = MTRR_MEMTYPE_WB;
-    wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
-    wrmsr_smp(MSR_MTRRfix16K_A0000, 0);   // 0xA0000-0xC0000 is uncached
-    int j;
-    for (j = 0; j < 8; j++) {
-        u.val = 0;
-        for (i = 0; i < 8; i++)
-            if (RamSize >= 0xC0000 + j * 0x8000 + 4096 * (i + 1))
-                u.valb[i] = MTRR_MEMTYPE_WP;
-        wrmsr_smp(MSR_MTRRfix4K_C0000 + j, u.val);
-    }
-
-    // Set variable MTRRs
-    int phys_bits = 36;
-    cpuid(0x80000000u, &eax, &ebx, &ecx, &edx);
-    if (eax >= 0x80000008) {
-        /* Get physical bits from leaf 0x80000008 (if available) */
-        cpuid(0x80000008u, &eax, &ebx, &ecx, &edx);
-        phys_bits = eax & 0xff;
-    }
-    u64 phys_mask = ((1ull << phys_bits) - 1);
-    for (i=0; i<vcnt; i++) {
-        wrmsr_smp(MTRRphysBase_MSR(i), 0);
-        wrmsr_smp(MTRRphysMask_MSR(i), 0);
-    }
-    /* Mark 3.5-4GB as UC, anything not specified defaults to WB */
-    wrmsr_smp(MTRRphysBase_MSR(0), pcimem_start | MTRR_MEMTYPE_UC);
-    wrmsr_smp(MTRRphysMask_MSR(0)
-              , (-((1ull<<32)-pcimem_start) & phys_mask) | 0x800);
-
-    // Enable fixed and variable MTRRs; set default type.
-    wrmsr_smp(MSR_MTRRdefType, 0xc00 | MTRR_MEMTYPE_WB);
-}
index fb2dd76c9a57cfe12fb53e6de02084215f47721d..8b63d9abcf392ba5e3273ff09337ef7a69dc3df5 100644 (file)
@@ -11,7 +11,7 @@
 #include "bregs.h" // struct bregs
 #include "config.h" // CONFIG_*
 #include "biosvar.h" // GET_GLOBAL
-#include "paravirt.h" // PlatformRunningOn
+#include "fw/paravirt.h" // PlatformRunningOn
 
 struct putcinfo {
     void (*func)(struct putcinfo *info, char c);
diff --git a/src/paravirt.c b/src/paravirt.c
deleted file mode 100644 (file)
index b1dd8b0..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-// Paravirtualization support.
-//
-// Copyright (C) 2013  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2009 Red Hat Inc.
-//
-// Authors:
-//  Gleb Natapov <gnatapov@redhat.com>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "config.h" // CONFIG_QEMU
-#include "util.h" // dprintf
-#include "byteorder.h" // be32_to_cpu
-#include "ioport.h" // outw
-#include "paravirt.h" // qemu_cfg_preinit
-#include "smbios.h" // smbios_setup
-#include "memmap.h" // add_e820
-#include "hw/cmos.h" // CMOS_*
-#include "acpi.h" // acpi_setup
-#include "mptable.h" // mptable_setup
-#include "hw/pci.h" // create_pirtable
-#include "xen.h" // xen_biostable_setup
-
-// Amount of continuous ram under 4Gig
-u32 RamSize;
-// Amount of continuous ram >4Gig
-u64 RamSizeOver4G;
-// Type of emulator platform.
-int PlatformRunningOn VARFSEG;
-
-/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
- * should be used to determine that a VM is running under KVM.
- */
-#define KVM_CPUID_SIGNATURE     0x40000000
-
-static void kvm_preinit(void)
-{
-    if (!CONFIG_QEMU)
-        return;
-    unsigned int eax, ebx, ecx, edx;
-    char signature[13];
-
-    cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
-    memcpy(signature + 0, &ebx, 4);
-    memcpy(signature + 4, &ecx, 4);
-    memcpy(signature + 8, &edx, 4);
-    signature[12] = 0;
-
-    if (strcmp(signature, "KVMKVMKVM") == 0) {
-        dprintf(1, "Running on KVM\n");
-        PlatformRunningOn |= PF_KVM;
-    }
-}
-
-void
-qemu_preinit(void)
-{
-    if (!CONFIG_QEMU)
-        return;
-
-    if (runningOnXen()) {
-        xen_ramsize_preinit();
-        return;
-    }
-
-    PlatformRunningOn = PF_QEMU;
-    kvm_preinit();
-
-    // On emulators, get memory size from nvram.
-    u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16)
-              | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24));
-    if (rs)
-        rs += 16 * 1024 * 1024;
-    else
-        rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10)
-               | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18))
-              + 1 * 1024 * 1024);
-    RamSize = rs;
-    add_e820(0, rs, E820_RAM);
-
-    // Check for memory over 4Gig
-    u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16)
-                | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24)
-                | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32));
-    RamSizeOver4G = high;
-    add_e820(0x100000000ull, high, E820_RAM);
-
-    /* reserve 256KB BIOS area at the end of 4 GB */
-    add_e820(0xfffc0000, 256*1024, E820_RESERVED);
-
-    dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G);
-}
-
-void
-qemu_platform_setup(void)
-{
-    if (!CONFIG_QEMU)
-        return;
-
-    if (runningOnXen()) {
-        pci_probe_devices();
-        xen_hypercall_setup();
-        xen_biostable_setup();
-        return;
-    }
-
-    // Initialize pci
-    pci_setup();
-    smm_device_setup();
-    smm_setup();
-
-    // Initialize mtrr and smp
-    mtrr_setup();
-    smp_setup();
-
-    // Create bios tables
-    pirtable_setup();
-    mptable_setup();
-    smbios_setup();
-    acpi_setup();
-}
-
-
-/****************************************************************
- * QEMU firmware config (fw_cfg) interface
- ****************************************************************/
-
-// List of QEMU fw_cfg entries.  DO NOT ADD MORE.  (All new content
-// should be passed via the fw_cfg "file" interface.)
-#define QEMU_CFG_SIGNATURE              0x00
-#define QEMU_CFG_ID                     0x01
-#define QEMU_CFG_UUID                   0x02
-#define QEMU_CFG_NUMA                   0x0d
-#define QEMU_CFG_BOOT_MENU              0x0e
-#define QEMU_CFG_MAX_CPUS               0x0f
-#define QEMU_CFG_FILE_DIR               0x19
-#define QEMU_CFG_ARCH_LOCAL             0x8000
-#define QEMU_CFG_ACPI_TABLES            (QEMU_CFG_ARCH_LOCAL + 0)
-#define QEMU_CFG_SMBIOS_ENTRIES         (QEMU_CFG_ARCH_LOCAL + 1)
-#define QEMU_CFG_IRQ0_OVERRIDE          (QEMU_CFG_ARCH_LOCAL + 2)
-#define QEMU_CFG_E820_TABLE             (QEMU_CFG_ARCH_LOCAL + 3)
-
-static void
-qemu_cfg_select(u16 f)
-{
-    outw(f, PORT_QEMU_CFG_CTL);
-}
-
-static void
-qemu_cfg_read(void *buf, int len)
-{
-    insb(PORT_QEMU_CFG_DATA, buf, len);
-}
-
-static void
-qemu_cfg_skip(int len)
-{
-    while (len--)
-        inb(PORT_QEMU_CFG_DATA);
-}
-
-static void
-qemu_cfg_read_entry(void *buf, int e, int len)
-{
-    qemu_cfg_select(e);
-    qemu_cfg_read(buf, len);
-}
-
-struct qemu_romfile_s {
-    struct romfile_s file;
-    int select, skip;
-};
-
-static int
-qemu_cfg_read_file(struct romfile_s *file, void *dst, u32 maxlen)
-{
-    if (file->size > maxlen)
-        return -1;
-    struct qemu_romfile_s *qfile;
-    qfile = container_of(file, struct qemu_romfile_s, file);
-    qemu_cfg_select(qfile->select);
-    qemu_cfg_skip(qfile->skip);
-    qemu_cfg_read(dst, file->size);
-    return file->size;
-}
-
-static void
-qemu_romfile_add(char *name, int select, int skip, int size)
-{
-    struct qemu_romfile_s *qfile = malloc_tmp(sizeof(*qfile));
-    if (!qfile) {
-        warn_noalloc();
-        return;
-    }
-    memset(qfile, 0, sizeof(*qfile));
-    strtcpy(qfile->file.name, name, sizeof(qfile->file.name));
-    qfile->file.size = size;
-    qfile->select = select;
-    qfile->skip = skip;
-    qfile->file.copy = qemu_cfg_read_file;
-    romfile_add(&qfile->file);
-}
-
-struct e820_reservation {
-    u64 address;
-    u64 length;
-    u32 type;
-};
-
-#define SMBIOS_FIELD_ENTRY 0
-#define SMBIOS_TABLE_ENTRY 1
-
-struct qemu_smbios_header {
-    u16 length;
-    u8 headertype;
-    u8 tabletype;
-    u16 fieldoffset;
-} PACKED;
-
-// Populate romfile entries for legacy fw_cfg ports (that predate the
-// "file" interface).
-static void
-qemu_cfg_legacy(void)
-{
-    if (!CONFIG_QEMU)
-        return;
-
-    // Misc config items.
-    qemu_romfile_add("etc/show-boot-menu", QEMU_CFG_BOOT_MENU, 0, 2);
-    qemu_romfile_add("etc/irq0-override", QEMU_CFG_IRQ0_OVERRIDE, 0, 1);
-    qemu_romfile_add("etc/max-cpus", QEMU_CFG_MAX_CPUS, 0, 2);
-
-    // NUMA data
-    u64 numacount;
-    qemu_cfg_read_entry(&numacount, QEMU_CFG_NUMA, sizeof(numacount));
-    int max_cpu = romfile_loadint("etc/max-cpus", 0);
-    qemu_romfile_add("etc/numa-cpu-map", QEMU_CFG_NUMA, sizeof(numacount)
-                     , max_cpu*sizeof(u64));
-    qemu_romfile_add("etc/numa-nodes", QEMU_CFG_NUMA
-                     , sizeof(numacount) + max_cpu*sizeof(u64)
-                     , numacount*sizeof(u64));
-
-    // e820 data
-    u32 count32;
-    qemu_cfg_read_entry(&count32, QEMU_CFG_E820_TABLE, sizeof(count32));
-    if (count32) {
-        struct e820_reservation entry;
-        int i;
-        for (i = 0; i < count32; i++) {
-            qemu_cfg_read(&entry, sizeof(entry));
-            add_e820(entry.address, entry.length, entry.type);
-        }
-    } else if (runningOnKVM()) {
-        // Backwards compatibility - provide hard coded range.
-        // 4 pages before the bios, 3 pages for vmx tss pages, the
-        // other page for EPT real mode pagetable
-        add_e820(0xfffbc000, 4*4096, E820_RESERVED);
-    }
-
-    // ACPI tables
-    char name[128];
-    u16 cnt;
-    qemu_cfg_read_entry(&cnt, QEMU_CFG_ACPI_TABLES, sizeof(cnt));
-    int i, offset = sizeof(cnt);
-    for (i = 0; i < cnt; i++) {
-        u16 len;
-        qemu_cfg_read(&len, sizeof(len));
-        offset += sizeof(len);
-        snprintf(name, sizeof(name), "acpi/table%d", i);
-        qemu_romfile_add(name, QEMU_CFG_ACPI_TABLES, offset, len);
-        qemu_cfg_skip(len);
-        offset += len;
-    }
-
-    // SMBIOS info
-    qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt));
-    offset = sizeof(cnt);
-    for (i = 0; i < cnt; i++) {
-        struct qemu_smbios_header header;
-        qemu_cfg_read(&header, sizeof(header));
-        if (header.headertype == SMBIOS_FIELD_ENTRY) {
-            snprintf(name, sizeof(name), "smbios/field%d-%d"
-                     , header.tabletype, header.fieldoffset);
-            qemu_romfile_add(name, QEMU_CFG_SMBIOS_ENTRIES
-                             , offset + sizeof(header)
-                             , header.length - sizeof(header));
-        } else {
-            snprintf(name, sizeof(name), "smbios/table%d-%d"
-                     , header.tabletype, i);
-            qemu_romfile_add(name, QEMU_CFG_SMBIOS_ENTRIES
-                             , offset + 3, header.length - 3);
-        }
-        qemu_cfg_skip(header.length - sizeof(header));
-        offset += header.length;
-    }
-}
-
-struct QemuCfgFile {
-    u32  size;        /* file size */
-    u16  select;      /* write this to 0x510 to read it */
-    u16  reserved;
-    char name[56];
-};
-
-void qemu_cfg_init(void)
-{
-    if (!runningOnQEMU())
-        return;
-
-    // Detect fw_cfg interface.
-    qemu_cfg_select(QEMU_CFG_SIGNATURE);
-    char *sig = "QEMU";
-    int i;
-    for (i = 0; i < 4; i++)
-        if (inb(PORT_QEMU_CFG_DATA) != sig[i])
-            return;
-    dprintf(1, "Found QEMU fw_cfg\n");
-
-    // Populate romfiles for legacy fw_cfg entries
-    qemu_cfg_legacy();
-
-    // Load files found in the fw_cfg file directory
-    u32 count;
-    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
-    count = be32_to_cpu(count);
-    u32 e;
-    for (e = 0; e < count; e++) {
-        struct QemuCfgFile qfile;
-        qemu_cfg_read(&qfile, sizeof(qfile));
-        qemu_romfile_add(qfile.name, be16_to_cpu(qfile.select)
-                         , 0, be32_to_cpu(qfile.size));
-    }
-}
diff --git a/src/paravirt.h b/src/paravirt.h
deleted file mode 100644 (file)
index fce5af9..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __PV_H
-#define __PV_H
-
-#include "config.h" // CONFIG_*
-#include "biosvar.h" // GET_GLOBAL
-
-// Types of paravirtualized platforms.
-#define PF_QEMU     (1<<0)
-#define PF_XEN      (1<<1)
-#define PF_KVM      (1<<2)
-
-extern u32 RamSize;
-extern u64 RamSizeOver4G;
-extern int PlatformRunningOn;
-
-static inline int runningOnQEMU(void) {
-    return CONFIG_QEMU || (
-        CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU);
-}
-static inline int runningOnXen(void) {
-    return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN;
-}
-static inline int runningOnKVM(void) {
-    return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM;
-}
-
-void qemu_preinit(void);
-void qemu_platform_setup(void);
-void qemu_cfg_init(void);
-
-#endif
diff --git a/src/pciinit.c b/src/pciinit.c
deleted file mode 100644 (file)
index ca32d43..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-// Initialize PCI devices (on emulators)
-//
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "util.h" // dprintf
-#include "hw/pci.h" // pci_config_readl
-#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
-#include "hw/pci_regs.h" // PCI_COMMAND
-#include "ioport.h" // PORT_ATA1_CMD_BASE
-#include "config.h" // CONFIG_*
-#include "memmap.h" // add_e820
-#include "paravirt.h" // RamSize
-#include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR
-#include "list.h" // struct hlist_node
-#include "acpi.h" // acpi_pm1a_cnt
-
-#define PCI_DEVICE_MEM_MIN     0x1000
-#define PCI_BRIDGE_IO_MIN      0x1000
-#define PCI_BRIDGE_MEM_MIN   0x100000
-
-enum pci_region_type {
-    PCI_REGION_TYPE_IO,
-    PCI_REGION_TYPE_MEM,
-    PCI_REGION_TYPE_PREFMEM,
-    PCI_REGION_TYPE_COUNT,
-};
-
-static const char *region_type_name[] = {
-    [ PCI_REGION_TYPE_IO ]      = "io",
-    [ PCI_REGION_TYPE_MEM ]     = "mem",
-    [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
-};
-
-u64 pcimem_start   = BUILD_PCIMEM_START;
-u64 pcimem_end     = BUILD_PCIMEM_END;
-u64 pcimem64_start = BUILD_PCIMEM64_START;
-u64 pcimem64_end   = BUILD_PCIMEM64_END;
-
-struct pci_region_entry {
-    struct pci_device *dev;
-    int bar;
-    u64 size;
-    u64 align;
-    int is64;
-    enum pci_region_type type;
-    struct hlist_node node;
-};
-
-struct pci_region {
-    /* pci region assignments */
-    u64 base;
-    struct hlist_head list;
-};
-
-struct pci_bus {
-    struct pci_region r[PCI_REGION_TYPE_COUNT];
-    struct pci_device *bus_dev;
-};
-
-static u32 pci_bar(struct pci_device *pci, int region_num)
-{
-    if (region_num != PCI_ROM_SLOT) {
-        return PCI_BASE_ADDRESS_0 + region_num * 4;
-    }
-
-#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
-    u8 type = pci->header_type & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
-    return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS;
-}
-
-static void
-pci_set_io_region_addr(struct pci_device *pci, int bar, u64 addr, int is64)
-{
-    u32 ofs = pci_bar(pci, bar);
-    pci_config_writel(pci->bdf, ofs, addr);
-    if (is64)
-        pci_config_writel(pci->bdf, ofs + 4, addr >> 32);
-}
-
-
-/****************************************************************
- * Misc. device init
- ****************************************************************/
-
-/* host irqs corresponding to PCI irqs A-D */
-const u8 pci_irqs[4] = {
-    10, 10, 11, 11
-};
-
-static int dummy_pci_slot_get_irq(struct pci_device *pci, int pin)
-{
-    dprintf(1, "pci_slot_get_irq called with unknown routing\n");
-
-    return 0xff; /* PCI defined "unknown" or "no connection" for x86 */
-}
-
-static int (*pci_slot_get_irq)(struct pci_device *pci, int pin) =
-    dummy_pci_slot_get_irq;
-
-// Return the global irq number corresponding to a host bus device irq pin.
-static int piix_pci_slot_get_irq(struct pci_device *pci, int pin)
-{
-    int slot_addend = 0;
-
-    while (pci->parent != NULL) {
-        slot_addend += pci_bdf_to_dev(pci->bdf);
-        pci = pci->parent;
-    }
-    slot_addend += pci_bdf_to_dev(pci->bdf) - 1;
-    return pci_irqs[(pin - 1 + slot_addend) & 3];
-}
-
-static int mch_pci_slot_get_irq(struct pci_device *pci, int pin)
-{
-    int irq, slot, pin_addend = 0;
-
-    while (pci->parent != NULL) {
-        pin_addend += pci_bdf_to_dev(pci->bdf);
-        pci = pci->parent;
-    }
-    slot = pci_bdf_to_dev(pci->bdf);
-
-    switch (slot) {
-    /* Slots 0-24 rotate slot:pin mapping similar to piix above, but
-       with a different starting index - see q35-acpi-dsdt.dsl */
-    case 0 ... 24:
-        irq = pci_irqs[(pin - 1 + pin_addend + slot) & 3];
-        break;
-    /* Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H) */
-    case 25 ... 31:
-        irq = pci_irqs[(pin - 1 + pin_addend) & 3];
-        break;
-    }
-
-    return irq;
-}
-
-/* PIIX3/PIIX4 PCI to ISA bridge */
-static void piix_isa_bridge_setup(struct pci_device *pci, void *arg)
-{
-    int i, irq;
-    u8 elcr[2];
-
-    elcr[0] = 0x00;
-    elcr[1] = 0x00;
-    for (i = 0; i < 4; i++) {
-        irq = pci_irqs[i];
-        /* set to trigger level */
-        elcr[irq >> 3] |= (1 << (irq & 7));
-        /* activate irq remapping in PIIX */
-        pci_config_writeb(pci->bdf, 0x60 + i, irq);
-    }
-    outb(elcr[0], 0x4d0);
-    outb(elcr[1], 0x4d1);
-    dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
-}
-
-/* ICH9 LPC PCI to ISA bridge */
-/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
-void mch_isa_bridge_setup(struct pci_device *dev, void *arg)
-{
-    u16 bdf = dev->bdf;
-    int i, irq;
-    u8 elcr[2];
-
-    elcr[0] = 0x00;
-    elcr[1] = 0x00;
-
-    for (i = 0; i < 4; i++) {
-        irq = pci_irqs[i];
-        /* set to trigger level */
-        elcr[irq >> 3] |= (1 << (irq & 7));
-
-        /* activate irq remapping in LPC */
-
-        /* PIRQ[A-D] routing */
-        pci_config_writeb(bdf, ICH9_LPC_PIRQA_ROUT + i, irq);
-        /* PIRQ[E-H] routing */
-        pci_config_writeb(bdf, ICH9_LPC_PIRQE_ROUT + i, irq);
-    }
-    outb(elcr[0], ICH9_LPC_PORT_ELCR1);
-    outb(elcr[1], ICH9_LPC_PORT_ELCR2);
-    dprintf(1, "Q35 LPC init: elcr=%02x %02x\n", elcr[0], elcr[1]);
-
-    /* pm io base */
-    pci_config_writel(bdf, ICH9_LPC_PMBASE,
-                      PORT_ACPI_PM_BASE | ICH9_LPC_PMBASE_RTE);
-
-    /* acpi enable, SCI: IRQ9 000b = irq9*/
-    pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
-
-    acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04;
-    pmtimer_setup(PORT_ACPI_PM_BASE + 0x08);
-}
-
-static void storage_ide_setup(struct pci_device *pci, void *arg)
-{
-    /* IDE: we map it as in ISA mode */
-    pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE, 0);
-    pci_set_io_region_addr(pci, 1, PORT_ATA1_CTRL_BASE, 0);
-    pci_set_io_region_addr(pci, 2, PORT_ATA2_CMD_BASE, 0);
-    pci_set_io_region_addr(pci, 3, PORT_ATA2_CTRL_BASE, 0);
-}
-
-/* PIIX3/PIIX4 IDE */
-static void piix_ide_setup(struct pci_device *pci, void *arg)
-{
-    u16 bdf = pci->bdf;
-    pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0
-    pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1
-}
-
-static void pic_ibm_setup(struct pci_device *pci, void *arg)
-{
-    /* PIC, IBM, MPIC & MPIC2 */
-    pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000, 0);
-}
-
-static void apple_macio_setup(struct pci_device *pci, void *arg)
-{
-    /* macio bridge */
-    pci_set_io_region_addr(pci, 0, 0x80800000, 0);
-}
-
-/* PIIX4 Power Management device (for ACPI) */
-static void piix4_pm_setup(struct pci_device *pci, void *arg)
-{
-    u16 bdf = pci->bdf;
-    // acpi sci is hardwired to 9
-    pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
-
-    pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1);
-    pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
-    pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
-    pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
-
-    acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04;
-    pmtimer_setup(PORT_ACPI_PM_BASE + 0x08);
-}
-
-/* ICH9 SMBUS */
-/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */
-void ich9_smbus_setup(struct pci_device *dev, void *arg)
-{
-    u16 bdf = dev->bdf;
-    /* map smbus into io space */
-    pci_config_writel(bdf, ICH9_SMB_SMB_BASE,
-                      PORT_SMB_BASE | PCI_BASE_ADDRESS_SPACE_IO);
-
-    /* enable SMBus */
-    pci_config_writeb(bdf, ICH9_SMB_HOSTC, ICH9_SMB_HOSTC_HST_EN);
-}
-
-static const struct pci_device_id pci_device_tbl[] = {
-    /* PIIX3/PIIX4 PCI to ISA bridge */
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0,
-               piix_isa_bridge_setup),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
-               piix_isa_bridge_setup),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
-               mch_isa_bridge_setup),
-
-    /* STORAGE IDE */
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1,
-                     PCI_CLASS_STORAGE_IDE, piix_ide_setup),
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
-                     PCI_CLASS_STORAGE_IDE, piix_ide_setup),
-    PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
-                     storage_ide_setup),
-
-    /* PIC, IBM, MIPC & MPIC2 */
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC,
-                     pic_ibm_setup),
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC,
-                     pic_ibm_setup),
-
-    /* PIIX4 Power Management device (for ACPI) */
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
-               piix4_pm_setup),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_SMBUS,
-               ich9_smbus_setup),
-
-    /* 0xff00 */
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_setup),
-    PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_setup),
-
-    PCI_DEVICE_END,
-};
-
-static void pci_bios_init_device(struct pci_device *pci)
-{
-    u16 bdf = pci->bdf;
-    dprintf(1, "PCI: init bdf=%02x:%02x.%x id=%04x:%04x\n"
-            , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)
-            , pci->vendor, pci->device);
-
-    /* map the interrupt */
-    int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
-    if (pin != 0)
-        pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pci, pin));
-
-    pci_init_device(pci_device_tbl, pci, NULL);
-
-    /* enable memory mappings */
-    pci_config_maskw(bdf, PCI_COMMAND, 0,
-                     PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR);
-}
-
-static void pci_bios_init_devices(void)
-{
-    struct pci_device *pci;
-    foreachpci(pci) {
-        pci_bios_init_device(pci);
-    }
-}
-
-static void pci_enable_default_vga(void)
-{
-    struct pci_device *pci;
-
-    foreachpci(pci) {
-        if (is_pci_vga(pci)) {
-            dprintf(1, "PCI: Using %02x:%02x.%x for primary VGA\n",
-                    pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
-                    pci_bdf_to_fn(pci->bdf));
-            return;
-        }
-    }
-
-    pci = pci_find_class(PCI_CLASS_DISPLAY_VGA);
-    if (!pci) {
-        dprintf(1, "PCI: No VGA devices found\n");
-        return;
-    }
-
-    dprintf(1, "PCI: Enabling %02x:%02x.%x for primary VGA\n",
-            pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
-            pci_bdf_to_fn(pci->bdf));
-
-    pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
-                     PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-
-    while (pci->parent) {
-        pci = pci->parent;
-
-        dprintf(1, "PCI: Setting VGA enable on bridge %02x:%02x.%x\n",
-                pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
-                pci_bdf_to_fn(pci->bdf));
-
-        pci_config_maskw(pci->bdf, PCI_BRIDGE_CONTROL, 0, PCI_BRIDGE_CTL_VGA);
-        pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
-                         PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-    }
-}
-
-/****************************************************************
- * Platform device initialization
- ****************************************************************/
-
-void i440fx_mem_addr_setup(struct pci_device *dev, void *arg)
-{
-    if (RamSize <= 0x80000000)
-        pcimem_start = 0x80000000;
-    else if (RamSize <= 0xc0000000)
-        pcimem_start = 0xc0000000;
-
-    pci_slot_get_irq = piix_pci_slot_get_irq;
-}
-
-void mch_mem_addr_setup(struct pci_device *dev, void *arg)
-{
-    u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
-    u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
-
-    /* setup mmconfig */
-    u16 bdf = dev->bdf;
-    u32 upper = addr >> 32;
-    u32 lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
-    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0);
-    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
-    pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);
-    add_e820(addr, size, E820_RESERVED);
-
-    /* setup pci i/o window (above mmconfig) */
-    pcimem_start = addr + size;
-
-    pci_slot_get_irq = mch_pci_slot_get_irq;
-}
-
-static const struct pci_device_id pci_platform_tbl[] = {
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
-               i440fx_mem_addr_setup),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH,
-               mch_mem_addr_setup),
-    PCI_DEVICE_END
-};
-
-static void pci_bios_init_platform(void)
-{
-    struct pci_device *pci;
-    foreachpci(pci) {
-        pci_init_device(pci_platform_tbl, pci, NULL);
-    }
-}
-
-
-/****************************************************************
- * Bus initialization
- ****************************************************************/
-
-static void
-pci_bios_init_bus_rec(int bus, u8 *pci_bus)
-{
-    int bdf;
-    u16 class;
-
-    dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus);
-
-    /* prevent accidental access to unintended devices */
-    foreachbdf(bdf, bus) {
-        class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
-        if (class == PCI_CLASS_BRIDGE_PCI) {
-            pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255);
-            pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0);
-        }
-    }
-
-    foreachbdf(bdf, bus) {
-        class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
-        if (class != PCI_CLASS_BRIDGE_PCI) {
-            continue;
-        }
-        dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf);
-
-        u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS);
-        if (pribus != bus) {
-            dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus);
-            pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus);
-        } else {
-            dprintf(1, "PCI: primary bus = 0x%x\n", pribus);
-        }
-
-        u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS);
-        (*pci_bus)++;
-        if (*pci_bus != secbus) {
-            dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n",
-                    secbus, *pci_bus);
-            secbus = *pci_bus;
-            pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus);
-        } else {
-            dprintf(1, "PCI: secondary bus = 0x%x\n", secbus);
-        }
-
-        /* set to max for access to all subordinate buses.
-           later set it to accurate value */
-        u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS);
-        pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255);
-
-        pci_bios_init_bus_rec(secbus, pci_bus);
-
-        if (subbus != *pci_bus) {
-            dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n",
-                    subbus, *pci_bus);
-            subbus = *pci_bus;
-        } else {
-            dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus);
-        }
-        pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus);
-    }
-}
-
-static void
-pci_bios_init_bus(void)
-{
-    u8 pci_bus = 0;
-    pci_bios_init_bus_rec(0 /* host bus */, &pci_bus);
-}
-
-
-/****************************************************************
- * Bus sizing
- ****************************************************************/
-
-static void
-pci_bios_get_bar(struct pci_device *pci, int bar,
-                 int *ptype, u64 *psize, int *pis64)
-{
-    u32 ofs = pci_bar(pci, bar);
-    u16 bdf = pci->bdf;
-    u32 old = pci_config_readl(bdf, ofs);
-    int is64 = 0, type = PCI_REGION_TYPE_MEM;
-    u64 mask;
-
-    if (bar == PCI_ROM_SLOT) {
-        mask = PCI_ROM_ADDRESS_MASK;
-        pci_config_writel(bdf, ofs, mask);
-    } else {
-        if (old & PCI_BASE_ADDRESS_SPACE_IO) {
-            mask = PCI_BASE_ADDRESS_IO_MASK;
-            type = PCI_REGION_TYPE_IO;
-        } else {
-            mask = PCI_BASE_ADDRESS_MEM_MASK;
-            if (old & PCI_BASE_ADDRESS_MEM_PREFETCH)
-                type = PCI_REGION_TYPE_PREFMEM;
-            is64 = ((old & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
-                    == PCI_BASE_ADDRESS_MEM_TYPE_64);
-        }
-        pci_config_writel(bdf, ofs, ~0);
-    }
-    u64 val = pci_config_readl(bdf, ofs);
-    pci_config_writel(bdf, ofs, old);
-    if (is64) {
-        u32 hold = pci_config_readl(bdf, ofs + 4);
-        pci_config_writel(bdf, ofs + 4, ~0);
-        u32 high = pci_config_readl(bdf, ofs + 4);
-        pci_config_writel(bdf, ofs + 4, hold);
-        val |= ((u64)high << 32);
-        mask |= ((u64)0xffffffff << 32);
-        *psize = (~(val & mask)) + 1;
-    } else {
-        *psize = ((~(val & mask)) + 1) & 0xffffffff;
-    }
-    *ptype = type;
-    *pis64 = is64;
-}
-
-static int pci_bios_bridge_region_is64(struct pci_region *r,
-                                 struct pci_device *pci, int type)
-{
-    if (type != PCI_REGION_TYPE_PREFMEM)
-        return 0;
-    u32 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
-    if (!pmem) {
-        pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0);
-        pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
-        pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0);
-    }
-    if ((pmem & PCI_PREF_RANGE_TYPE_MASK) != PCI_PREF_RANGE_TYPE_64)
-       return 0;
-    struct pci_region_entry *entry;
-    hlist_for_each_entry(entry, &r->list, node) {
-        if (!entry->is64)
-            return 0;
-    }
-    return 1;
-}
-
-static u64 pci_region_align(struct pci_region *r)
-{
-    struct pci_region_entry *entry;
-    hlist_for_each_entry(entry, &r->list, node) {
-        // The first entry in the sorted list has the largest alignment
-        return entry->align;
-    }
-    return 1;
-}
-
-static u64 pci_region_sum(struct pci_region *r)
-{
-    u64 sum = 0;
-    struct pci_region_entry *entry;
-    hlist_for_each_entry(entry, &r->list, node) {
-        sum += entry->size;
-    }
-    return sum;
-}
-
-static void pci_region_migrate_64bit_entries(struct pci_region *from,
-                                             struct pci_region *to)
-{
-    struct hlist_node *n, **last = &to->list.first;
-    struct pci_region_entry *entry;
-    hlist_for_each_entry_safe(entry, n, &from->list, node) {
-        if (!entry->is64)
-            continue;
-        // Move from source list to destination list.
-        hlist_del(&entry->node);
-        hlist_add(&entry->node, last);
-    }
-}
-
-static struct pci_region_entry *
-pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
-                        int bar, u64 size, u64 align, int type, int is64)
-{
-    struct pci_region_entry *entry = malloc_tmp(sizeof(*entry));
-    if (!entry) {
-        warn_noalloc();
-        return NULL;
-    }
-    memset(entry, 0, sizeof(*entry));
-    entry->dev = dev;
-    entry->bar = bar;
-    entry->size = size;
-    entry->align = align;
-    entry->is64 = is64;
-    entry->type = type;
-    // Insert into list in sorted order.
-    struct hlist_node **pprev;
-    struct pci_region_entry *pos;
-    hlist_for_each_entry_pprev(pos, pprev, &bus->r[type].list, node) {
-        if (pos->align < align || (pos->align == align && pos->size < size))
-            break;
-    }
-    hlist_add(&entry->node, pprev);
-    return entry;
-}
-
-static int pci_bios_check_devices(struct pci_bus *busses)
-{
-    dprintf(1, "PCI: check devices\n");
-
-    // Calculate resources needed for regular (non-bus) devices.
-    struct pci_device *pci;
-    foreachpci(pci) {
-        if (pci->class == PCI_CLASS_BRIDGE_PCI)
-            busses[pci->secondary_bus].bus_dev = pci;
-
-        struct pci_bus *bus = &busses[pci_bdf_to_bus(pci->bdf)];
-        int i;
-        for (i = 0; i < PCI_NUM_REGIONS; i++) {
-            if ((pci->class == PCI_CLASS_BRIDGE_PCI) &&
-                (i >= PCI_BRIDGE_NUM_REGIONS && i < PCI_ROM_SLOT))
-                continue;
-            int type, is64;
-            u64 size;
-            pci_bios_get_bar(pci, i, &type, &size, &is64);
-            if (size == 0)
-                continue;
-
-            if (type != PCI_REGION_TYPE_IO && size < PCI_DEVICE_MEM_MIN)
-                size = PCI_DEVICE_MEM_MIN;
-            struct pci_region_entry *entry = pci_region_create_entry(
-                bus, pci, i, size, size, type, is64);
-            if (!entry)
-                return -1;
-
-            if (is64)
-                i++;
-        }
-    }
-
-    // Propagate required bus resources to parent busses.
-    int secondary_bus;
-    for (secondary_bus=MaxPCIBus; secondary_bus>0; secondary_bus--) {
-        struct pci_bus *s = &busses[secondary_bus];
-        if (!s->bus_dev)
-            continue;
-        struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
-        int type;
-        for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
-            u64 align = (type == PCI_REGION_TYPE_IO) ?
-                PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
-            if (pci_region_align(&s->r[type]) > align)
-                 align = pci_region_align(&s->r[type]);
-            u64 sum = pci_region_sum(&s->r[type]);
-            u64 size = ALIGN(sum, align);
-            int is64 = pci_bios_bridge_region_is64(&s->r[type],
-                                            s->bus_dev, type);
-            // entry->bar is -1 if the entry represents a bridge region
-            struct pci_region_entry *entry = pci_region_create_entry(
-                parent, s->bus_dev, -1, size, align, type, is64);
-            if (!entry)
-                return -1;
-            dprintf(1, "PCI: secondary bus %d size %08llx type %s\n",
-                      entry->dev->secondary_bus, size,
-                      region_type_name[entry->type]);
-        }
-    }
-    return 0;
-}
-
-
-/****************************************************************
- * BAR assignment
- ****************************************************************/
-
-// Setup region bases (given the regions' size and alignment)
-static int pci_bios_init_root_regions(struct pci_bus *bus)
-{
-    bus->r[PCI_REGION_TYPE_IO].base = 0xc000;
-
-    struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM];
-    struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM];
-
-    if (pci_region_align(r_start) < pci_region_align(r_end)) {
-        // Swap regions to improve alignment.
-        r_end = r_start;
-        r_start = &bus->r[PCI_REGION_TYPE_PREFMEM];
-    }
-    u64 sum = pci_region_sum(r_end);
-    u64 align = pci_region_align(r_end);
-    r_end->base = ALIGN_DOWN((pcimem_end - sum), align);
-    sum = pci_region_sum(r_start);
-    align = pci_region_align(r_start);
-    r_start->base = ALIGN_DOWN((r_end->base - sum), align);
-
-    if ((r_start->base < pcimem_start) ||
-         (r_start->base > pcimem_end))
-        // Memory range requested is larger than available.
-        return -1;
-    return 0;
-}
-
-#define PCI_IO_SHIFT            8
-#define PCI_MEMORY_SHIFT        16
-#define PCI_PREF_MEMORY_SHIFT   16
-
-static void
-pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr)
-{
-    u16 bdf = entry->dev->bdf;
-    if (entry->bar >= 0) {
-        dprintf(1, "PCI: map device bdf=%02x:%02x.%x"
-                "  bar %d, addr %08llx, size %08llx [%s]\n",
-                pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
-                entry->bar, addr, entry->size, region_type_name[entry->type]);
-
-        pci_set_io_region_addr(entry->dev, entry->bar, addr, entry->is64);
-        return;
-    }
-
-    u64 limit = addr + entry->size - 1;
-    if (entry->type == PCI_REGION_TYPE_IO) {
-        pci_config_writeb(bdf, PCI_IO_BASE, addr >> PCI_IO_SHIFT);
-        pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
-        pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
-        pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
-    }
-    if (entry->type == PCI_REGION_TYPE_MEM) {
-        pci_config_writew(bdf, PCI_MEMORY_BASE, addr >> PCI_MEMORY_SHIFT);
-        pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
-    }
-    if (entry->type == PCI_REGION_TYPE_PREFMEM) {
-        pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, addr >> PCI_PREF_MEMORY_SHIFT);
-        pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
-        pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, addr >> 32);
-        pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, limit >> 32);
-    }
-}
-
-static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)
-{
-    struct hlist_node *n;
-    struct pci_region_entry *entry;
-    hlist_for_each_entry_safe(entry, n, &r->list, node) {
-        u64 addr = r->base;
-        r->base += entry->size;
-        if (entry->bar == -1)
-            // Update bus base address if entry is a bridge region
-            busses[entry->dev->secondary_bus].r[entry->type].base = addr;
-        pci_region_map_one_entry(entry, addr);
-        hlist_del(&entry->node);
-        free(entry);
-    }
-}
-
-static void pci_bios_map_devices(struct pci_bus *busses)
-{
-    if (pci_bios_init_root_regions(busses)) {
-        struct pci_region r64_mem, r64_pref;
-        r64_mem.list.first = NULL;
-        r64_pref.list.first = NULL;
-        pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_MEM],
-                                         &r64_mem);
-        pci_region_migrate_64bit_entries(&busses[0].r[PCI_REGION_TYPE_PREFMEM],
-                                         &r64_pref);
-
-        if (pci_bios_init_root_regions(busses))
-            panic("PCI: out of 32bit address space\n");
-
-        u64 sum_mem = pci_region_sum(&r64_mem);
-        u64 sum_pref = pci_region_sum(&r64_pref);
-        u64 align_mem = pci_region_align(&r64_mem);
-        u64 align_pref = pci_region_align(&r64_pref);
-
-        r64_mem.base = ALIGN(0x100000000LL + RamSizeOver4G, align_mem);
-        r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref);
-        pcimem64_start = r64_mem.base;
-        pcimem64_end = r64_pref.base + sum_pref;
-
-        pci_region_map_entries(busses, &r64_mem);
-        pci_region_map_entries(busses, &r64_pref);
-    } else {
-        // no bars mapped high -> drop 64bit window (see dsdt)
-        pcimem64_start = 0;
-    }
-    // Map regions on each device.
-    int bus;
-    for (bus = 0; bus<=MaxPCIBus; bus++) {
-        int type;
-        for (type = 0; type < PCI_REGION_TYPE_COUNT; type++)
-            pci_region_map_entries(busses, &busses[bus].r[type]);
-    }
-}
-
-
-/****************************************************************
- * Main setup code
- ****************************************************************/
-
-void
-pci_setup(void)
-{
-    if (!CONFIG_QEMU)
-        return;
-
-    dprintf(3, "pci setup\n");
-
-    dprintf(1, "=== PCI bus & bridge init ===\n");
-    if (pci_probe_host() != 0) {
-        return;
-    }
-    pci_bios_init_bus();
-
-    dprintf(1, "=== PCI device probing ===\n");
-    pci_probe_devices();
-
-    pcimem_start = RamSize;
-    pci_bios_init_platform();
-
-    dprintf(1, "=== PCI new allocation pass #1 ===\n");
-    struct pci_bus *busses = malloc_tmp(sizeof(*busses) * (MaxPCIBus + 1));
-    if (!busses) {
-        warn_noalloc();
-        return;
-    }
-    memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1));
-    if (pci_bios_check_devices(busses))
-        return;
-
-    dprintf(1, "=== PCI new allocation pass #2 ===\n");
-    pci_bios_map_devices(busses);
-
-    pci_bios_init_devices();
-
-    free(busses);
-
-    pci_enable_default_vga();
-}
diff --git a/src/pirtable.c b/src/pirtable.c
deleted file mode 100644 (file)
index 57fb48f..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// PIR table generation (for emulators)
-//
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2002  MandrakeSoft S.A.
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "hw/pci.h" // struct pir_header
-#include "config.h" // CONFIG_*
-#include "util.h" // checksum
-
-struct pir_header *PirAddr VARFSEG;
-
-struct pir_table {
-    struct pir_header pir;
-    struct pir_slot slots[6];
-} PACKED;
-
-extern struct pir_table PIR_TABLE;
-#if CONFIG_PIRTABLE
-struct pir_table PIR_TABLE __aligned(16) VARFSEG = {
-    .pir = {
-        .version = 0x0100,
-        .size = sizeof(struct pir_table),
-        .router_devfunc = 0x08,
-        .compatible_devid = 0x122e8086,
-    },
-    .slots = {
-        {
-            // first slot entry PCI-to-ISA (embedded)
-            .dev = 1<<3,
-            .links = {
-                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 0, // embedded
-        }, {
-            // second slot entry: 1st PCI slot
-            .dev = 2<<3,
-            .links = {
-                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 1,
-        }, {
-            // third slot entry: 2nd PCI slot
-            .dev = 3<<3,
-            .links = {
-                {.link = 0x62, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 2,
-        }, {
-            // 4th slot entry: 3rd PCI slot
-            .dev = 4<<3,
-            .links = {
-                {.link = 0x63, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 3,
-        }, {
-            // 5th slot entry: 4rd PCI slot
-            .dev = 5<<3,
-            .links = {
-                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 4,
-        }, {
-            // 6th slot entry: 5rd PCI slot
-            .dev = 6<<3,
-            .links = {
-                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 5,
-        },
-    }
-};
-#endif // CONFIG_PIRTABLE
-
-void
-pirtable_setup(void)
-{
-    if (! CONFIG_PIRTABLE)
-        return;
-
-    dprintf(3, "init PIR table\n");
-
-    PIR_TABLE.pir.signature = PIR_SIGNATURE;
-    PIR_TABLE.pir.checksum -= checksum(&PIR_TABLE, sizeof(PIR_TABLE));
-    PirAddr = &PIR_TABLE.pir;
-}
index 9e61580a5b720436db5d2554a42891be980e905c..7d6fbd2d1d850bc2b5f33ead3a194aa4b1d214c0 100644 (file)
@@ -17,8 +17,8 @@
 #include "bregs.h" // struct bregs
 #include "boot.h" // boot_init
 #include "hw/usb.h" // usb_setup
-#include "paravirt.h" // qemu_cfg_preinit
-#include "xen.h" // xen_preinit
+#include "fw/paravirt.h" // qemu_cfg_preinit
+#include "fw/xen.h" // xen_preinit
 #include "hw/ps2port.h" // ps2port_setup
 #include "hw/virtio-blk.h" // virtio_blk_setup
 #include "hw/virtio-scsi.h" // virtio_scsi_setup
diff --git a/src/q35-acpi-dsdt.dsl b/src/q35-acpi-dsdt.dsl
deleted file mode 100644 (file)
index c031d83..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Bochs/QEMU ACPI DSDT ASL definition
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-/*
- * Copyright (c) 2010 Isaku Yamahata
- *                    yamahata at valinux co jp
- * Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
- */
-
-DefinitionBlock (
-    "q35-acpi-dsdt.aml",// Output Filename
-    "DSDT",             // Signature
-    0x01,               // DSDT Compliance Revision
-    "BXPC",             // OEMID
-    "BXDSDT",           // TABLE ID
-    0x2                 // OEM Revision
-    )
-{
-
-#include "acpi-dsdt-dbug.dsl"
-
-    Scope(\_SB) {
-        OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
-        OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
-        Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
-            PCIB, 8,
-        }
-    }
-
-
-/****************************************************************
- * PCI Bus definition
- ****************************************************************/
-
-    Scope(\_SB) {
-        Device(PCI0) {
-            Name(_HID, EisaId("PNP0A08"))
-            Name(_CID, EisaId("PNP0A03"))
-            Name(_ADR, 0x00)
-            Name(_UID, 1)
-
-            // _OSC: based on sample of ACPI3.0b spec
-            Name(SUPP, 0) // PCI _OSC Support Field value
-            Name(CTRL, 0) // PCI _OSC Control Field value
-            Method(_OSC, 4) {
-                // Create DWORD-addressable fields from the Capabilities Buffer
-                CreateDWordField(Arg3, 0, CDW1)
-
-                // Check for proper UUID
-                If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
-                    // Create DWORD-addressable fields from the Capabilities Buffer
-                    CreateDWordField(Arg3, 4, CDW2)
-                    CreateDWordField(Arg3, 8, CDW3)
-
-                    // Save Capabilities DWORD2 & 3
-                    Store(CDW2, SUPP)
-                    Store(CDW3, CTRL)
-
-                    // Always allow native PME, AER (no dependencies)
-                    // Never allow SHPC (no SHPC controller in this system)
-                    And(CTRL, 0x1D, CTRL)
-
-#if 0 // For now, nothing to do
-                    If (Not(And(CDW1, 1))) { // Query flag clear?
-                        // Disable GPEs for features granted native control.
-                        If (And(CTRL, 0x01)) { // Hot plug control granted?
-                            Store(0, HPCE) // clear the hot plug SCI enable bit
-                            Store(1, HPCS) // clear the hot plug SCI status bit
-                        }
-                        If (And(CTRL, 0x04)) { // PME control granted?
-                            Store(0, PMCE) // clear the PME SCI enable bit
-                            Store(1, PMCS) // clear the PME SCI status bit
-                        }
-                        If (And(CTRL, 0x10)) { // OS restoring PCI Express cap structure?
-                            // Set status to not restore PCI Express cap structure
-                            // upon resume from S3
-                            Store(1, S3CR)
-                        }
-                    }
-#endif
-                    If (LNotEqual(Arg1, One)) {
-                        // Unknown revision
-                        Or(CDW1, 0x08, CDW1)
-                    }
-                    If (LNotEqual(CDW3, CTRL)) {
-                        // Capabilities bits were masked
-                        Or(CDW1, 0x10, CDW1)
-                    }
-                    // Update DWORD3 in the buffer
-                    Store(CTRL, CDW3)
-                } Else {
-                    Or(CDW1, 4, CDW1) // Unrecognized UUID
-                }
-                Return (Arg3)
-            }
-        }
-    }
-
-#include "acpi-dsdt-pci-crs.dsl"
-#include "acpi-dsdt-hpet.dsl"
-
-
-/****************************************************************
- * VGA
- ****************************************************************/
-
-    Scope(\_SB.PCI0) {
-        Device(VGA) {
-            Name(_ADR, 0x00010000)
-            Method(_S1D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S2D, 0, NotSerialized) {
-                Return (0x00)
-            }
-            Method(_S3D, 0, NotSerialized) {
-                Return (0x00)
-            }
-        }
-    }
-
-
-/****************************************************************
- * LPC ISA bridge
- ****************************************************************/
-
-    Scope(\_SB.PCI0) {
-        /* PCI D31:f0 LPC ISA bridge */
-        Device(ISA) {
-            /* PCI D31:f0 */
-            Name(_ADR, 0x001f0000)
-
-            /* ICH9 PCI to ISA irq remapping */
-            OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
-
-            OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
-            Field(LPCD, AnyAcc, NoLock, Preserve) {
-                COMA,   3,
-                    ,   1,
-                COMB,   3,
-
-                Offset(0x01),
-                LPTD,   2,
-                    ,   2,
-                FDCD,   2
-            }
-            OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
-            Field(LPCE, AnyAcc, NoLock, Preserve) {
-                CAEN,   1,
-                CBEN,   1,
-                LPEN,   1,
-                FDEN,   1
-            }
-        }
-    }
-
-#include "acpi-dsdt-isa.dsl"
-
-
-/****************************************************************
- * PCI IRQs
- ****************************************************************/
-
-    /* Zero => PIC mode, One => APIC Mode */
-    Name(\PICF, Zero)
-    Method(\_PIC, 1, NotSerialized) {
-        Store(Arg0, \PICF)
-    }
-
-    Scope(\_SB) {
-        Scope(PCI0) {
-#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3)  \
-    Package() { nr##ffff, 0, lnk0, 0 },           \
-    Package() { nr##ffff, 1, lnk1, 0 },           \
-    Package() { nr##ffff, 2, lnk2, 0 },           \
-    Package() { nr##ffff, 3, lnk3, 0 }
-
-#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
-#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
-#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
-#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
-
-#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
-#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
-#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
-#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
-
-            Name(PRTP, package() {
-                prt_slot_lnkE(0x0000),
-                prt_slot_lnkF(0x0001),
-                prt_slot_lnkG(0x0002),
-                prt_slot_lnkH(0x0003),
-                prt_slot_lnkE(0x0004),
-                prt_slot_lnkF(0x0005),
-                prt_slot_lnkG(0x0006),
-                prt_slot_lnkH(0x0007),
-                prt_slot_lnkE(0x0008),
-                prt_slot_lnkF(0x0009),
-                prt_slot_lnkG(0x000a),
-                prt_slot_lnkH(0x000b),
-                prt_slot_lnkE(0x000c),
-                prt_slot_lnkF(0x000d),
-                prt_slot_lnkG(0x000e),
-                prt_slot_lnkH(0x000f),
-                prt_slot_lnkE(0x0010),
-                prt_slot_lnkF(0x0011),
-                prt_slot_lnkG(0x0012),
-                prt_slot_lnkH(0x0013),
-                prt_slot_lnkE(0x0014),
-                prt_slot_lnkF(0x0015),
-                prt_slot_lnkG(0x0016),
-                prt_slot_lnkH(0x0017),
-                prt_slot_lnkE(0x0018),
-
-                /* INTA -> PIRQA for slot 25 - 31
-                   see the default value of D<N>IR */
-                prt_slot_lnkA(0x0019),
-                prt_slot_lnkA(0x001a),
-                prt_slot_lnkA(0x001b),
-                prt_slot_lnkA(0x001c),
-                prt_slot_lnkA(0x001d),
-
-                /* PCIe->PCI bridge. use PIRQ[E-H] */
-                prt_slot_lnkE(0x001e),
-
-                prt_slot_lnkA(0x001f)
-            })
-
-#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3)  \
-    Package() { nr##ffff, 0, gsi0, 0 },           \
-    Package() { nr##ffff, 1, gsi1, 0 },           \
-    Package() { nr##ffff, 2, gsi2, 0 },           \
-    Package() { nr##ffff, 3, gsi3, 0 }
-
-#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
-#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
-#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
-#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
-
-#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
-#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
-#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
-#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
-
-            Name(PRTA, package() {
-                prt_slot_gsiE(0x0000),
-                prt_slot_gsiF(0x0001),
-                prt_slot_gsiG(0x0002),
-                prt_slot_gsiH(0x0003),
-                prt_slot_gsiE(0x0004),
-                prt_slot_gsiF(0x0005),
-                prt_slot_gsiG(0x0006),
-                prt_slot_gsiH(0x0007),
-                prt_slot_gsiE(0x0008),
-                prt_slot_gsiF(0x0009),
-                prt_slot_gsiG(0x000a),
-                prt_slot_gsiH(0x000b),
-                prt_slot_gsiE(0x000c),
-                prt_slot_gsiF(0x000d),
-                prt_slot_gsiG(0x000e),
-                prt_slot_gsiH(0x000f),
-                prt_slot_gsiE(0x0010),
-                prt_slot_gsiF(0x0011),
-                prt_slot_gsiG(0x0012),
-                prt_slot_gsiH(0x0013),
-                prt_slot_gsiE(0x0014),
-                prt_slot_gsiF(0x0015),
-                prt_slot_gsiG(0x0016),
-                prt_slot_gsiH(0x0017),
-                prt_slot_gsiE(0x0018),
-
-                /* INTA -> PIRQA for slot 25 - 31, but 30
-                   see the default value of D<N>IR */
-                prt_slot_gsiA(0x0019),
-                prt_slot_gsiA(0x001a),
-                prt_slot_gsiA(0x001b),
-                prt_slot_gsiA(0x001c),
-                prt_slot_gsiA(0x001d),
-
-                /* PCIe->PCI bridge. use PIRQ[E-H] */
-                prt_slot_gsiE(0x001e),
-
-                prt_slot_gsiA(0x001f)
-            })
-
-            Method(_PRT, 0, NotSerialized) {
-                /* PCI IRQ routing table, example from ACPI 2.0a specification,
-                   section 6.2.8.1 */
-                /* Note: we provide the same info as the PCI routing
-                   table of the Bochs BIOS */
-                If (LEqual(\PICF, Zero)) {
-                    Return (PRTP)
-                } Else {
-                    Return (PRTA)
-                }
-            }
-        }
-
-        Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
-            PRQA,   8,
-            PRQB,   8,
-            PRQC,   8,
-            PRQD,   8,
-
-            Offset(0x08),
-            PRQE,   8,
-            PRQF,   8,
-            PRQG,   8,
-            PRQH,   8
-        }
-
-        Method(IQST, 1, NotSerialized) {
-            // _STA method - get status
-            If (And(0x80, Arg0)) {
-                Return (0x09)
-            }
-            Return (0x0B)
-        }
-        Method(IQCR, 1, NotSerialized) {
-            // _CRS method - get current settings
-            Name(PRR0, ResourceTemplate() {
-                Interrupt(, Level, ActiveHigh, Shared) { 0 }
-            })
-            CreateDWordField(PRR0, 0x05, PRRI)
-            Store(And(Arg0, 0x0F), PRRI)
-            Return (PRR0)
-        }
-
-#define define_link(link, uid, reg)                             \
-        Device(link) {                                          \
-            Name(_HID, EISAID("PNP0C0F"))                       \
-            Name(_UID, uid)                                     \
-            Name(_PRS, ResourceTemplate() {                     \
-                Interrupt(, Level, ActiveHigh, Shared) {        \
-                    5, 10, 11                                   \
-                }                                               \
-            })                                                  \
-            Method(_STA, 0, NotSerialized) {                    \
-                Return (IQST(reg))                              \
-            }                                                   \
-            Method(_DIS, 0, NotSerialized) {                    \
-                Or(reg, 0x80, reg)                              \
-            }                                                   \
-            Method(_CRS, 0, NotSerialized) {                    \
-                Return (IQCR(reg))                              \
-            }                                                   \
-            Method(_SRS, 1, NotSerialized) {                    \
-                CreateDWordField(Arg0, 0x05, PRRI)              \
-                Store(PRRI, reg)                                \
-            }                                                   \
-        }
-
-        define_link(LNKA, 0, PRQA)
-        define_link(LNKB, 1, PRQB)
-        define_link(LNKC, 2, PRQC)
-        define_link(LNKD, 3, PRQD)
-        define_link(LNKE, 4, PRQE)
-        define_link(LNKF, 5, PRQF)
-        define_link(LNKG, 6, PRQG)
-        define_link(LNKH, 7, PRQH)
-
-#define define_gsi_link(link, uid, gsi)                         \
-        Device(link) {                                          \
-            Name(_HID, EISAID("PNP0C0F"))                       \
-            Name(_UID, uid)                                     \
-            Name(_PRS, ResourceTemplate() {                     \
-                Interrupt(, Level, ActiveHigh, Shared) {        \
-                    gsi                                         \
-                }                                               \
-            })                                                  \
-            Name(_CRS, ResourceTemplate() {                     \
-                Interrupt(, Level, ActiveHigh, Shared) {        \
-                    gsi                                         \
-                }                                               \
-            })                                                  \
-            Method(_SRS, 1, NotSerialized) {                    \
-            }                                                   \
-        }
-
-        define_gsi_link(GSIA, 0, 0x10)
-        define_gsi_link(GSIB, 0, 0x11)
-        define_gsi_link(GSIC, 0, 0x12)
-        define_gsi_link(GSID, 0, 0x13)
-        define_gsi_link(GSIE, 0, 0x14)
-        define_gsi_link(GSIF, 0, 0x15)
-        define_gsi_link(GSIG, 0, 0x16)
-        define_gsi_link(GSIH, 0, 0x17)
-    }
-
-#include "acpi-dsdt-cpu-hotplug.dsl"
-
-
-/****************************************************************
- * General purpose events
- ****************************************************************/
-
-    Scope(\_GPE) {
-        Name(_HID, "ACPI0006")
-
-        Method(_L00) {
-        }
-        Method(_L01) {
-            // CPU hotplug event
-            \_SB.PRSC()
-        }
-        Method(_L02) {
-        }
-        Method(_L03) {
-        }
-        Method(_L04) {
-        }
-        Method(_L05) {
-        }
-        Method(_L06) {
-        }
-        Method(_L07) {
-        }
-        Method(_L08) {
-        }
-        Method(_L09) {
-        }
-        Method(_L0A) {
-        }
-        Method(_L0B) {
-        }
-        Method(_L0C) {
-        }
-        Method(_L0D) {
-        }
-        Method(_L0E) {
-        }
-        Method(_L0F) {
-        }
-    }
-}
index 8ec6e37ba499e76d045dfb638d884c6a28acb1ee..5323d7ea4caf4f9286be67800a69b603ae0a3d90 100644 (file)
@@ -9,7 +9,7 @@
 #include "hw/pic.h" // pic_eoi2
 #include "biosvar.h" // struct bios_data_area_s
 #include "bregs.h" // struct bregs
-#include "acpi.h" // find_resume_vector
+#include "fw/acpi.h" // find_resume_vector
 #include "hw/ps2port.h" // i8042_reboot
 #include "hw/pci.h" // pci_reboot
 #include "hw/cmos.h" // inb_cmos
diff --git a/src/shadow.c b/src/shadow.c
deleted file mode 100644 (file)
index 67e943f..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// Support for enabling/disabling BIOS ram shadowing.
-//
-// Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "util.h" // memcpy
-#include "hw/pci.h" // pci_config_writeb
-#include "config.h" // CONFIG_*
-#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
-#include "hw/pci_regs.h" // PCI_VENDOR_ID
-#include "paravirt.h" // runningOnXen
-#include "dev-q35.h" // PCI_VENDOR_ID_INTEL
-
-// On the emulators, the bios at 0xf0000 is also at 0xffff0000
-#define BIOS_SRC_OFFSET 0xfff00000
-
-#define I440FX_PAM0     0x59
-
-// Enable shadowing and copy bios.
-static void
-__make_bios_writable_intel(u16 bdf, u32 pam0)
-{
-    // Make ram from 0xc0000-0xf0000 writable
-    int clear = 0;
-    int i;
-    for (i=0; i<6; i++) {
-        u32 pam = pam0 + 1 + i;
-        int reg = pci_config_readb(bdf, pam);
-        if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
-            // Need to copy optionroms to work around qemu implementation
-            void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
-            memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
-            pci_config_writeb(bdf, pam, 0x33);
-            memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
-            clear = 1;
-        } else {
-            pci_config_writeb(bdf, pam, 0x33);
-        }
-    }
-    if (clear)
-        memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
-
-    // Make ram from 0xf0000-0x100000 writable
-    int reg = pci_config_readb(bdf, pam0);
-    pci_config_writeb(bdf, pam0, 0x30);
-    if (reg & 0x10)
-        // Ram already present.
-        return;
-
-    // Copy bios.
-    extern u8 code32flat_start[], code32flat_end[];
-    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
-           , code32flat_end - code32flat_start);
-}
-
-static void
-make_bios_writable_intel(u16 bdf, u32 pam0)
-{
-    int reg = pci_config_readb(bdf, pam0);
-    if (!(reg & 0x10)) {
-        // QEMU doesn't fully implement the piix shadow capabilities -
-        // if ram isn't backing the bios segment when shadowing is
-        // disabled, the code itself wont be in memory.  So, run the
-        // code from the high-memory flash location.
-        u32 pos = (u32)__make_bios_writable_intel + BIOS_SRC_OFFSET;
-        void (*func)(u16 bdf, u32 pam0) = (void*)pos;
-        func(bdf, pam0);
-        return;
-    }
-    // Ram already present - just enable writes
-    __make_bios_writable_intel(bdf, pam0);
-}
-
-static void
-make_bios_readonly_intel(u16 bdf, u32 pam0)
-{
-    // Flush any pending writes before locking memory.
-    wbinvd();
-
-    // Write protect roms from 0xc0000-0xf0000
-    u32 romlast = BUILD_BIOS_ADDR, rommax = BUILD_BIOS_ADDR;
-    if (CONFIG_WRITABLE_UPPERMEMORY)
-        romlast = rom_get_last();
-    if (CONFIG_MALLOC_UPPERMEMORY)
-        rommax = rom_get_max();
-    int i;
-    for (i=0; i<6; i++) {
-        u32 mem = BUILD_ROM_START + i * 32*1024;
-        u32 pam = pam0 + 1 + i;
-        if (romlast < mem + 16*1024 || rommax < mem + 32*1024) {
-            if (romlast >= mem && rommax >= mem + 16*1024)
-                pci_config_writeb(bdf, pam, 0x31);
-            break;
-        }
-        pci_config_writeb(bdf, pam, 0x11);
-    }
-
-    // Write protect 0xf0000-0x100000
-    pci_config_writeb(bdf, pam0, 0x10);
-}
-
-static int ShadowBDF = -1;
-
-// Make the 0xc0000-0x100000 area read/writable.
-void
-make_bios_writable(void)
-{
-    if (!CONFIG_QEMU || runningOnXen())
-        return;
-
-    dprintf(3, "enabling shadow ram\n");
-
-    // At this point, statically allocated variables can't be written,
-    // so do this search manually.
-    int bdf;
-    foreachbdf(bdf, 0) {
-        u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
-        u16 vendor = vendev & 0xffff, device = vendev >> 16;
-        if (vendor == PCI_VENDOR_ID_INTEL
-            && device == PCI_DEVICE_ID_INTEL_82441) {
-            make_bios_writable_intel(bdf, I440FX_PAM0);
-            ShadowBDF = bdf;
-            return;
-        }
-        if (vendor == PCI_VENDOR_ID_INTEL
-            && device == PCI_DEVICE_ID_INTEL_Q35_MCH) {
-            make_bios_writable_intel(bdf, Q35_HOST_BRIDGE_PAM0);
-            ShadowBDF = bdf;
-            return;
-        }
-    }
-    dprintf(1, "Unable to unlock ram - bridge not found\n");
-}
-
-// Make the BIOS code segment area (0xf0000) read-only.
-void
-make_bios_readonly(void)
-{
-    if (!CONFIG_QEMU || runningOnXen())
-        return;
-    dprintf(3, "locking shadow ram\n");
-
-    if (ShadowBDF < 0) {
-        dprintf(1, "Unable to lock ram - bridge not found\n");
-        return;
-    }
-
-    u16 device = pci_config_readw(ShadowBDF, PCI_DEVICE_ID);
-    if (device == PCI_DEVICE_ID_INTEL_82441)
-        make_bios_readonly_intel(ShadowBDF, I440FX_PAM0);
-    else
-        make_bios_readonly_intel(ShadowBDF, Q35_HOST_BRIDGE_PAM0);
-}
-
-void
-qemu_prep_reset(void)
-{
-    if (!CONFIG_QEMU || runningOnXen())
-        return;
-    // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
-    // reset, so do that manually before invoking a hard reset.
-    make_bios_writable();
-    extern u8 code32flat_start[], code32flat_end[];
-    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
-           , code32flat_end - code32flat_start);
-}
diff --git a/src/smbios.c b/src/smbios.c
deleted file mode 100644 (file)
index fd63afb..0000000
+++ /dev/null
@@ -1,649 +0,0 @@
-// smbios table generation (on emulators)
-//
-// Copyright (C) 2008,2009  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "util.h" // dprintf
-#include "config.h" // CONFIG_*
-#include "paravirt.h" // RamSize
-#include "smbios.h" // struct smbios_entry_point
-
-struct smbios_entry_point *SMBiosAddr;
-
-static void
-smbios_entry_point_setup(u16 max_structure_size,
-                         u16 structure_table_length,
-                         void *structure_table_address,
-                         u16 number_of_structures)
-{
-    struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep));
-    void *finaltable;
-    if (structure_table_length <= BUILD_MAX_SMBIOS_FSEG)
-        // Table is small enough for f-seg - allocate there.  This
-        // works around a bug in JunOS (at least for small SMBIOS tables).
-        finaltable = malloc_fseg(structure_table_length);
-    else
-        finaltable = malloc_high(structure_table_length);
-    if (!ep || !finaltable) {
-        warn_noalloc();
-        free(ep);
-        free(finaltable);
-        return;
-    }
-    memcpy(finaltable, structure_table_address, structure_table_length);
-
-    memcpy(ep->anchor_string, "_SM_", 4);
-    ep->length = 0x1f;
-    ep->smbios_major_version = 2;
-    ep->smbios_minor_version = 4;
-    ep->max_structure_size = max_structure_size;
-    ep->entry_point_revision = 0;
-    memset(ep->formatted_area, 0, 5);
-    memcpy(ep->intermediate_anchor_string, "_DMI_", 5);
-
-    ep->structure_table_length = structure_table_length;
-    ep->structure_table_address = (u32)finaltable;
-    ep->number_of_structures = number_of_structures;
-    ep->smbios_bcd_revision = 0x24;
-
-    ep->checksum -= checksum(ep, 0x10);
-
-    ep->intermediate_checksum -= checksum((void*)ep + 0x10, ep->length - 0x10);
-
-    SMBiosAddr = ep;
-    dprintf(1, "SMBIOS ptr=%p table=%p size=%d\n"
-            , ep, finaltable, structure_table_length);
-}
-
-static int
-get_field(int type, int offset, void *dest)
-{
-    char name[128];
-    snprintf(name, sizeof(name), "smbios/field%d-%d", type, offset);
-    struct romfile_s *file = romfile_find(name);
-    if (!file)
-        return 0;
-    file->copy(file, dest, file->size);
-    return file->size;
-}
-
-static int
-get_external(int type, char **p, unsigned *nr_structs,
-             unsigned *max_struct_size, char *end)
-{
-    static u64 used_bitmap[4] = { 0 };
-    char *start = *p;
-
-    /* Check if we've already reported these tables */
-    if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
-        return 1;
-
-    /* Don't introduce spurious end markers */
-    if (type == 127)
-        return 0;
-
-    char prefix[128];
-    snprintf(prefix, sizeof(prefix), "smbios/table%d-", type);
-    struct romfile_s *file = NULL;
-    for (;;) {
-        file = romfile_findprefix(prefix, file);
-        if (!file)
-            break;
-
-        if (end - *p < file->size) {
-            warn_noalloc();
-            break;
-        }
-
-        struct smbios_structure_header *header = (void*)*p;
-        file->copy(file, header, file->size);
-        *p += file->size;
-
-        /* Entries end with a double NULL char, if there's a string at
-         * the end (length is greater than formatted length), the string
-         * terminator provides the first NULL. */
-        *((u8*)*p) = 0;
-        (*p)++;
-        if (header->length >= file->size) {
-            *((u8*)*p) = 0;
-            (*p)++;
-        }
-
-        (*nr_structs)++;
-        if (*p - (char*)header > *max_struct_size)
-            *max_struct_size = *p - (char*)header;
-    }
-
-    if (start == *p)
-        return 0;
-
-    /* Mark that we've reported on this type */
-    used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
-    return 1;
-}
-
-#define load_str_field_with_default(type, field, def)                   \
-    do {                                                                \
-        size = get_field(type, offsetof(struct smbios_type_##type,      \
-                                        field), end);                   \
-        if (size > 0) {                                                 \
-            end += size;                                                \
-        } else {                                                        \
-            memcpy(end, def, sizeof(def));                              \
-            end += sizeof(def);                                         \
-        }                                                               \
-        p->field = ++str_index;                                         \
-    } while (0)
-
-#define load_str_field_or_skip(type, field)                             \
-    do {                                                                \
-        size = get_field(type, offsetof(struct smbios_type_##type,      \
-                                        field), end);                   \
-        if (size > 0) {                                                 \
-            end += size;                                                \
-            p->field = ++str_index;                                     \
-        } else {                                                        \
-            p->field = 0;                                               \
-        }                                                               \
-    } while (0)
-
-#define set_field_with_default(type, field, def)                        \
-    do {                                                                \
-        if (!get_field(type, offsetof(struct smbios_type_##type,        \
-                                      field), &p->field)) {             \
-            p->field = def;                                             \
-        }                                                               \
-    } while (0)
-
-/* Type 0 -- BIOS Information */
-#define RELEASE_DATE_STR "01/01/2011"
-static void *
-smbios_init_type_0(void *start)
-{
-    struct smbios_type_0 *p = (struct smbios_type_0 *)start;
-    char *end = (char *)start + sizeof(struct smbios_type_0);
-    size_t size;
-    int str_index = 0;
-
-    p->header.type = 0;
-    p->header.length = sizeof(struct smbios_type_0);
-    p->header.handle = 0;
-
-    load_str_field_with_default(0, vendor_str, BUILD_APPNAME);
-    load_str_field_with_default(0, bios_version_str, BUILD_APPNAME);
-
-    p->bios_starting_address_segment = 0xe800;
-
-    load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR);
-
-    p->bios_rom_size = 0; /* FIXME */
-
-    if (!get_field(0, offsetof(struct smbios_type_0, bios_characteristics),
-                   &p->bios_characteristics)) {
-        memset(p->bios_characteristics, 0, 8);
-        /* BIOS characteristics not supported */
-        p->bios_characteristics[0] = 0x08;
-    }
-
-    if (!get_field(0, offsetof(struct smbios_type_0,
-                               bios_characteristics_extension_bytes),
-                   &p->bios_characteristics_extension_bytes)) {
-        p->bios_characteristics_extension_bytes[0] = 0;
-        /* Enable targeted content distribution. Needed for SVVP */
-        p->bios_characteristics_extension_bytes[1] = 4;
-    }
-
-    set_field_with_default(0, system_bios_major_release, 1);
-    set_field_with_default(0, system_bios_minor_release, 0);
-    set_field_with_default(0, embedded_controller_major_release, 0xff);
-    set_field_with_default(0, embedded_controller_minor_release, 0xff);
-
-    *end = 0;
-    end++;
-
-    return end;
-}
-
-/* Type 1 -- System Information */
-static void *
-smbios_init_type_1(void *start)
-{
-    struct smbios_type_1 *p = (struct smbios_type_1 *)start;
-    char *end = (char *)start + sizeof(struct smbios_type_1);
-    size_t size;
-    int str_index = 0;
-
-    p->header.type = 1;
-    p->header.length = sizeof(struct smbios_type_1);
-    p->header.handle = 0x100;
-
-    load_str_field_with_default(1, manufacturer_str, BUILD_APPNAME);
-    load_str_field_with_default(1, product_name_str, BUILD_APPNAME);
-    load_str_field_or_skip(1, version_str);
-    load_str_field_or_skip(1, serial_number_str);
-
-    if (!get_field(1, offsetof(struct smbios_type_1, uuid), &p->uuid))
-        memset(p->uuid, 0, 16);
-
-    set_field_with_default(1, wake_up_type, 0x06); /* power switch */
-
-    load_str_field_or_skip(1, sku_number_str);
-    load_str_field_or_skip(1, family_str);
-
-    *end = 0;
-    end++;
-    if (!str_index) {
-        *end = 0;
-        end++;
-    }
-
-    return end;
-}
-
-/* Type 3 -- System Enclosure */
-static void *
-smbios_init_type_3(void *start)
-{
-    struct smbios_type_3 *p = (struct smbios_type_3 *)start;
-    char *end = (char *)start + sizeof(struct smbios_type_3);
-    size_t size;
-    int str_index = 0;
-
-    p->header.type = 3;
-    p->header.length = sizeof(struct smbios_type_3);
-    p->header.handle = 0x300;
-
-    load_str_field_with_default(3, manufacturer_str, BUILD_APPNAME);
-    set_field_with_default(3, type, 0x01); /* other */
-
-    load_str_field_or_skip(3, version_str);
-    load_str_field_or_skip(3, serial_number_str);
-    load_str_field_or_skip(3, asset_tag_number_str);
-
-    set_field_with_default(3, boot_up_state, 0x03); /* safe */
-    set_field_with_default(3, power_supply_state, 0x03); /* safe */
-    set_field_with_default(3, thermal_state, 0x03); /* safe */
-    set_field_with_default(3, security_status, 0x02); /* unknown */
-
-    set_field_with_default(3, oem_defined, 0);
-    set_field_with_default(3, height, 0);
-    set_field_with_default(3, number_of_power_cords, 0);
-    set_field_with_default(3, contained_element_count, 0);
-
-    *end = 0;
-    end++;
-    if (!str_index) {
-        *end = 0;
-        end++;
-    }
-
-    return end;
-}
-
-/* Type 4 -- Processor Information */
-static void *
-smbios_init_type_4(void *start, unsigned int cpu_number)
-{
-    struct smbios_type_4 *p = (struct smbios_type_4 *)start;
-    char *end = (char *)start + sizeof(struct smbios_type_4);
-    size_t size;
-    int str_index = 0;
-    char name[1024];
-
-    p->header.type = 4;
-    p->header.length = sizeof(struct smbios_type_4);
-    p->header.handle = 0x400 + cpu_number;
-
-    size = get_field(4, offsetof(struct smbios_type_4, socket_designation_str),
-                     name);
-    if (size)
-        snprintf(name + size - 1, sizeof(name) - size, "%2x", cpu_number);
-    else
-        snprintf(name, sizeof(name), "CPU%2x", cpu_number);
-
-    memcpy(end, name, strlen(name) + 1);
-    end += strlen(name) + 1;
-    p->socket_designation_str = ++str_index;
-
-    set_field_with_default(4, processor_type, 0x03); /* CPU */
-    set_field_with_default(4, processor_family, 0x01); /* other */
-
-    load_str_field_with_default(4, processor_manufacturer_str, BUILD_APPNAME);
-
-    if (!get_field(4, offsetof(struct smbios_type_4, processor_id)
-                   , p->processor_id)) {
-        u32 cpuid_signature, ebx, ecx, cpuid_features;
-        cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
-        p->processor_id[0] = cpuid_signature;
-        p->processor_id[1] = cpuid_features;
-    }
-
-    load_str_field_or_skip(4, processor_version_str);
-    set_field_with_default(4, voltage, 0);
-    set_field_with_default(4, external_clock, 0);
-
-    set_field_with_default(4, max_speed, 2000);
-    set_field_with_default(4, current_speed, 2000);
-
-    set_field_with_default(4, status, 0x41); /* socket populated, CPU enabled */
-    set_field_with_default(4, processor_upgrade, 0x01); /* other */
-
-    /* cache information structure not provided */
-    p->l1_cache_handle =  0xffff;
-    p->l2_cache_handle =  0xffff;
-    p->l3_cache_handle =  0xffff;
-
-    *end = 0;
-    end++;
-    if (!str_index) {
-        *end = 0;
-        end++;
-    }
-
-    return end;
-}
-
-/* Type 16 -- Physical Memory Array */
-static void *
-smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs)
-{
-    struct smbios_type_16 *p = (struct smbios_type_16*)start;
-
-    p->header.type = 16;
-    p->header.length = sizeof(struct smbios_type_16);
-    p->header.handle = 0x1000;
-
-    set_field_with_default(16, location, 0x01); /* other */
-    set_field_with_default(16, use, 0x03); /* system memory */
-    /* Multi-bit ECC to make Microsoft happy */
-    set_field_with_default(16, error_correction, 0x06);
-    /* 0x80000000 = unknown, accept sizes < 2TB - TODO multiple arrays */
-    p->maximum_capacity = memory_size_mb < 2 << 20 ?
-                          memory_size_mb << 10 : 0x80000000;
-    p->memory_error_information_handle = 0xfffe; /* none provided */
-    p->number_of_memory_devices = nr_mem_devs;
-
-    start += sizeof(struct smbios_type_16);
-    *((u16 *)start) = 0;
-
-    return start + 2;
-}
-
-/* Type 17 -- Memory Device */
-static void *
-smbios_init_type_17(void *start, u32 size_mb, int instance)
-{
-    struct smbios_type_17 *p = (struct smbios_type_17 *)start;
-    char *end = (char *)start + sizeof(struct smbios_type_17);
-    size_t size;
-    int str_index = 0;
-    char name[1024];
-
-    p->header.type = 17;
-    p->header.length = sizeof(struct smbios_type_17);
-    p->header.handle = 0x1100 + instance;
-
-    p->physical_memory_array_handle = 0x1000;
-    set_field_with_default(17, total_width, 64);
-    set_field_with_default(17, data_width, 64);
-/* TODO: should assert in case something is wrong   ASSERT((memory_size_mb & ~0x7fff) == 0); */
-    p->size = size_mb;
-    set_field_with_default(17, form_factor, 0x09); /* DIMM */
-    p->device_set = 0;
-
-    size = get_field(17, offsetof(struct smbios_type_17, device_locator_str),
-                     name);
-    if (size)
-        snprintf(name + size - 1, sizeof(name) - size, "%d", instance);
-    else
-        snprintf(name, sizeof(name), "DIMM %d", instance);
-
-    memcpy(end, name, strlen(name) + 1);
-    end += strlen(name) + 1;
-    p->device_locator_str = ++str_index;
-
-    load_str_field_or_skip(17, bank_locator_str);
-    set_field_with_default(17, memory_type, 0x07); /* RAM */
-    set_field_with_default(17, type_detail, 0);
-
-    *end = 0;
-    end++;
-    if (!str_index) {
-        *end = 0;
-        end++;
-    }
-
-    return end;
-}
-
-/* Type 19 -- Memory Array Mapped Address */
-static void *
-smbios_init_type_19(void *start, u32 start_mb, u32 size_mb, int instance)
-{
-    struct smbios_type_19 *p = (struct smbios_type_19 *)start;
-
-    p->header.type = 19;
-    p->header.length = sizeof(struct smbios_type_19);
-    p->header.handle = 0x1300 + instance;
-
-    p->starting_address = start_mb << 10;
-    p->ending_address = p->starting_address + (size_mb << 10) - 1;
-    p->memory_array_handle = 0x1000;
-    p->partition_width = 1;
-
-    start += sizeof(struct smbios_type_19);
-    *((u16 *)start) = 0;
-
-    return start + 2;
-}
-
-/* Type 20 -- Memory Device Mapped Address */
-static void *
-smbios_init_type_20(void *start, u32 start_mb, u32 size_mb, int instance,
-                    int dev_handle, int array_handle)
-{
-    struct smbios_type_20 *p = (struct smbios_type_20 *)start;
-
-    p->header.type = 20;
-    p->header.length = sizeof(struct smbios_type_20);
-    p->header.handle = 0x1400 + instance;
-
-    p->starting_address = start_mb << 10;
-    p->ending_address = p->starting_address + (size_mb << 10) - 1;
-    p->memory_device_handle = 0x1100 + dev_handle;
-    p->memory_array_mapped_address_handle = 0x1300 + array_handle;
-    p->partition_row_position = 1;
-    p->interleave_position = 0;
-    p->interleaved_data_depth = 0;
-
-    start += sizeof(struct smbios_type_20);
-
-    *((u16 *)start) = 0;
-    return start+2;
-}
-
-/* Type 32 -- System Boot Information */
-static void *
-smbios_init_type_32(void *start)
-{
-    struct smbios_type_32 *p = (struct smbios_type_32 *)start;
-
-    p->header.type = 32;
-    p->header.length = sizeof(struct smbios_type_32);
-    p->header.handle = 0x2000;
-    memset(p->reserved, 0, 6);
-    set_field_with_default(32, boot_status, 0); /* no errors detected */
-
-    start += sizeof(struct smbios_type_32);
-    *((u16 *)start) = 0;
-
-    return start+2;
-}
-
-/* Type 127 -- End of Table */
-static void *
-smbios_init_type_127(void *start)
-{
-    struct smbios_type_127 *p = (struct smbios_type_127 *)start;
-
-    p->header.type = 127;
-    p->header.length = sizeof(struct smbios_type_127);
-    p->header.handle = 0x7f00;
-
-    start += sizeof(struct smbios_type_127);
-    *((u16 *)start) = 0;
-
-    return start + 2;
-}
-
-#define TEMPSMBIOSSIZE (32 * 1024)
-
-void
-smbios_setup(void)
-{
-    if (! CONFIG_SMBIOS)
-        return;
-
-    dprintf(3, "init SMBIOS tables\n");
-
-    char *start = malloc_tmphigh(TEMPSMBIOSSIZE);
-    if (! start) {
-        warn_noalloc();
-        return;
-    }
-
-    u32 nr_structs = 0, max_struct_size = 0;
-    char *q, *p = start;
-    char *end = start + TEMPSMBIOSSIZE - sizeof(struct smbios_type_127);
-
-#define add_struct(type, args...)                                       \
-    do {                                                                \
-        if (!get_external(type, &p, &nr_structs, &max_struct_size, end)) { \
-            q = smbios_init_type_##type(args);                          \
-            nr_structs++;                                               \
-            if ((q - p) > max_struct_size)                              \
-                max_struct_size = q - p;                                \
-            p = q;                                                      \
-        }                                                               \
-    } while (0)
-
-    add_struct(0, p);
-    add_struct(1, p);
-    add_struct(3, p);
-
-    int cpu_num;
-    for (cpu_num = 1; cpu_num <= MaxCountCPUs; cpu_num++)
-        add_struct(4, p, cpu_num);
-
-    int ram_mb = (RamSize + RamSizeOver4G) >> 20;
-    int nr_mem_devs = (ram_mb + 0x3fff) >> 14;
-    add_struct(16, p, ram_mb, nr_mem_devs);
-
-    int i, j;
-    for (i = 0; i < nr_mem_devs; i++) {
-        u32 dev_mb = ((i == (nr_mem_devs - 1))
-                      ? (((ram_mb - 1) & 0x3fff) + 1)
-                      : 16384);
-        add_struct(17, p, dev_mb, i);
-    }
-
-    add_struct(19, p, 0, RamSize >> 20, 0);
-    if (RamSizeOver4G)
-        add_struct(19, p, 4096, RamSizeOver4G >> 20, 1);
-
-    add_struct(20, p, 0, RamSize >> 20, 0, 0, 0);
-    if (RamSizeOver4G) {
-        u32 start_mb = 4096;
-        for (j = 1, i = 0; i < nr_mem_devs; i++, j++) {
-            u32 dev_mb = ((i == (nr_mem_devs - 1))
-                               ? (((ram_mb - 1) & 0x3fff) + 1)
-                               : 16384);
-            if (i == 0)
-                dev_mb -= RamSize >> 20;
-
-            add_struct(20, p, start_mb, dev_mb, j, i, 1);
-            start_mb += dev_mb;
-        }
-    }
-
-    add_struct(32, p);
-    /* Add any remaining provided entries before the end marker */
-    for (i = 0; i < 256; i++)
-        get_external(i, &p, &nr_structs, &max_struct_size, end);
-    add_struct(127, p);
-
-#undef add_struct
-
-    smbios_entry_point_setup(max_struct_size, p - start, start, nr_structs);
-    free(start);
-}
-
-void
-display_uuid(void)
-{
-    u32 addr, end;
-    u8 *uuid;
-    u8 empty_uuid[16] = { 0 };
-
-    if (SMBiosAddr == NULL)
-        return;
-
-    addr =        SMBiosAddr->structure_table_address;
-    end  = addr + SMBiosAddr->structure_table_length;
-
-    /* the following takes care of any initial wraparound too */
-    while (addr < end) {
-        const struct smbios_structure_header *hdr;
-
-        /* partial structure header */
-        if (end - addr < sizeof(struct smbios_structure_header))
-            return;
-
-        hdr = (struct smbios_structure_header *)addr;
-
-        /* partial structure */
-        if (end - addr < hdr->length)
-            return;
-
-        /* any Type 1 structure version will do that has the UUID */
-        if (hdr->type == 1 &&
-            hdr->length >= offsetof(struct smbios_type_1, uuid) + 16)
-            break;
-
-        /* done with formatted area, skip string-set */
-        addr += hdr->length;
-
-        while (end - addr >= 2 &&
-               (*(u8 *)addr     != '\0' ||
-                *(u8 *)(addr+1) != '\0'))
-            ++addr;
-
-        /* structure terminator not found */
-        if (end - addr < 2)
-            return;
-
-        addr += 2;
-    }
-
-    /* parsing finished or skipped entirely, UUID not found */
-    if (addr >= end)
-        return;
-
-    uuid = (u8 *)(addr + offsetof(struct smbios_type_1, uuid));
-    if (memcmp(uuid, empty_uuid, sizeof empty_uuid) == 0)
-        return;
-
-    printf("Machine UUID"
-             " %02x%02x%02x%02x"
-             "-%02x%02x"
-             "-%02x%02x"
-             "-%02x%02x"
-             "-%02x%02x%02x%02x%02x%02x\n"
-           , uuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3]
-           , uuid[ 4], uuid[ 5]
-           , uuid[ 6], uuid[ 7]
-           , uuid[ 8], uuid[ 9]
-           , uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
-}
diff --git a/src/smbios.h b/src/smbios.h
deleted file mode 100644 (file)
index a4c1444..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-#ifndef __SMBIOS_H
-#define __SMBIOS_H
-
-// smbios.c
-void smbios_setup(void);
-
-/* SMBIOS entry point -- must be written to a 16-bit aligned address
-   between 0xf0000 and 0xfffff.
- */
-struct smbios_entry_point {
-    char anchor_string[4];
-    u8 checksum;
-    u8 length;
-    u8 smbios_major_version;
-    u8 smbios_minor_version;
-    u16 max_structure_size;
-    u8 entry_point_revision;
-    u8 formatted_area[5];
-    char intermediate_anchor_string[5];
-    u8 intermediate_checksum;
-    u16 structure_table_length;
-    u32 structure_table_address;
-    u16 number_of_structures;
-    u8 smbios_bcd_revision;
-} PACKED;
-
-extern struct smbios_entry_point *SMBiosAddr;
-
-/* This goes at the beginning of every SMBIOS structure. */
-struct smbios_structure_header {
-    u8 type;
-    u8 length;
-    u16 handle;
-} PACKED;
-
-/* SMBIOS type 0 - BIOS Information */
-struct smbios_type_0 {
-    struct smbios_structure_header header;
-    u8 vendor_str;
-    u8 bios_version_str;
-    u16 bios_starting_address_segment;
-    u8 bios_release_date_str;
-    u8 bios_rom_size;
-    u8 bios_characteristics[8];
-    u8 bios_characteristics_extension_bytes[2];
-    u8 system_bios_major_release;
-    u8 system_bios_minor_release;
-    u8 embedded_controller_major_release;
-    u8 embedded_controller_minor_release;
-} PACKED;
-
-/* SMBIOS type 1 - System Information */
-struct smbios_type_1 {
-    struct smbios_structure_header header;
-    u8 manufacturer_str;
-    u8 product_name_str;
-    u8 version_str;
-    u8 serial_number_str;
-    u8 uuid[16];
-    u8 wake_up_type;
-    u8 sku_number_str;
-    u8 family_str;
-} PACKED;
-
-/* SMBIOS type 3 - System Enclosure (v2.3) */
-struct smbios_type_3 {
-    struct smbios_structure_header header;
-    u8 manufacturer_str;
-    u8 type;
-    u8 version_str;
-    u8 serial_number_str;
-    u8 asset_tag_number_str;
-    u8 boot_up_state;
-    u8 power_supply_state;
-    u8 thermal_state;
-    u8 security_status;
-    u32 oem_defined;
-    u8 height;
-    u8 number_of_power_cords;
-    u8 contained_element_count;
-    // contained elements follow
-} PACKED;
-
-/* SMBIOS type 4 - Processor Information (v2.0) */
-struct smbios_type_4 {
-    struct smbios_structure_header header;
-    u8 socket_designation_str;
-    u8 processor_type;
-    u8 processor_family;
-    u8 processor_manufacturer_str;
-    u32 processor_id[2];
-    u8 processor_version_str;
-    u8 voltage;
-    u16 external_clock;
-    u16 max_speed;
-    u16 current_speed;
-    u8 status;
-    u8 processor_upgrade;
-    u16 l1_cache_handle;
-    u16 l2_cache_handle;
-    u16 l3_cache_handle;
-} PACKED;
-
-/* SMBIOS type 16 - Physical Memory Array
- *   Associated with one type 17 (Memory Device).
- */
-struct smbios_type_16 {
-    struct smbios_structure_header header;
-    u8 location;
-    u8 use;
-    u8 error_correction;
-    u32 maximum_capacity;
-    u16 memory_error_information_handle;
-    u16 number_of_memory_devices;
-} PACKED;
-
-/* SMBIOS type 17 - Memory Device
- *   Associated with one type 19
- */
-struct smbios_type_17 {
-    struct smbios_structure_header header;
-    u16 physical_memory_array_handle;
-    u16 memory_error_information_handle;
-    u16 total_width;
-    u16 data_width;
-    u16 size;
-    u8 form_factor;
-    u8 device_set;
-    u8 device_locator_str;
-    u8 bank_locator_str;
-    u8 memory_type;
-    u16 type_detail;
-} PACKED;
-
-/* SMBIOS type 19 - Memory Array Mapped Address */
-struct smbios_type_19 {
-    struct smbios_structure_header header;
-    u32 starting_address;
-    u32 ending_address;
-    u16 memory_array_handle;
-    u8 partition_width;
-} PACKED;
-
-/* SMBIOS type 20 - Memory Device Mapped Address */
-struct smbios_type_20 {
-    struct smbios_structure_header header;
-    u32 starting_address;
-    u32 ending_address;
-    u16 memory_device_handle;
-    u16 memory_array_mapped_address_handle;
-    u8 partition_row_position;
-    u8 interleave_position;
-    u8 interleaved_data_depth;
-} PACKED;
-
-/* SMBIOS type 32 - System Boot Information */
-struct smbios_type_32 {
-    struct smbios_structure_header header;
-    u8 reserved[6];
-    u8 boot_status;
-} PACKED;
-
-/* SMBIOS type 127 -- End-of-table */
-struct smbios_type_127 {
-    struct smbios_structure_header header;
-} PACKED;
-
-void display_uuid(void);
-#endif // smbios.h
diff --git a/src/smm.c b/src/smm.c
deleted file mode 100644 (file)
index 3f01207..0000000
--- a/src/smm.c
+++ /dev/null
@@ -1,196 +0,0 @@
-// System Management Mode support (on emulators)
-//
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "hw/pci.h" // pci_config_writel
-#include "hw/pci_regs.h" // PCI_DEVICE_ID
-#include "util.h" // wbinvd
-#include "config.h" // CONFIG_*
-#include "ioport.h" // outb
-#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
-#include "dev-q35.h"
-
-extern u8 smm_relocation_start, smm_relocation_end;
-ASM32FLAT(
-    ".global smm_relocation_start, smm_relocation_end\n"
-    "  .code16gcc\n"
-
-    /* code to relocate SMBASE to 0xa0000 */
-    "smm_relocation_start:\n"
-    "  movl $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7efc, %ebx\n"
-    "  addr32 movb (%ebx), %al\n"  /* revision ID to see if x86_64 or x86 */
-    "  cmpb $0x64, %al\n"
-    "  je 1f\n"
-    "  movl $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7ef8, %ebx\n"
-    "  jmp 2f\n"
-    "1:\n"
-    "  movl $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7f00, %ebx\n"
-    "2:\n"
-    "  movl $" __stringify(BUILD_SMM_ADDR) " - 0x8000, %eax\n"
-    "  addr32 movl %eax, (%ebx)\n"
-    /* indicate to the BIOS that the SMM code was executed */
-    "  movb $0x00, %al\n"
-    "  movw $" __stringify(PORT_SMI_STATUS) ", %dx\n"
-    "  outb %al, %dx\n"
-    "  rsm\n"
-    "smm_relocation_end:\n"
-    "  .code32\n"
-    );
-
-extern u8 smm_code_start, smm_code_end;
-ASM32FLAT(
-    /* minimal SMM code to enable or disable ACPI */
-    ".global smm_code_start, smm_code_end\n"
-    "  .code16gcc\n"
-    "smm_code_start:\n"
-    "  movw $" __stringify(PORT_SMI_CMD) ", %dx\n"
-    "  inb %dx, %al\n"
-    "  cmpb $0xf0, %al\n"
-    "  jne 1f\n"
-
-    /* ACPI disable */
-    "  movw $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */
-    "  inw %dx, %ax\n"
-    "  andw $~1, %ax\n"
-    "  outw %ax, %dx\n"
-
-    "  jmp 2f\n"
-
-    "1:\n"
-    "  cmpb $0xf1, %al\n"
-    "  jne 2f\n"
-
-    /* ACPI enable */
-    "  movw $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */
-    "  inw %dx, %ax\n"
-    "  orw $1, %ax\n"
-    "  outw %ax, %dx\n"
-
-    "2:\n"
-    "  rsm\n"
-    "smm_code_end:\n"
-    "  .code32\n"
-    );
-
-static void
-smm_save_and_copy(void)
-{
-    /* save original memory content */
-    memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE);
-
-    /* copy the SMM relocation code */
-    memcpy((void *)BUILD_SMM_INIT_ADDR, &smm_relocation_start,
-           &smm_relocation_end - &smm_relocation_start);
-}
-
-static void
-smm_relocate_and_restore(void)
-{
-    /* init APM status port */
-    outb(0x01, PORT_SMI_STATUS);
-
-    /* raise an SMI interrupt */
-    outb(0x00, PORT_SMI_CMD);
-
-    /* wait until SMM code executed */
-    while (inb(PORT_SMI_STATUS) != 0x00)
-        ;
-
-    /* restore original memory content */
-    memcpy((void *)BUILD_SMM_INIT_ADDR, (void *)BUILD_SMM_ADDR, BUILD_SMM_SIZE);
-
-    /* copy the SMM code */
-    memcpy((void *)BUILD_SMM_ADDR, &smm_code_start
-           , &smm_code_end - &smm_code_start);
-    wbinvd();
-}
-
-#define I440FX_SMRAM    0x72
-#define PIIX_DEVACTB    0x58
-#define PIIX_APMC_EN    (1 << 25)
-
-// This code is hardcoded for PIIX4 Power Management device.
-static void piix4_apmc_smm_setup(int isabdf, int i440_bdf)
-{
-    /* check if SMM init is already done */
-    u32 value = pci_config_readl(isabdf, PIIX_DEVACTB);
-    if (value & PIIX_APMC_EN)
-        return;
-
-    /* enable the SMM memory window */
-    pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x48);
-
-    smm_save_and_copy();
-
-    /* enable SMI generation when writing to the APMC register */
-    pci_config_writel(isabdf, PIIX_DEVACTB, value | PIIX_APMC_EN);
-
-    smm_relocate_and_restore();
-
-    /* close the SMM memory window and enable normal SMM */
-    pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x08);
-}
-
-/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
-void ich9_lpc_apmc_smm_setup(int isabdf, int mch_bdf)
-{
-    /* check if SMM init is already done */
-    u32 value = inl(PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN);
-    if (value & ICH9_PMIO_SMI_EN_APMC_EN)
-        return;
-
-    /* enable the SMM memory window */
-    pci_config_writeb(mch_bdf, Q35_HOST_BRIDGE_SMRAM, 0x02 | 0x48);
-
-    smm_save_and_copy();
-
-    /* enable SMI generation when writing to the APMC register */
-    outl(value | ICH9_PMIO_SMI_EN_APMC_EN,
-         PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN);
-
-    smm_relocate_and_restore();
-
-    /* close the SMM memory window and enable normal SMM */
-    pci_config_writeb(mch_bdf, Q35_HOST_BRIDGE_SMRAM, 0x02 | 0x08);
-}
-
-static int SMMISADeviceBDF = -1, SMMPMDeviceBDF = -1;
-
-void
-smm_device_setup(void)
-{
-    if (!CONFIG_USE_SMM)
-       return;
-
-    struct pci_device *isapci, *pmpci;
-    isapci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3);
-    pmpci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
-    if (isapci && pmpci) {
-        SMMISADeviceBDF = isapci->bdf;
-        SMMPMDeviceBDF = pmpci->bdf;
-        return;
-    }
-    isapci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC);
-    pmpci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH);
-    if (isapci && pmpci) {
-        SMMISADeviceBDF = isapci->bdf;
-        SMMPMDeviceBDF = pmpci->bdf;
-    }
-}
-
-void
-smm_setup(void)
-{
-    if (!CONFIG_USE_SMM || SMMISADeviceBDF < 0)
-       return;
-
-    dprintf(3, "init smm\n");
-    u16 device = pci_config_readw(SMMISADeviceBDF, PCI_DEVICE_ID);
-    if (device == PCI_DEVICE_ID_INTEL_82371AB_3)
-        piix4_apmc_smm_setup(SMMISADeviceBDF, SMMPMDeviceBDF);
-    else
-        ich9_lpc_apmc_smm_setup(SMMISADeviceBDF, SMMPMDeviceBDF);
-}
diff --git a/src/smp.c b/src/smp.c
deleted file mode 100644 (file)
index 6379d36..0000000
--- a/src/smp.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// CPU count detection
-//
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2006 Fabrice Bellard
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "util.h" // dprintf
-#include "config.h" // CONFIG_*
-#include "hw/cmos.h" // CMOS_BIOS_SMP_COUNT
-
-#define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300)
-#define APIC_SVR     ((u8*)BUILD_APIC_ADDR + 0x0F0)
-#define APIC_LINT0   ((u8*)BUILD_APIC_ADDR + 0x350)
-#define APIC_LINT1   ((u8*)BUILD_APIC_ADDR + 0x360)
-
-#define APIC_ENABLED 0x0100
-
-struct { u32 ecx, eax, edx; } smp_mtrr[32] VARFSEG;
-u32 smp_mtrr_count VARFSEG;
-
-void
-wrmsr_smp(u32 index, u64 val)
-{
-    wrmsr(index, val);
-    if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr)) {
-        warn_noalloc();
-        return;
-    }
-    smp_mtrr[smp_mtrr_count].ecx = index;
-    smp_mtrr[smp_mtrr_count].eax = val;
-    smp_mtrr[smp_mtrr_count].edx = val >> 32;
-    smp_mtrr_count++;
-}
-
-u32 CountCPUs VARFSEG;
-u32 MaxCountCPUs;
-// 256 bits for the found APIC IDs
-u32 FoundAPICIDs[256/32] VARFSEG;
-extern void smp_ap_boot_code(void);
-ASM16(
-    "  .global smp_ap_boot_code\n"
-    "smp_ap_boot_code:\n"
-
-    // Setup data segment
-    "  movw $" __stringify(SEG_BIOS) ", %ax\n"
-    "  movw %ax, %ds\n"
-
-    // MTRR setup
-    "  movl $smp_mtrr, %esi\n"
-    "  movl smp_mtrr_count, %ebx\n"
-    "1:testl %ebx, %ebx\n"
-    "  jz 2f\n"
-    "  movl 0(%esi), %ecx\n"
-    "  movl 4(%esi), %eax\n"
-    "  movl 8(%esi), %edx\n"
-    "  wrmsr\n"
-    "  addl $12, %esi\n"
-    "  decl %ebx\n"
-    "  jmp 1b\n"
-    "2:\n"
-
-    // get apic ID on EBX, set bit on FoundAPICIDs
-    "  movl $1, %eax\n"
-    "  cpuid\n"
-    "  shrl $24, %ebx\n"
-    "  lock btsl %ebx, FoundAPICIDs\n"
-
-    // Increment the cpu counter
-    "  lock incl CountCPUs\n"
-
-    // Halt the processor.
-    "1:hlt\n"
-    "  jmp 1b\n"
-    );
-
-int apic_id_is_present(u8 apic_id)
-{
-    return !!(FoundAPICIDs[apic_id/32] & (1ul << (apic_id % 32)));
-}
-
-// find and initialize the CPUs by launching a SIPI to them
-void
-smp_setup(void)
-{
-    if (!CONFIG_QEMU)
-        return;
-
-    ASSERT32FLAT();
-    u32 eax, ebx, ecx, cpuid_features;
-    cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
-    if (eax < 1 || !(cpuid_features & CPUID_APIC)) {
-        // No apic - only the main cpu is present.
-        dprintf(1, "No apic - only the main cpu is present.\n");
-        CountCPUs= 1;
-        MaxCountCPUs = 1;
-        return;
-    }
-
-    // mark the BSP initial APIC ID as found, too:
-    u8 apic_id = ebx>>24;
-    FoundAPICIDs[apic_id/32] |= (1 << (apic_id % 32));
-
-    // Init the counter.
-    writel(&CountCPUs, 1);
-
-    // Setup jump trampoline to counter code.
-    u64 old = *(u64*)BUILD_AP_BOOT_ADDR;
-    // ljmpw $SEG_BIOS, $(smp_ap_boot_code - BUILD_BIOS_ADDR)
-    u64 new = (0xea | ((u64)SEG_BIOS<<24)
-               | (((u32)smp_ap_boot_code - BUILD_BIOS_ADDR) << 8));
-    *(u64*)BUILD_AP_BOOT_ADDR = new;
-
-    // enable local APIC
-    u32 val = readl(APIC_SVR);
-    writel(APIC_SVR, val | APIC_ENABLED);
-
-    /* Set LINT0 as Ext_INT, level triggered */
-    writel(APIC_LINT0, 0x8700);
-
-    /* Set LINT1 as NMI, level triggered */
-    writel(APIC_LINT1, 0x8400);
-
-    // broadcast SIPI
-    barrier();
-    writel(APIC_ICR_LOW, 0x000C4500);
-    u32 sipi_vector = BUILD_AP_BOOT_ADDR >> 12;
-    writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
-
-    // Wait for other CPUs to process the SIPI.
-    u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT);
-    while (cmos_smp_count + 1 != readl(&CountCPUs))
-        yield();
-
-    // Restore memory.
-    *(u64*)BUILD_AP_BOOT_ADDR = old;
-
-    MaxCountCPUs = romfile_loadint("etc/max-cpus", 0);
-    if (!MaxCountCPUs || MaxCountCPUs < CountCPUs)
-        MaxCountCPUs = CountCPUs;
-
-    dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", readl(&CountCPUs),
-        MaxCountCPUs);
-}
diff --git a/src/ssdt-misc.dsl b/src/ssdt-misc.dsl
deleted file mode 100644 (file)
index acc850e..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
-
-DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
-{
-
-/****************************************************************
- * PCI memory ranges
- ****************************************************************/
-
-    Scope(\) {
-       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
-       Name(P0S, 0x12345678)
-       ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
-       Name(P0E, 0x12345678)
-       ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
-       Name(P1V, 0x12)
-       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start
-       Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end
-       Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-       ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
-       Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
-    }
-
-
-/****************************************************************
- * Suspend
- ****************************************************************/
-
-    Scope(\) {
-    /*
-     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
-     * must match piix4 emulation.
-     */
-
-        ACPI_EXTRACT_NAME_STRING acpi_s3_name
-        Name(_S3, Package(0x04) {
-            One,  /* PM1a_CNT.SLP_TYP */
-            One,  /* PM1b_CNT.SLP_TYP */
-            Zero,  /* reserved */
-            Zero   /* reserved */
-        })
-        ACPI_EXTRACT_NAME_STRING acpi_s4_name
-        ACPI_EXTRACT_PKG_START acpi_s4_pkg
-        Name(_S4, Package(0x04) {
-            0x2,  /* PM1a_CNT.SLP_TYP */
-            0x2,  /* PM1b_CNT.SLP_TYP */
-            Zero,  /* reserved */
-            Zero   /* reserved */
-        })
-        Name(_S5, Package(0x04) {
-            Zero,  /* PM1a_CNT.SLP_TYP */
-            Zero,  /* PM1b_CNT.SLP_TYP */
-            Zero,  /* reserved */
-            Zero   /* reserved */
-        })
-    }
-
-    External(\_SB.PCI0, DeviceObj)
-    External(\_SB.PCI0.ISA, DeviceObj)
-
-    Scope(\_SB.PCI0.ISA) {
-        Device(PEVT) {
-            Name(_HID, "QEMU0001")
-            /* PEST will be patched to be Zero if no such device */
-            ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest
-            Name(PEST, 0xFFFF)
-            OperationRegion(PEOR, SystemIO, PEST, 0x01)
-            Field(PEOR, ByteAcc, NoLock, Preserve) {
-                PEPT,   8,
-            }
-
-            Method(_STA, 0, NotSerialized) {
-                Store(PEST, Local0)
-                If (LEqual(Local0, Zero)) {
-                    Return (0x00)
-                } Else {
-                    Return (0x0F)
-                }
-            }
-
-            Method(RDPT, 0, NotSerialized) {
-                Store(PEPT, Local0)
-                Return (Local0)
-            }
-
-            Method(WRPT, 1, NotSerialized) {
-                Store(Arg0, PEPT)
-            }
-
-            Name(_CRS, ResourceTemplate() {
-                IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
-            })
-
-            CreateWordField(_CRS, IO._MIN, IOMN)
-            CreateWordField(_CRS, IO._MAX, IOMX)
-
-            Method(_INI, 0, NotSerialized) {
-                Store(PEST, IOMN)
-                Store(PEST, IOMX)
-            }
-        }
-    }
-}
diff --git a/src/ssdt-pcihp.dsl b/src/ssdt-pcihp.dsl
deleted file mode 100644 (file)
index 67e485f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml
-
-DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
-{
-
-/****************************************************************
- * PCI hotplug
- ****************************************************************/
-
-    /* Objects supplied by DSDT */
-    External(\_SB.PCI0, DeviceObj)
-    External(\_SB.PCI0.PCEJ, MethodObj)
-
-    Scope(\_SB.PCI0) {
-
-        /* Bulk generated PCI hotplug devices */
-        ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start
-        ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end
-        ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name
-
-        // Method _EJ0 can be patched by BIOS to EJ0_
-        // at runtime, if the slot is detected to not support hotplug.
-        // Extract the offset of the address dword and the
-        // _EJ0 name to allow this patching.
-        Device(SAA) {
-            ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id
-            Name(_SUN, 0xAA)
-            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr
-            Name(_ADR, 0xAA0000)
-            ACPI_EXTRACT_METHOD_STRING ssdt_pcihp_ej0
-            Method(_EJ0, 1) {
-                Return (PCEJ(_SUN))
-            }
-        }
-    }
-}
diff --git a/src/ssdt-proc.dsl b/src/ssdt-proc.dsl
deleted file mode 100644 (file)
index 407d61e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This file is the basis for the ssdt table generated in src/acpi.c.
- * It defines the contents of the per-cpu Processor() object.  At
- * runtime, a dynamically generated SSDT will contain one copy of this
- * AML snippet for every possible cpu in the system.  The objects will
- * be placed in the \_SB_ namespace.
- *
- * In addition to the aml code generated from this file, the
- * src/acpi.c file creates a NTFY method with an entry for each cpu:
- *     Method(NTFY, 2) {
- *         If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) }
- *         If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) }
- *         ...
- *     }
- * and a CPON array with the list of active and inactive cpus:
- *     Name(CPON, Package() { One, One, ..., Zero, Zero, ... })
- */
-
-ACPI_EXTRACT_ALL_CODE ssdp_proc_aml
-
-DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1)
-{
-    ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start
-    ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end
-    ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name
-    Processor(CPAA, 0xAA, 0x0000b010, 0x06) {
-        ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id
-        Name(ID, 0xAA)
-/*
- * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update
- * CPAA and 0xAA with the appropriate CPU id (see
- * SD_OFFSET_CPUHEX/CPUID1/CPUID2).  Don't change the above without
- * also updating the C code.
- */
-        Name(_HID, "ACPI0007")
-        External(CPMA, MethodObj)
-        External(CPST, MethodObj)
-        External(CPEJ, MethodObj)
-        Method(_MAT, 0) {
-            Return (CPMA(ID))
-        }
-        Method(_STA, 0) {
-            Return (CPST(ID))
-        }
-        Method(_EJ0, 1, NotSerialized) {
-            CPEJ(ID, Arg0)
-        }
-    }
-}
index 9b1b7741f6b3c64a22b9e55214f75b37421965e1..f2a1671b87cae422e91822da34919b9def5b91cd 100644 (file)
@@ -307,27 +307,27 @@ void handle_1553(struct bregs *regs);
 void handle_1ab1(struct bregs *regs);
 void bios32_init(void);
 
-// shadow.c
+// fw/shadow.c
 void make_bios_writable(void);
 void make_bios_readonly(void);
 void qemu_prep_reset(void);
 
-// pciinit.c
+// fw/pciinit.c
 extern const u8 pci_irqs[4];
 void pci_setup(void);
 
-// smm.c
+// fw/smm.c
 void smm_device_setup(void);
 void smm_setup(void);
 
-// smp.c
+// fw/smp.c
 extern u32 CountCPUs;
 extern u32 MaxCountCPUs;
 void wrmsr_smp(u32 index, u64 val);
 void smp_setup(void);
 int apic_id_is_present(u8 apic_id);
 
-// coreboot.c
+// fw/coreboot.c
 extern const char *CBvendor, *CBpart;
 struct cbfs_file;
 void debug_cbmem(char c);
@@ -337,7 +337,7 @@ void cbfs_payload_setup(void);
 void coreboot_preinit(void);
 void coreboot_cbfs_init(void);
 
-// biostable.c
+// fw/biostable.c
 void copy_smbios(void *pos);
 void copy_table(void *pos);
 
@@ -431,7 +431,7 @@ static inline void free(void *data) {
     pmm_free(data);
 }
 
-// mtrr.c
+// fw/mtrr.c
 void mtrr_setup(void);
 
 // romfile.c
diff --git a/src/xen.c b/src/xen.c
deleted file mode 100644 (file)
index 5dfee9e..0000000
--- a/src/xen.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// Xen HVM support
-//
-// Copyright (C) 2011 Citrix Systems.
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "config.h"
-#include "xen.h"
-#include "paravirt.h" // PlatformRunningOn
-#include "memmap.h" // add_e820
-#include "types.h" // ASM32FLAT
-#include "util.h" // copy_acpi_rsdp
-#include "acpi.h" // find_acpi_features
-
-#define INFO_PHYSICAL_ADDRESS 0x00001000
-
-u32 xen_cpuid_base = 0;
-unsigned long xen_hypercall_page = 0;
-
-struct xen_seabios_info {
-    char signature[14]; /* XenHVMSeaBIOS\0 */
-    u8 length;     /* Length of this struct */
-    u8 checksum;   /* Set such that the sum over bytes 0..length == 0 */
-    /*
-     * Physical address of an array of tables_nr elements.
-     *
-     * Each element is a 32 bit value contianing the physical address
-     * of a BIOS table.
-     */
-    u32 tables;
-    u32 tables_nr;
-    /*
-     * Physical address of the e820 table, contains e820_nr entries.
-     */
-    u32 e820;
-    u32 e820_nr;
-} PACKED;
-
-static void validate_info(struct xen_seabios_info *t)
-{
-    if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) )
-        panic("Bad Xen info signature\n");
-
-    if ( t->length < sizeof(struct xen_seabios_info) )
-        panic("Bad Xen info length\n");
-
-    if (checksum(t, t->length) != 0)
-        panic("Bad Xen info checksum\n");
-}
-
-void xen_preinit(void)
-{
-    u32 base, eax, ebx, ecx, edx;
-    char signature[13];
-
-    if (!CONFIG_XEN)
-        return;
-
-    for (base = 0x40000000; base < 0x40010000; base += 0x100) {
-        cpuid(base, &eax, &ebx, &ecx, &edx);
-        memcpy(signature + 0, &ebx, 4);
-        memcpy(signature + 4, &ecx, 4);
-        memcpy(signature + 8, &edx, 4);
-        signature[12] = 0;
-
-        dprintf(9, "Found hypervisor signature \"%s\" at %x\n",
-                signature, base);
-        if (strcmp(signature, "XenVMMXenVMM") == 0) {
-            /* Set debug_io_port first, so the following messages work. */
-            DebugOutputPort = 0xe9;
-            dprintf(1, "SeaBIOS (version %s)\n\n", VERSION);
-            dprintf(1, "Found Xen hypervisor signature at %x\n", base);
-            if ((eax - base) < 2)
-                panic("Insufficient Xen cpuid leaves. eax=%x at base %x\n",
-                      eax, base);
-            xen_cpuid_base = base;
-            break;
-        }
-    }
-    if (!xen_cpuid_base) {
-        dprintf(1, "No Xen hypervisor found.\n");
-        return;
-    }
-    PlatformRunningOn = PF_QEMU|PF_XEN;
-}
-
-static int hypercall_xen_version( int cmd, void *arg)
-{
-    return _hypercall2(int, xen_version, cmd, arg);
-}
-
-/* Fill in hypercall transfer pages. */
-void xen_hypercall_setup(void)
-{
-    u32 eax, ebx, ecx, edx;
-    xen_extraversion_t extraversion;
-    unsigned long i;
-
-    if (!runningOnXen())
-        return;
-
-    cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx);
-
-    xen_hypercall_page = (unsigned long)memalign_high(PAGE_SIZE, eax*PAGE_SIZE);
-    if (!xen_hypercall_page)
-        panic("unable to allocate Xen hypercall page\n");
-
-    dprintf(1, "Allocated Xen hypercall page at %lx\n", xen_hypercall_page);
-    for ( i = 0; i < eax; i++ )
-        wrmsr(ebx, xen_hypercall_page + (i << 12) + i);
-
-    /* Print version information. */
-    cpuid(xen_cpuid_base + 1, &eax, &ebx, &ecx, &edx);
-    hypercall_xen_version(XENVER_extraversion, extraversion);
-    dprintf(1, "Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion);
-}
-
-void xen_biostable_setup(void)
-{
-    struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS;
-    void **tables = (void*)info->tables;
-    int i;
-
-    dprintf(1, "xen: copy BIOS tables...\n");
-    for (i=0; i<info->tables_nr; i++)
-        copy_table(tables[i]);
-
-    find_acpi_features();
-}
-
-void xen_ramsize_preinit(void)
-{
-    int i;
-    struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS;
-    struct e820entry *e820 = (struct e820entry *)info->e820;
-    validate_info(info);
-
-    dprintf(1, "xen: copy e820...\n");
-
-    for (i = 0; i < info->e820_nr; i++) {
-        struct e820entry *e = &e820[i];
-        add_e820(e->start, e->size, e->type);
-    }
-}
diff --git a/src/xen.h b/src/xen.h
deleted file mode 100644 (file)
index f00f840..0000000
--- a/src/xen.h
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef __XEN_H
-#define __XEN_H
-
-void xen_preinit(void);
-void xen_ramsize_preinit(void);
-void xen_hypercall_setup(void);
-void xen_biostable_setup(void);
-
-extern unsigned long xen_hypercall_page;
-
-#define _hypercall0(type, name)                                         \
-({                                                                      \
-    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
-    long __res;                                                         \
-    asm volatile (                                                      \
-        "call *%%eax"                                                   \
-        : "=a" (__res)                                                  \
-        : "0" (__hentry)                                                \
-        : "memory" );                                                   \
-    (type)__res;                                                        \
-})
-
-#define _hypercall1(type, name, a1)                                     \
-({                                                                      \
-    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
-    long __res, __ign1;                                                 \
-    asm volatile (                                                      \
-        "call *%%eax"                                                   \
-        : "=a" (__res), "=b" (__ign1)                                   \
-        : "0" (__hentry), "1" ((long)(a1))                              \
-        : "memory" );                                                   \
-    (type)__res;                                                        \
-})
-
-#define _hypercall2(type, name, a1, a2)                                 \
-({                                                                      \
-    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
-    long __res, __ign1, __ign2;                                         \
-    asm volatile (                                                      \
-        "call *%%eax"                                                   \
-        : "=a" (__res), "=b" (__ign1), "=c" (__ign2)                    \
-        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2))            \
-        : "memory" );                                                   \
-    (type)__res;                                                        \
-})
-
-#define _hypercall3(type, name, a1, a2, a3)                             \
-({                                                                      \
-    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
-    long __res, __ign1, __ign2, __ign3;                                 \
-    asm volatile (                                                      \
-        "call *%%eax"                                                   \
-        : "=a" (__res), "=b" (__ign1), "=c" (__ign2),                   \
-          "=d" (__ign3)                                                 \
-        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2)),           \
-          "3" ((long)(a3))                                              \
-        : "memory" );                                                   \
-    (type)__res;                                                        \
-})
-
-#define _hypercall4(type, name, a1, a2, a3, a4)                         \
-({                                                                      \
-    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
-    long __res, __ign1, __ign2, __ign3, __ign4;                         \
-    asm volatile (                                                      \
-        "call *%%eax"                                                   \
-        : "=a" (__res), "=b" (__ign1), "=c" (__ign2),                   \
-          "=d" (__ign3), "=S" (__ign4)                                  \
-        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2)),           \
-          "3" ((long)(a3)), "4" ((long)(a4))                            \
-        : "memory" );                                                   \
-    (type)__res;                                                        \
-})
-
-#define _hypercall5(type, name, a1, a2, a3, a4, a5)                     \
-({                                                                      \
-    unsigned long __hentry = xen_hypercall_page+__HYPERVISOR_##name*32; \
-    long __res, __ign1, __ign2, __ign3, __ign4, __ign5;                 \
-    asm volatile (                                                      \
-        "call *%%eax"                                                   \
-        : "=a" (__res), "=b" (__ign1), "=c" (__ign2),                   \
-          "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)                   \
-        : "0" (__hentry), "1" ((long)(a1)), "2" ((long)(a2)),           \
-          "3" ((long)(a3)), "4" ((long)(a4)),                           \
-          "5" ((long)(a5))                                              \
-        : "memory" );                                                   \
-    (type)__res;                                                        \
-})
-
-/******************************************************************************
- *
- * The following interface definitions are taken from Xen and have the
- * following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/* xen.h */
-
-#define __HYPERVISOR_xen_version          17
-
-/* version.h */
-
-/* arg == xen_extraversion_t. */
-#define XENVER_extraversion 1
-typedef char xen_extraversion_t[16];
-#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))
-
-#endif