Author: jhb
Date: Thu Jan  2 21:26:59 2014
New Revision: 260206
URL: http://svnweb.freebsd.org/changeset/base/260206

Log:
  Rework the DSDT generation code a bit to generate more accurate info about
  LPC devices.  Among other things, the LPC serial ports now appear as
  ACPI devices.
  - Move the info for the top-level PCI bus into the PCI emulation code and
    add ResourceProducer entries for the memory ranges decoded by the bus
    for memory BARs.
  - Add a framework to allow each PCI emulation driver to optionally write
    an entry into the DSDT under the \_SB_.PCI0 namespace.  The LPC driver
    uses this to write a node for the LPC bus (\_SB_.PCI0.ISA).
  - Add a linker set to allow any LPC devices to write entries into the
    DSDT below the LPC node.
  - Move the existing DSDT block for the RTC to the RTC driver.
  - Add DSDT nodes for the AT PIC, the 8254 ISA timer, and the LPC UART
    devices.
  - Add a "SuperIO" device under the LPC node to claim "system resources"
    aling with a linker set to allow various drivers to add IO or memory
    ranges that should be claimed as a system resource.
  - Add system resource entries for the extended RTC IO range, the registers
    used for ACPI power management, the ELCR, PCI interrupt routing register,
    and post data register.
  - Add various helper routines for generating DSDT entries.
  
  Reviewed by:  neel (earlier version)

Modified:
  head/usr.sbin/bhyve/acpi.c
  head/usr.sbin/bhyve/acpi.h
  head/usr.sbin/bhyve/atpic.c
  head/usr.sbin/bhyve/elcr.c
  head/usr.sbin/bhyve/pci_emul.c
  head/usr.sbin/bhyve/pci_emul.h
  head/usr.sbin/bhyve/pci_lpc.c
  head/usr.sbin/bhyve/pci_lpc.h
  head/usr.sbin/bhyve/pit_8254.c
  head/usr.sbin/bhyve/pm.c
  head/usr.sbin/bhyve/post.c
  head/usr.sbin/bhyve/rtc.c

Modified: head/usr.sbin/bhyve/acpi.c
==============================================================================
--- head/usr.sbin/bhyve/acpi.c  Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/acpi.c  Thu Jan  2 21:26:59 2014        (r260206)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/stat.h>
 
 #include <paths.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -67,6 +68,7 @@ __FBSDID("$FreeBSD$");
 
 #include "bhyverun.h"
 #include "acpi.h"
+#include "pci_emul.h"
 
 /*
  * Define the base address of the ACPI tables, and the offsets to
@@ -98,6 +100,13 @@ static uint32_t hpet_capabilities;
 static char basl_template[MAXPATHLEN];
 static char basl_stemplate[MAXPATHLEN];
 
+/*
+ * State for dsdt_line(), dsdt_indent(), and dsdt_unindent().
+ */
+static FILE *dsdt_fp;
+static int dsdt_indent_level;
+static int dsdt_error;
+
 struct basl_fio {
        int     fd;
        FILE    *fp;
@@ -606,119 +615,122 @@ err_exit:
        return (errno);
 }
 
+/*
+ * Helper routines for writing to the DSDT from other modules.
+ */
+void
+dsdt_line(const char *fmt, ...)
+{
+       va_list ap;
+       int err;
+
+       if (dsdt_error != 0)
+               return;
+
+       if (strcmp(fmt, "") != 0) {
+               if (dsdt_indent_level != 0)
+                       EFPRINTF(dsdt_fp, "%*c", dsdt_indent_level * 2, ' ');
+               va_start(ap, fmt);
+               if (vfprintf(dsdt_fp, fmt, ap) < 0)
+                       goto err_exit;
+               va_end(ap);
+       }
+       EFPRINTF(dsdt_fp, "\n");
+       return;
+
+err_exit:
+       dsdt_error = errno;
+}
+
+void
+dsdt_indent(int levels)
+{
+
+       dsdt_indent_level += levels;
+       assert(dsdt_indent_level >= 0);
+}
+
+void
+dsdt_unindent(int levels)
+{
+
+       assert(dsdt_indent_level >= levels);
+       dsdt_indent_level -= levels;
+}
+
+void
+dsdt_fixed_ioport(uint16_t iobase, uint16_t length)
+{
+
+       dsdt_line("IO (Decode16,");
+       dsdt_line("  0x%04X,             // Range Minimum", iobase);
+       dsdt_line("  0x%04X,             // Range Maximum", iobase);
+       dsdt_line("  0x01,               // Alignment");
+       dsdt_line("  0x%02X,               // Length", length);
+       dsdt_line("  )");
+}
+
+void
+dsdt_fixed_irq(uint8_t irq)
+{
+
+       dsdt_line("IRQNoFlags ()");
+       dsdt_line("  {%d}", irq);
+}
+
+void
+dsdt_fixed_mem32(uint32_t base, uint32_t length)
+{
+
+       dsdt_line("Memory32Fixed (ReadWrite,");
+       dsdt_line("  0x%08X,         // Address Base", base);
+       dsdt_line("  0x%08X,         // Address Length", length);
+       dsdt_line("  )");
+}
+
 static int
 basl_fwrite_dsdt(FILE *fp)
 {
        int err;
 
        err = 0;
+       dsdt_fp = fp;
+       dsdt_error = 0;
+       dsdt_indent_level = 0;
+
+       dsdt_line("/*");
+       dsdt_line(" * bhyve DSDT template");
+       dsdt_line(" */");
+       dsdt_line("DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2,"
+                "\"BHYVE \", \"BVDSDT  \", 0x00000001)");
+       dsdt_line("{");
+       dsdt_line("  Name (_S5, Package (0x02)");
+       dsdt_line("  {");
+       dsdt_line("      0x05,");
+       dsdt_line("      Zero,");
+       dsdt_line("  })");
+
+       pci_write_dsdt();
+
+       dsdt_line("");
+       dsdt_line("  Scope (_SB.PCI0)");
+       dsdt_line("  {");
+       dsdt_line("    Device (HPET)");
+       dsdt_line("    {");
+       dsdt_line("      Name (_HID, EISAID(\"PNP0103\"))");
+       dsdt_line("      Name (_UID, 0)");
+       dsdt_line("      Name (_CRS, ResourceTemplate ()");
+       dsdt_line("      {");
+       dsdt_indent(4);
+       dsdt_fixed_mem32(0xFED00000, 0x400);
+       dsdt_unindent(4);
+       dsdt_line("      })");
+       dsdt_line("    }");
+       dsdt_line("  }");
+       dsdt_line("}");
 
-       EFPRINTF(fp, "/*\n");
-       EFPRINTF(fp, " * bhyve DSDT template\n");
-       EFPRINTF(fp, " */\n");
-       EFPRINTF(fp, "DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2,"
-                "\"BHYVE \", \"BVDSDT  \", 0x00000001)\n");
-       EFPRINTF(fp, "{\n");
-       EFPRINTF(fp, "  Name (_S5, Package (0x02)\n");
-       EFPRINTF(fp, "  {\n");
-       EFPRINTF(fp, "      0x05,\n");
-       EFPRINTF(fp, "      Zero,\n");
-       EFPRINTF(fp, "  })\n");
-       EFPRINTF(fp, "  Scope (_SB)\n");
-       EFPRINTF(fp, "  {\n");
-       EFPRINTF(fp, "    Device (PCI0)\n");
-       EFPRINTF(fp, "    {\n");
-       EFPRINTF(fp, "      Name (_HID, EisaId (\"PNP0A03\"))\n");
-       EFPRINTF(fp, "      Name (_ADR, Zero)\n");
-       EFPRINTF(fp, "      Name (_UID, One)\n");
-       EFPRINTF(fp, "      Name (_CRS, ResourceTemplate ()\n");
-       EFPRINTF(fp, "      {\n");
-       EFPRINTF(fp, "        WordBusNumber (ResourceProducer, MinFixed,"
-                "MaxFixed, PosDecode,\n");
-       EFPRINTF(fp, "            0x0000,             // Granularity\n");
-       EFPRINTF(fp, "            0x0000,             // Range Minimum\n");
-       EFPRINTF(fp, "            0x00FF,             // Range Maximum\n");
-       EFPRINTF(fp, "            0x0000,             // Transl Offset\n");
-       EFPRINTF(fp, "            0x0100,             // Length\n");
-       EFPRINTF(fp, "            ,, )\n");
-       EFPRINTF(fp, "         IO (Decode16,\n");
-       EFPRINTF(fp, "            0x0CF8,             // Range Minimum\n");
-       EFPRINTF(fp, "            0x0CF8,             // Range Maximum\n");
-       EFPRINTF(fp, "            0x01,               // Alignment\n");
-       EFPRINTF(fp, "            0x08,               // Length\n");
-       EFPRINTF(fp, "            )\n");
-       EFPRINTF(fp, "         WordIO (ResourceProducer, MinFixed, MaxFixed,"
-                "PosDecode, EntireRange,\n");
-       EFPRINTF(fp, "            0x0000,             // Granularity\n");
-       EFPRINTF(fp, "            0x0000,             // Range Minimum\n");
-       EFPRINTF(fp, "            0x0CF7,             // Range Maximum\n");
-       EFPRINTF(fp, "            0x0000,             // Transl Offset\n");
-       EFPRINTF(fp, "            0x0CF8,             // Length\n");
-       EFPRINTF(fp, "            ,, , TypeStatic)\n");
-       EFPRINTF(fp, "         WordIO (ResourceProducer, MinFixed, MaxFixed,"
-                "PosDecode, EntireRange,\n");
-       EFPRINTF(fp, "            0x0000,             // Granularity\n");
-       EFPRINTF(fp, "            0x0D00,             // Range Minimum\n");
-       EFPRINTF(fp, "            0xFFFF,             // Range Maximum\n");
-       EFPRINTF(fp, "            0x0000,             // Transl Offset\n");
-       EFPRINTF(fp, "            0xF300,             // Length\n");
-       EFPRINTF(fp, "             ,, , TypeStatic)\n");
-       EFPRINTF(fp, "          })\n");
-       EFPRINTF(fp, "     }\n");
-       EFPRINTF(fp, "  }\n");
-       EFPRINTF(fp, "\n");
-       EFPRINTF(fp, "  Scope (_SB.PCI0)\n");
-       EFPRINTF(fp, "  {\n");
-       EFPRINTF(fp, "    Device (ISA)\n");
-       EFPRINTF(fp, "    {\n");
-       EFPRINTF(fp, "      Name (_ADR, 0x00010000)\n");
-       EFPRINTF(fp, "      OperationRegion (P40C, PCI_Config, 0x60, 0x04)\n");
-       EFPRINTF(fp, "    }\n");
-
-       EFPRINTF(fp, "    Device (HPET)\n");
-       EFPRINTF(fp, "    {\n");
-       EFPRINTF(fp, "      Name (_HID, EISAID(\"PNP0103\"))\n");
-       EFPRINTF(fp, "      Name (_UID, 0)\n");
-       EFPRINTF(fp, "      Name (_CRS, ResourceTemplate ()\n");
-       EFPRINTF(fp, "      {\n");
-       EFPRINTF(fp, "        DWordMemory (ResourceConsumer, PosDecode, "
-                "MinFixed, MaxFixed, NonCacheable, ReadWrite,\n");
-       EFPRINTF(fp, "            0x00000000,\n");
-       EFPRINTF(fp, "            0xFED00000,\n");
-       EFPRINTF(fp, "            0xFED003FF,\n");
-       EFPRINTF(fp, "            0x00000000,\n");
-       EFPRINTF(fp, "            0x00000400\n");
-       EFPRINTF(fp, "            )\n");
-       EFPRINTF(fp, "      })\n");
-       EFPRINTF(fp, "    }\n");
-
-       EFPRINTF(fp, "  }\n");
-       EFPRINTF(fp, "\n");
-       EFPRINTF(fp, "  Scope (_SB.PCI0.ISA)\n");
-        EFPRINTF(fp, "  {\n");
-       EFPRINTF(fp, "    Device (RTC)\n");
-        EFPRINTF(fp, "    {\n");
-       EFPRINTF(fp, "      Name (_HID, EisaId (\"PNP0B00\"))\n");
-       EFPRINTF(fp, "      Name (_CRS, ResourceTemplate ()\n");
-       EFPRINTF(fp, "      {\n");
-       EFPRINTF(fp, "        IO (Decode16,\n");
-       EFPRINTF(fp, "            0x0070,             // Range Minimum\n");
-       EFPRINTF(fp, "            0x0070,             // Range Maximum\n");
-       EFPRINTF(fp, "            0x10,               // Alignment\n");
-       EFPRINTF(fp, "            0x02,               // Length\n");
-       EFPRINTF(fp, "            )\n");
-       EFPRINTF(fp, "        IRQNoFlags ()\n");
-       EFPRINTF(fp, "            {8}\n");
-       EFPRINTF(fp, "        IO (Decode16,\n");
-       EFPRINTF(fp, "            0x0072,             // Range Minimum\n");
-       EFPRINTF(fp, "            0x0072,             // Range Maximum\n");
-       EFPRINTF(fp, "            0x02,               // Alignment\n");
-       EFPRINTF(fp, "            0x06,               // Length\n");
-       EFPRINTF(fp, "            )\n");
-       EFPRINTF(fp, "      })\n");
-        EFPRINTF(fp, "    }\n");
-       EFPRINTF(fp, "  }\n");
-       EFPRINTF(fp, "}\n");
+       if (dsdt_error != 0)
+               return (dsdt_error);
 
        EFFLUSH(fp);
 

Modified: head/usr.sbin/bhyve/acpi.h
==============================================================================
--- head/usr.sbin/bhyve/acpi.h  Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/acpi.h  Thu Jan  2 21:26:59 2014        (r260206)
@@ -43,5 +43,11 @@
 struct vmctx;
 
 int    acpi_build(struct vmctx *ctx, int ncpu);
+void   dsdt_line(const char *fmt, ...);
+void   dsdt_fixed_ioport(uint16_t iobase, uint16_t length);
+void   dsdt_fixed_irq(uint8_t irq);
+void   dsdt_fixed_mem32(uint32_t base, uint32_t length);
+void   dsdt_indent(int levels);
+void   dsdt_unindent(int levels);
 
 #endif /* _ACPI_H_ */

Modified: head/usr.sbin/bhyve/atpic.c
==============================================================================
--- head/usr.sbin/bhyve/atpic.c Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/atpic.c Thu Jan  2 21:26:59 2014        (r260206)
@@ -35,7 +35,9 @@ __FBSDID("$FreeBSD$");
 #include <string.h>
 #include <assert.h>
 
+#include "acpi.h"
 #include "inout.h"
+#include "pci_lpc.h"
 
 #define        IO_ICU1         0x20
 #define        IO_ICU2         0xA0
@@ -65,3 +67,23 @@ INOUT_PORT(atpic, IO_ICU1, IOPORT_F_INOU
 INOUT_PORT(atpic, IO_ICU1 + ICU_IMR_OFFSET, IOPORT_F_INOUT, atpic_handler);
 INOUT_PORT(atpic, IO_ICU2, IOPORT_F_INOUT, atpic_handler);
 INOUT_PORT(atpic, IO_ICU2 + ICU_IMR_OFFSET, IOPORT_F_INOUT, atpic_handler);
+
+static void
+atpic_dsdt(void)
+{
+
+       dsdt_line("");
+       dsdt_line("Device (PIC)");
+       dsdt_line("{");
+       dsdt_line("  Name (_HID, EisaId (\"PNP0000\"))");
+       dsdt_line("  Name (_CRS, ResourceTemplate ()");
+       dsdt_line("  {");
+       dsdt_indent(2);
+       dsdt_fixed_ioport(IO_ICU1, 2);
+       dsdt_fixed_ioport(IO_ICU2, 2);
+       dsdt_fixed_irq(2);
+       dsdt_unindent(2);
+       dsdt_line("  })");
+       dsdt_line("}");
+}
+LPC_DSDT(atpic_dsdt);

Modified: head/usr.sbin/bhyve/elcr.c
==============================================================================
--- head/usr.sbin/bhyve/elcr.c  Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/elcr.c  Thu Jan  2 21:26:59 2014        (r260206)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 
 #include "inout.h"
+#include "pci_lpc.h"
 
 /*
  * EISA interrupt Level Control Register.
@@ -63,3 +64,4 @@ elcr_handler(struct vmctx *ctx, int vcpu
 }
 INOUT_PORT(elcr, ELCR_PORT + 0, IOPORT_F_INOUT, elcr_handler);
 INOUT_PORT(elcr, ELCR_PORT + 1, IOPORT_F_INOUT, elcr_handler);
+SYSRES_IO(ELCR_PORT, 2);

Modified: head/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.c      Thu Jan  2 18:50:52 2014        
(r260205)
+++ head/usr.sbin/bhyve/pci_emul.c      Thu Jan  2 21:26:59 2014        
(r260206)
@@ -44,11 +44,13 @@ __FBSDID("$FreeBSD$");
 #include <machine/vmm.h>
 #include <vmmapi.h>
 
+#include "acpi.h"
 #include "bhyverun.h"
 #include "inout.h"
 #include "legacy_irq.h"
 #include "mem.h"
 #include "pci_emul.h"
+#include "pci_lpc.h"
 
 #define CONF1_ADDR_PORT    0x0cf8
 #define CONF1_DATA_PORT    0x0cfc
@@ -93,6 +95,7 @@ static uint64_t pci_emul_membase64;
 static struct pci_devemu *pci_emul_finddev(char *name);
 
 static int pci_emul_devices;
+static struct mem_range pci_mem_hole;
 
 /*
  * I/O access
@@ -997,7 +1000,6 @@ pci_emul_fallback_handler(struct vmctx *
 int
 init_pci(struct vmctx *ctx)
 {
-       struct mem_range memp;
        struct pci_devemu *pde;
        struct slotinfo *si;
        size_t lowmem;
@@ -1035,19 +1037,100 @@ init_pci(struct vmctx *ctx)
        error = vm_get_memory_seg(ctx, 0, &lowmem, NULL);
        assert(error == 0);
 
-       memset(&memp, 0, sizeof(struct mem_range));
-       memp.name = "PCI hole";
-       memp.flags = MEM_F_RW;
-       memp.base = lowmem;
-       memp.size = (4ULL * 1024 * 1024 * 1024) - lowmem;
-       memp.handler = pci_emul_fallback_handler;
+       memset(&pci_mem_hole, 0, sizeof(struct mem_range));
+       pci_mem_hole.name = "PCI hole";
+       pci_mem_hole.flags = MEM_F_RW;
+       pci_mem_hole.base = lowmem;
+       pci_mem_hole.size = (4ULL * 1024 * 1024 * 1024) - lowmem;
+       pci_mem_hole.handler = pci_emul_fallback_handler;
 
-       error = register_mem_fallback(&memp);
+       error = register_mem_fallback(&pci_mem_hole);
        assert(error == 0);
 
        return (0);
 }
 
+void
+pci_write_dsdt(void)
+{
+       struct pci_devinst *pi;
+       int slot, func;
+
+       dsdt_indent(1);
+       dsdt_line("Scope (_SB)");
+       dsdt_line("{");
+       dsdt_line("  Device (PCI0)");
+       dsdt_line("  {");
+       dsdt_line("    Name (_HID, EisaId (\"PNP0A03\"))");
+       dsdt_line("    Name (_ADR, Zero)");
+       dsdt_line("    Name (_CRS, ResourceTemplate ()");
+       dsdt_line("    {");
+       dsdt_line("      WordBusNumber (ResourceProducer, MinFixed, "
+           "MaxFixed, PosDecode,");
+       dsdt_line("        0x0000,             // Granularity");
+       dsdt_line("        0x0000,             // Range Minimum");
+       dsdt_line("        0x00FF,             // Range Maximum");
+       dsdt_line("        0x0000,             // Translation Offset");
+       dsdt_line("        0x0100,             // Length");
+       dsdt_line("        ,, )");
+       dsdt_indent(3);
+       dsdt_fixed_ioport(0xCF8, 8);
+       dsdt_unindent(3);
+       dsdt_line("      WordIO (ResourceProducer, MinFixed, MaxFixed, "
+           "PosDecode, EntireRange,");
+       dsdt_line("        0x0000,             // Granularity");
+       dsdt_line("        0x0000,             // Range Minimum");
+       dsdt_line("        0x0CF7,             // Range Maximum");
+       dsdt_line("        0x0000,             // Translation Offset");
+       dsdt_line("        0x0CF8,             // Length");
+       dsdt_line("        ,, , TypeStatic)");
+       dsdt_line("      WordIO (ResourceProducer, MinFixed, MaxFixed, "
+           "PosDecode, EntireRange,");
+       dsdt_line("        0x0000,             // Granularity");
+       dsdt_line("        0x0D00,             // Range Minimum");
+       dsdt_line("        0xFFFF,             // Range Maximum");
+       dsdt_line("        0x0000,             // Translation Offset");
+       dsdt_line("        0xF300,             // Length");
+       dsdt_line("        ,, , TypeStatic)");
+       dsdt_line("      DWordMemory (ResourceProducer, PosDecode, "
+           "MinFixed, MaxFixed, NonCacheable, ReadWrite,");
+       dsdt_line("        0x00000000,         // Granularity");
+       dsdt_line("        0x%08lX,         // Range Minimum\n",
+           pci_mem_hole.base);
+       dsdt_line("        0x%08X,         // Range Maximum\n",
+           PCI_EMUL_MEMLIMIT32 - 1);
+       dsdt_line("        0x00000000,         // Translation Offset");
+       dsdt_line("        0x%08lX,         // Length\n",
+           PCI_EMUL_MEMLIMIT32 - pci_mem_hole.base);
+       dsdt_line("        ,, , AddressRangeMemory, TypeStatic)");
+       dsdt_line("      QWordMemory (ResourceProducer, PosDecode, "
+           "MinFixed, MaxFixed, NonCacheable, ReadWrite,");
+       dsdt_line("        0x0000000000000000, // Granularity");
+       dsdt_line("        0x%016lX, // Range Minimum\n",
+           PCI_EMUL_MEMBASE64);
+       dsdt_line("        0x%016lX, // Range Maximum\n",
+           PCI_EMUL_MEMLIMIT64 - 1);
+       dsdt_line("        0x0000000000000000, // Translation Offset");
+       dsdt_line("        0x%016lX, // Length\n",
+           PCI_EMUL_MEMLIMIT64 - PCI_EMUL_MEMBASE64);
+       dsdt_line("        ,, , AddressRangeMemory, TypeStatic)");
+       dsdt_line("    })");
+
+       dsdt_indent(2);
+       for (slot = 0; slot < MAXSLOTS; slot++) {
+               for (func = 0; func < MAXFUNCS; func++) {
+                       pi = pci_slotinfo[slot][func].si_devi;
+                       if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL)
+                               pi->pi_d->pe_write_dsdt(pi);
+               }
+       }
+       dsdt_unindent(2);
+
+       dsdt_line("  }");
+       dsdt_line("}");
+       dsdt_unindent(1);
+}
+
 int
 pci_msi_enabled(struct pci_devinst *pi)
 {
@@ -1433,6 +1516,7 @@ pci_irq_port_handler(struct vmctx *ctx, 
 }
 INOUT_PORT(pci_irq, 0xC00, IOPORT_F_OUT, pci_irq_port_handler);
 INOUT_PORT(pci_irq, 0xC01, IOPORT_F_OUT, pci_irq_port_handler);
+SYSRES_IO(0xC00, 2);
 
 #define PCI_EMUL_TEST
 #ifdef PCI_EMUL_TEST

Modified: head/usr.sbin/bhyve/pci_emul.h
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.h      Thu Jan  2 18:50:52 2014        
(r260205)
+++ head/usr.sbin/bhyve/pci_emul.h      Thu Jan  2 21:26:59 2014        
(r260206)
@@ -51,6 +51,9 @@ struct pci_devemu {
        int       (*pe_init)(struct vmctx *, struct pci_devinst *,
                             char *opts);
 
+       /* ACPI DSDT enumeration */
+       void    (*pe_write_dsdt)(struct pci_devinst *);
+
        /* config space read/write callbacks */
        int     (*pe_cfgwrite)(struct vmctx *ctx, int vcpu,
                               struct pci_devinst *pi, int offset,
@@ -213,6 +216,7 @@ int pci_emul_add_msixcap(struct pci_devi
 int    pci_emul_msix_twrite(struct pci_devinst *pi, uint64_t offset, int size,
                             uint64_t value);
 uint64_t pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int 
size);
+void   pci_write_dsdt(void);
 
 static __inline void 
 pci_set_cfgdata8(struct pci_devinst *pi, int offset, uint8_t val)

Modified: head/usr.sbin/bhyve/pci_lpc.c
==============================================================================
--- head/usr.sbin/bhyve/pci_lpc.c       Thu Jan  2 18:50:52 2014        
(r260205)
+++ head/usr.sbin/bhyve/pci_lpc.c       Thu Jan  2 21:26:59 2014        
(r260206)
@@ -40,10 +40,15 @@ __FBSDID("$FreeBSD$");
 
 #include <vmmapi.h>
 
+#include "acpi.h"
 #include "inout.h"
 #include "pci_emul.h"
+#include "pci_lpc.h"
 #include "uart_emul.h"
 
+SET_DECLARE(lpc_dsdt_set, struct lpc_dsdt);
+SET_DECLARE(lpc_sysres_set, struct lpc_sysres);
+
 static struct pci_devinst *lpc_bridge;
 
 #define        LPC_UART_NUM    2
@@ -52,6 +57,7 @@ static struct lpc_uart_softc {
        const char *opts;
        int     iobase;
        int     irq;
+       int     enabled;
 } lpc_uart_softc[LPC_UART_NUM];
 
 static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2" };
@@ -164,12 +170,92 @@ lpc_init(void)
 
                error = register_inout(&iop);
                assert(error == 0);
+               sc->enabled = 1;
        }
 
        return (0);
 }
 
 static void
+pci_lpc_write_dsdt(struct pci_devinst *pi)
+{
+       struct lpc_dsdt **ldpp, *ldp;
+
+       dsdt_line("");
+       dsdt_line("Device (ISA)");
+       dsdt_line("{");
+       dsdt_line("  Name (_ADR, 0x%04X%04X)", pi->pi_slot, pi->pi_func);
+       dsdt_line("  OperationRegion (P40C, PCI_Config, 0x60, 0x04)");
+
+       dsdt_indent(1);
+       SET_FOREACH(ldpp, lpc_dsdt_set) {
+               ldp = *ldpp;
+               ldp->handler();
+       }
+       dsdt_unindent(1);
+
+       dsdt_line("}");
+}
+
+static void
+pci_lpc_sysres_dsdt(void)
+{
+       struct lpc_sysres **lspp, *lsp;
+
+       dsdt_line("");
+       dsdt_line("Device (SIO)");
+       dsdt_line("{");
+       dsdt_line("  Name (_HID, EisaId (\"PNP0C02\"))");
+       dsdt_line("  Name (_CRS, ResourceTemplate ()");
+       dsdt_line("  {");
+
+       dsdt_indent(2);
+       SET_FOREACH(lspp, lpc_sysres_set) {
+               lsp = *lspp;
+               switch (lsp->type) {
+               case LPC_SYSRES_IO:
+                       dsdt_fixed_ioport(lsp->base, lsp->length);
+                       break;
+               case LPC_SYSRES_MEM:
+                       dsdt_fixed_mem32(lsp->base, lsp->length);
+                       break;
+               }
+       }
+       dsdt_unindent(2);
+
+       dsdt_line("  })");
+       dsdt_line("}");
+}
+LPC_DSDT(pci_lpc_sysres_dsdt);
+
+static void
+pci_lpc_uart_dsdt(void)
+{
+       struct lpc_uart_softc *sc;
+       int unit;
+
+       for (unit = 0; unit < LPC_UART_NUM; unit++) {
+               sc = &lpc_uart_softc[unit];
+               if (!sc->enabled)
+                       continue;
+               dsdt_line("");
+               dsdt_line("Device (%s)", lpc_uart_names[unit]);
+               dsdt_line("{");
+               dsdt_line("  Name (_HID, EisaId (\"PNP0501\"))");
+               dsdt_line("  Name (_UID, %d)", unit + 1);
+               dsdt_line("  Name (_CRS, ResourceTemplate ()");
+               dsdt_line("  {");
+               dsdt_indent(2);
+               dsdt_fixed_ioport(sc->iobase, UART_IO_BAR_SIZE);
+               dsdt_fixed_irq(sc->irq);
+               dsdt_unindent(2);
+               dsdt_line("  })");
+               dsdt_line("}");
+       }
+}
+LPC_DSDT(pci_lpc_uart_dsdt);
+
+static void
 pci_lpc_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
               int baridx, uint64_t offset, int size, uint64_t value)
 {
@@ -211,6 +297,7 @@ pci_lpc_init(struct vmctx *ctx, struct p
 struct pci_devemu pci_de_lpc = {
        .pe_emu =       "lpc",
        .pe_init =      pci_lpc_init,
+       .pe_write_dsdt = pci_lpc_write_dsdt,
        .pe_barwrite =  pci_lpc_write,
        .pe_barread =   pci_lpc_read
 };

Modified: head/usr.sbin/bhyve/pci_lpc.h
==============================================================================
--- head/usr.sbin/bhyve/pci_lpc.h       Thu Jan  2 18:50:52 2014        
(r260205)
+++ head/usr.sbin/bhyve/pci_lpc.h       Thu Jan  2 21:26:59 2014        
(r260206)
@@ -29,6 +29,42 @@
 #ifndef _LPC_H_
 #define        _LPC_H_
 
+#include <sys/linker_set.h>
+
+typedef void (*lpc_write_dsdt_t)(void);
+
+struct lpc_dsdt {
+       lpc_write_dsdt_t handler;
+};
+
+#define        LPC_DSDT(handler)                                               
\
+       static struct lpc_dsdt __CONCAT(__lpc_dsdt, __LINE__) = {       \
+               (handler),                                              \
+       };                                                              \
+       DATA_SET(lpc_dsdt_set, __CONCAT(__lpc_dsdt, __LINE__))
+
+enum lpc_sysres_type {
+       LPC_SYSRES_IO,
+       LPC_SYSRES_MEM
+};
+
+struct lpc_sysres {
+       enum lpc_sysres_type type;
+       uint32_t base;
+       uint32_t length;
+};
+
+#define        LPC_SYSRES(type, base, length)                                  
\
+       static struct lpc_sysres __CONCAT(__lpc_sysres, __LINE__) = {   \
+               (type),                                                 \
+               (base),                                                 \
+               (length)                                                \
+       };                                                              \
+       DATA_SET(lpc_sysres_set, __CONCAT(__lpc_sysres, __LINE__))
+
+#define        SYSRES_IO(base, length)         LPC_SYSRES(LPC_SYSRES_IO, base, 
length)
+#define        SYSRES_MEM(base, length)        LPC_SYSRES(LPC_SYSRES_MEM, 
base, length)
+
 int    lpc_device_parse(const char *opt);
 
 #endif

Modified: head/usr.sbin/bhyve/pit_8254.c
==============================================================================
--- head/usr.sbin/bhyve/pit_8254.c      Thu Jan  2 18:50:52 2014        
(r260205)
+++ head/usr.sbin/bhyve/pit_8254.c      Thu Jan  2 21:26:59 2014        
(r260206)
@@ -42,9 +42,11 @@ __FBSDID("$FreeBSD$");
 
 #include <vmmapi.h>
 
+#include "acpi.h"
 #include "bhyverun.h"
 #include "inout.h"
 #include "mevent.h"
+#include "pci_lpc.h"
 #include "pit_8254.h"
 
 #define        TIMER_SEL_MASK          0xc0
@@ -268,3 +270,22 @@ INOUT_PORT(8254, TIMER_MODE, IOPORT_F_OU
 INOUT_PORT(8254, TIMER_CNTR0, IOPORT_F_INOUT, pit_8254_handler);
 INOUT_PORT(8254, TIMER_CNTR1, IOPORT_F_INOUT, pit_8254_handler);
 INOUT_PORT(8254, TIMER_CNTR2, IOPORT_F_INOUT, pit_8254_handler);
+
+static void
+pit_dsdt(void)
+{
+
+       dsdt_line("");
+       dsdt_line("Device (TIMR)");
+       dsdt_line("{");
+       dsdt_line("  Name (_HID, EisaId (\"PNP0100\"))");
+       dsdt_line("  Name (_CRS, ResourceTemplate ()");
+       dsdt_line("  {");
+       dsdt_indent(2);
+       dsdt_fixed_ioport(IO_TIMER1, 4);
+       dsdt_fixed_irq(0);
+       dsdt_unindent(2);
+       dsdt_line("  })");
+       dsdt_line("}");
+}
+LPC_DSDT(pit_dsdt);

Modified: head/usr.sbin/bhyve/pm.c
==============================================================================
--- head/usr.sbin/bhyve/pm.c    Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/pm.c    Thu Jan  2 21:26:59 2014        (r260206)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include "acpi.h"
 #include "inout.h"
 #include "mevent.h"
+#include "pci_lpc.h"
 
 static pthread_mutex_t pm_lock = PTHREAD_MUTEX_INITIALIZER;
 static struct mevent *power_button;
@@ -248,6 +249,7 @@ pm1_control_handler(struct vmctx *ctx, i
        return (0);
 }
 INOUT_PORT(pm1_control, PM1A_CNT_ADDR, IOPORT_F_INOUT, pm1_control_handler);
+SYSRES_IO(PM1A_EVT_ADDR, 8);
 
 /*
  * ACPI SMI Command Register
@@ -286,3 +288,4 @@ smi_cmd_handler(struct vmctx *ctx, int v
        return (0);
 }
 INOUT_PORT(smi_cmd, SMI_CMD, IOPORT_F_OUT, smi_cmd_handler);
+SYSRES_IO(SMI_CMD, 1);

Modified: head/usr.sbin/bhyve/post.c
==============================================================================
--- head/usr.sbin/bhyve/post.c  Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/post.c  Thu Jan  2 21:26:59 2014        (r260206)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <assert.h>
 
 #include "inout.h"
+#include "pci_lpc.h"
 
 static int
 post_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
@@ -49,3 +50,4 @@ post_data_handler(struct vmctx *ctx, int
 }
 
 INOUT_PORT(post, 0x84, IOPORT_F_IN, post_data_handler);
+SYSRES_IO(0x84, 1);

Modified: head/usr.sbin/bhyve/rtc.c
==============================================================================
--- head/usr.sbin/bhyve/rtc.c   Thu Jan  2 18:50:52 2014        (r260205)
+++ head/usr.sbin/bhyve/rtc.c   Thu Jan  2 21:26:59 2014        (r260206)
@@ -40,7 +40,9 @@ __FBSDID("$FreeBSD$");
 #include <machine/vmm.h>
 #include <vmmapi.h>
 
+#include "acpi.h"
 #include "inout.h"
+#include "pci_lpc.h"
 #include "rtc.h"
 
 #define        IO_RTC  0x70
@@ -358,3 +360,24 @@ rtc_init(struct vmctx *ctx)
 
 INOUT_PORT(rtc, IO_RTC, IOPORT_F_INOUT, rtc_addr_handler);
 INOUT_PORT(rtc, IO_RTC + 1, IOPORT_F_INOUT, rtc_data_handler);
+
+static void
+rtc_dsdt(void)
+{
+
+       dsdt_line("");
+       dsdt_line("Device (RTC)");
+       dsdt_line("{");
+       dsdt_line("  Name (_HID, EisaId (\"PNP0B00\"))");
+       dsdt_line("  Name (_CRS, ResourceTemplate ()");
+       dsdt_line("  {");
+       dsdt_indent(2);
+       dsdt_fixed_ioport(IO_RTC, 2);
+       dsdt_fixed_irq(8);
+       dsdt_unindent(2);
+       dsdt_line("  })");
+       dsdt_line("}");
+}
+LPC_DSDT(rtc_dsdt);
+
+SYSRES_IO(0x72, 6);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to