--- //depot/vendor/freebsd/src/usr.sbin/bhyve/acpi.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/acpi.c @@ -57,6 +57,7 @@ #include #include +#include #include #include #include @@ -67,6 +68,7 @@ #include "bhyverun.h" #include "acpi.h" +#include "pci_emul.h" /* * Define the base address of the ACPI tables, and the offsets to @@ -102,6 +100,13 @@ 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 @@ 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(" })"); - 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"); + pci_write_dsdt(); - 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"); + 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, "\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); --- //depot/vendor/freebsd/src/usr.sbin/bhyve/acpi.h +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/acpi.h @@ -29,19 +29,25 @@ #ifndef _ACPI_H_ #define _ACPI_H_ #define SCI_INT 9 #define SMI_CMD 0xb2 #define BHYVE_ACPI_ENABLE 0xa0 #define BHYVE_ACPI_DISABLE 0xa1 #define PM1A_EVT_ADDR 0x400 #define PM1A_CNT_ADDR 0x404 #define IO_PMTMR 0x408 /* 4-byte i/o port for the timer */ 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_ */ --- //depot/vendor/freebsd/src/usr.sbin/bhyve/atpic.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/atpic.c @@ -35,7 +35,9 @@ #include #include +#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 + 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); --- //depot/vendor/freebsd/src/usr.sbin/bhyve/pci_emul.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/pci_emul.c @@ -44,6 +44,7 @@ #include #include +#include "acpi.h" #include "bhyverun.h" #include "inout.h" #include "legacy_irq.h" @@ -93,6 +94,7 @@ 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 +999,6 @@ int init_pci(struct vmctx *ctx) { - struct mem_range memp; struct pci_devemu *pde; struct slotinfo *si; size_t lowmem; @@ -1035,19 +1036,100 @@ 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) { --- //depot/vendor/freebsd/src/usr.sbin/bhyve/pci_emul.h +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/pci_emul.h @@ -36,6 +36,7 @@ #include #include +#include #define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */ #define PCIY_RESERVED 0x00 @@ -51,6 +52,9 @@ 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 +217,7 @@ 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) --- //depot/vendor/freebsd/src/usr.sbin/bhyve/pci_lpc.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/pci_lpc.c @@ -34,16 +34,22 @@ #include #include +#include #include #include #include #include +#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 +58,7 @@ 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 +171,92 @@ 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 +298,7 @@ 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 }; --- //depot/vendor/freebsd/src/usr.sbin/bhyve/pci_lpc.h +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/pci_lpc.h @@ -29,6 +29,44 @@ #ifndef _LPC_H_ #define _LPC_H_ +#include +#include +#include + +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 --- //depot/vendor/freebsd/src/usr.sbin/bhyve/pit_8254.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/pit_8254.c @@ -42,9 +42,11 @@ #include +#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_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); --- //depot/vendor/freebsd/src/usr.sbin/bhyve/pm.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/pm.c @@ -29,20 +29,21 @@ __FBSDID("$FreeBSD: head/usr.sbin/bhyve/pm.c 259826 2013-12-24 16:14:19Z jhb $"); #include #include #include #include #include #include #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; static sig_t old_power_handler; /* * Reset Control register at I/O port 0xcf9. Bit 2 forces a system @@ -137,41 +250,43 @@ 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 * * This write-only register is used to enable and disable ACPI. */ static int smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, uint32_t *eax, void *arg) { assert(!in); if (bytes != 1) return (-1); pthread_mutex_lock(&pm_lock); switch (*eax) { case BHYVE_ACPI_ENABLE: pm1_control |= PM1_SCI_EN; if (power_button == NULL) { power_button = mevent_add(SIGTERM, EVF_SIGNAL, power_button_handler, ctx); old_power_handler = signal(SIGTERM, SIG_IGN); } break; case BHYVE_ACPI_DISABLE: pm1_control &= ~PM1_SCI_EN; if (power_button != NULL) { mevent_delete(power_button); power_button = NULL; signal(SIGTERM, old_power_handler); } break; } pthread_mutex_unlock(&pm_lock); return (0); } INOUT_PORT(smi_cmd, SMI_CMD, IOPORT_F_OUT, smi_cmd_handler); +SYSRES_IO(SMI_CMD, 1); --- //depot/vendor/freebsd/src/usr.sbin/bhyve/rtc.c +++ //depot/user/jhb/bhyve/usr.sbin/bhyve/rtc.c @@ -40,7 +40,9 @@ #include #include +#include "acpi.h" #include "inout.h" +#include "pci_lpc.h" #include "rtc.h" #define IO_RTC 0x70 @@ -358,3 +360,24 @@ 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);