acpi.c revision 284899
172339Sabial/*- 272339Sabial * Copyright (c) 2012 NetApp, Inc. 372339Sabial * All rights reserved. 472339Sabial * 572339Sabial * Redistribution and use in source and binary forms, with or without 672339Sabial * modification, are permitted provided that the following conditions 772339Sabial * are met: 872339Sabial * 1. Redistributions of source code must retain the above copyright 972339Sabial * notice, this list of conditions and the following disclaimer. 1072339Sabial * 2. Redistributions in binary form must reproduce the above copyright 1172339Sabial * notice, this list of conditions and the following disclaimer in the 1272339Sabial * documentation and/or other materials provided with the distribution. 1372339Sabial * 1472339Sabial * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 1572339Sabial * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1672339Sabial * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1772339Sabial * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 1872339Sabial * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1972339Sabial * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2072339Sabial * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2172339Sabial * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2272339Sabial * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2372339Sabial * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2472339Sabial * SUCH DAMAGE. 2572339Sabial * 2672339Sabial * $FreeBSD: stable/10/usr.sbin/bhyve/acpi.c 284899 2015-06-28 01:21:55Z neel $ 2772339Sabial */ 2872339Sabial 2972339Sabial/* 3072339Sabial * bhyve ACPI table generator. 3172339Sabial * 3272339Sabial * Create the minimal set of ACPI tables required to boot FreeBSD (and 3372339Sabial * hopefully other o/s's) by writing out ASL template files for each of 3472339Sabial * the tables and the compiling them to AML with the Intel iasl compiler. 3572339Sabial * The AML files are then read into guest memory. 3672339Sabial * 3772339Sabial * The tables are placed in the guest's ROM area just below 1MB physical, 3872339Sabial * above the MPTable. 3972339Sabial * 4072339Sabial * Layout 4172339Sabial * ------ 4272339Sabial * RSDP -> 0xf2400 (36 bytes fixed) 4372339Sabial * RSDT -> 0xf2440 (36 bytes + 4*7 table addrs, 4 used) 4472339Sabial * XSDT -> 0xf2480 (36 bytes + 8*7 table addrs, 4 used) 4572339Sabial * MADT -> 0xf2500 (depends on #CPUs) 4672339Sabial * FADT -> 0xf2600 (268 bytes) 4772339Sabial * HPET -> 0xf2740 (56 bytes) 4872339Sabial * MCFG -> 0xf2780 (60 bytes) 4972339Sabial * FACS -> 0xf27C0 (64 bytes) 5072339Sabial * DSDT -> 0xf2800 (variable - can go up to 0x100000) 5172339Sabial */ 5272339Sabial 5372339Sabial#include <sys/cdefs.h> 5472339Sabial__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/acpi.c 284899 2015-06-28 01:21:55Z neel $"); 5572339Sabial 5672339Sabial#include <sys/param.h> 5772339Sabial#include <sys/errno.h> 5872339Sabial#include <sys/stat.h> 5972339Sabial 6072339Sabial#include <paths.h> 6172339Sabial#include <stdarg.h> 6272339Sabial#include <stdio.h> 6372339Sabial#include <stdlib.h> 6472339Sabial#include <string.h> 6572339Sabial#include <unistd.h> 6672339Sabial 6772339Sabial#include <machine/vmm.h> 6872339Sabial#include <vmmapi.h> 6972339Sabial 7072339Sabial#include "bhyverun.h" 7172339Sabial#include "acpi.h" 7272339Sabial#include "pci_emul.h" 7372339Sabial 7472339Sabial/* 7572339Sabial * Define the base address of the ACPI tables, and the offsets to 7672339Sabial * the individual tables 7772339Sabial */ 7872339Sabial#define BHYVE_ACPI_BASE 0xf2400 7972339Sabial#define RSDT_OFFSET 0x040 8072339Sabial#define XSDT_OFFSET 0x080 8172339Sabial#define MADT_OFFSET 0x100 8272339Sabial#define FADT_OFFSET 0x200 8372339Sabial#define HPET_OFFSET 0x340 8472339Sabial#define MCFG_OFFSET 0x380 8572339Sabial#define FACS_OFFSET 0x3C0 8672339Sabial#define DSDT_OFFSET 0x400 8772339Sabial 8872339Sabial#define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX" 8972339Sabial#define BHYVE_ASL_SUFFIX ".aml" 9072339Sabial#define BHYVE_ASL_COMPILER "/usr/sbin/iasl" 9172339Sabial 9272339Sabialstatic int basl_keep_temps; 9372339Sabialstatic int basl_verbose_iasl; 9472339Sabialstatic int basl_ncpu; 9572339Sabialstatic uint32_t basl_acpi_base = BHYVE_ACPI_BASE; 9672339Sabialstatic uint32_t hpet_capabilities; 9772339Sabial 9872339Sabial/* 9972339Sabial * Contains the full pathname of the template to be passed 10072339Sabial * to mkstemp/mktemps(3) 10172339Sabial */ 10272339Sabialstatic char basl_template[MAXPATHLEN]; 10372339Sabialstatic char basl_stemplate[MAXPATHLEN]; 10472339Sabial 10572339Sabial/* 10672339Sabial * State for dsdt_line(), dsdt_indent(), and dsdt_unindent(). 10772339Sabial */ 10872339Sabialstatic FILE *dsdt_fp; 10972339Sabialstatic int dsdt_indent_level; 11072339Sabialstatic int dsdt_error; 11172339Sabial 11272339Sabialstruct basl_fio { 11372339Sabial int fd; 11472339Sabial FILE *fp; 11572339Sabial char f_name[MAXPATHLEN]; 11672339Sabial}; 11772339Sabial 11872339Sabial#define EFPRINTF(...) \ 11972339Sabial err = fprintf(__VA_ARGS__); if (err < 0) goto err_exit; 12072339Sabial 12172339Sabial#define EFFLUSH(x) \ 12272339Sabial err = fflush(x); if (err != 0) goto err_exit; 12372339Sabial 12472339Sabialstatic int 12572339Sabialbasl_fwrite_rsdp(FILE *fp) 12672339Sabial{ 12772339Sabial int err; 12872339Sabial 12972339Sabial err = 0; 13072339Sabial 13172339Sabial EFPRINTF(fp, "/*\n"); 13272339Sabial EFPRINTF(fp, " * bhyve RSDP template\n"); 13372339Sabial EFPRINTF(fp, " */\n"); 13472339Sabial EFPRINTF(fp, "[0008]\t\tSignature : \"RSD PTR \"\n"); 13572339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 43\n"); 13672339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 13772339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 02\n"); 13872339Sabial EFPRINTF(fp, "[0004]\t\tRSDT Address : %08X\n", 13972339Sabial basl_acpi_base + RSDT_OFFSET); 14072339Sabial EFPRINTF(fp, "[0004]\t\tLength : 00000024\n"); 14172339Sabial EFPRINTF(fp, "[0008]\t\tXSDT Address : 00000000%08X\n", 14272339Sabial basl_acpi_base + XSDT_OFFSET); 14372339Sabial EFPRINTF(fp, "[0001]\t\tExtended Checksum : 00\n"); 14472339Sabial EFPRINTF(fp, "[0003]\t\tReserved : 000000\n"); 14572339Sabial 14672339Sabial EFFLUSH(fp); 14772339Sabial 14872339Sabial return (0); 14972339Sabial 15072339Sabialerr_exit: 15172339Sabial return (errno); 15272339Sabial} 15372339Sabial 15472339Sabialstatic int 15572339Sabialbasl_fwrite_rsdt(FILE *fp) 15672339Sabial{ 15772339Sabial int err; 15872339Sabial 15972339Sabial err = 0; 16072339Sabial 16172339Sabial EFPRINTF(fp, "/*\n"); 16272339Sabial EFPRINTF(fp, " * bhyve RSDT template\n"); 16372339Sabial EFPRINTF(fp, " */\n"); 16472339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"RSDT\"\n"); 16572339Sabial EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); 16672339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); 16772339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); 16872339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 16972339Sabial EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVRSDT \"\n"); 17072339Sabial EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); 17172339Sabial /* iasl will fill in the compiler ID/revision fields */ 17272339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); 17372339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); 17472339Sabial EFPRINTF(fp, "\n"); 17572339Sabial 17672339Sabial /* Add in pointers to the MADT, FADT and HPET */ 17772339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : %08X\n", 17872339Sabial basl_acpi_base + MADT_OFFSET); 17972339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : %08X\n", 18072339Sabial basl_acpi_base + FADT_OFFSET); 18172339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : %08X\n", 18272339Sabial basl_acpi_base + HPET_OFFSET); 18372339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 3 : %08X\n", 18472339Sabial basl_acpi_base + MCFG_OFFSET); 18572339Sabial 18672339Sabial EFFLUSH(fp); 18772339Sabial 18872339Sabial return (0); 18972339Sabial 19072339Sabialerr_exit: 19172339Sabial return (errno); 19272339Sabial} 19372339Sabial 19472339Sabialstatic int 19572339Sabialbasl_fwrite_xsdt(FILE *fp) 19672339Sabial{ 19772339Sabial int err; 19872339Sabial 19972339Sabial err = 0; 20072339Sabial 20172339Sabial EFPRINTF(fp, "/*\n"); 20272339Sabial EFPRINTF(fp, " * bhyve XSDT template\n"); 20372339Sabial EFPRINTF(fp, " */\n"); 20472339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"XSDT\"\n"); 20572339Sabial EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); 20672339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); 20772339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); 20872339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 20972339Sabial EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVXSDT \"\n"); 21072339Sabial EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); 21172339Sabial /* iasl will fill in the compiler ID/revision fields */ 21272339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); 21372339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); 21472339Sabial EFPRINTF(fp, "\n"); 21572339Sabial 21672339Sabial /* Add in pointers to the MADT, FADT and HPET */ 21772339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : 00000000%08X\n", 21872339Sabial basl_acpi_base + MADT_OFFSET); 21972339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : 00000000%08X\n", 22072339Sabial basl_acpi_base + FADT_OFFSET); 22172339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : 00000000%08X\n", 22272339Sabial basl_acpi_base + HPET_OFFSET); 22372339Sabial EFPRINTF(fp, "[0004]\t\tACPI Table Address 3 : 00000000%08X\n", 22472339Sabial basl_acpi_base + MCFG_OFFSET); 22572339Sabial 22672339Sabial EFFLUSH(fp); 22772339Sabial 22872339Sabial return (0); 22972339Sabial 23072339Sabialerr_exit: 23172339Sabial return (errno); 23272339Sabial} 23372339Sabial 23472339Sabialstatic int 23572339Sabialbasl_fwrite_madt(FILE *fp) 23672339Sabial{ 23772339Sabial int err; 23872339Sabial int i; 23972339Sabial 24072339Sabial err = 0; 24172339Sabial 24272339Sabial EFPRINTF(fp, "/*\n"); 24372339Sabial EFPRINTF(fp, " * bhyve MADT template\n"); 24472339Sabial EFPRINTF(fp, " */\n"); 24572339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"APIC\"\n"); 24672339Sabial EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); 24772339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); 24872339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); 24972339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 25072339Sabial EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVMADT \"\n"); 25172339Sabial EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); 25272339Sabial 25372339Sabial /* iasl will fill in the compiler ID/revision fields */ 25472339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); 25572339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); 25672339Sabial EFPRINTF(fp, "\n"); 25772339Sabial 25872339Sabial EFPRINTF(fp, "[0004]\t\tLocal Apic Address : FEE00000\n"); 25972339Sabial EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); 26072339Sabial EFPRINTF(fp, "\t\t\tPC-AT Compatibility : 1\n"); 26172339Sabial EFPRINTF(fp, "\n"); 26272339Sabial 26372339Sabial /* Add a Processor Local APIC entry for each CPU */ 26472339Sabial for (i = 0; i < basl_ncpu; i++) { 26572339Sabial EFPRINTF(fp, "[0001]\t\tSubtable Type : 00\n"); 26672339Sabial EFPRINTF(fp, "[0001]\t\tLength : 08\n"); 26772339Sabial /* iasl expects hex values for the proc and apic id's */ 26872339Sabial EFPRINTF(fp, "[0001]\t\tProcessor ID : %02x\n", i); 26972339Sabial EFPRINTF(fp, "[0001]\t\tLocal Apic ID : %02x\n", i); 27072339Sabial EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); 27172339Sabial EFPRINTF(fp, "\t\t\tProcessor Enabled : 1\n"); 27272339Sabial EFPRINTF(fp, "\n"); 27372339Sabial } 27472339Sabial 27572339Sabial /* Always a single IOAPIC entry, with ID 0 */ 27672339Sabial EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n"); 27772339Sabial EFPRINTF(fp, "[0001]\t\tLength : 0C\n"); 27872339Sabial /* iasl expects a hex value for the i/o apic id */ 27972339Sabial EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02x\n", 0); 28072339Sabial EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); 28172339Sabial EFPRINTF(fp, "[0004]\t\tAddress : fec00000\n"); 28272339Sabial EFPRINTF(fp, "[0004]\t\tInterrupt : 00000000\n"); 28372339Sabial EFPRINTF(fp, "\n"); 28472339Sabial 28572339Sabial /* Legacy IRQ0 is connected to pin 2 of the IOAPIC */ 28672339Sabial EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n"); 28772339Sabial EFPRINTF(fp, "[0001]\t\tLength : 0A\n"); 28872339Sabial EFPRINTF(fp, "[0001]\t\tBus : 00\n"); 28972339Sabial EFPRINTF(fp, "[0001]\t\tSource : 00\n"); 29072339Sabial EFPRINTF(fp, "[0004]\t\tInterrupt : 00000002\n"); 29172339Sabial EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n"); 29272339Sabial EFPRINTF(fp, "\t\t\tPolarity : 1\n"); 29372339Sabial EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n"); 29472339Sabial EFPRINTF(fp, "\n"); 29572339Sabial 29672339Sabial EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n"); 29772339Sabial EFPRINTF(fp, "[0001]\t\tLength : 0A\n"); 29872339Sabial EFPRINTF(fp, "[0001]\t\tBus : 00\n"); 29972339Sabial EFPRINTF(fp, "[0001]\t\tSource : %02X\n", SCI_INT); 30072339Sabial EFPRINTF(fp, "[0004]\t\tInterrupt : %08X\n", SCI_INT); 30172339Sabial EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0000\n"); 30272339Sabial EFPRINTF(fp, "\t\t\tPolarity : 3\n"); 30372339Sabial EFPRINTF(fp, "\t\t\tTrigger Mode : 3\n"); 30472339Sabial EFPRINTF(fp, "\n"); 30572339Sabial 30672339Sabial /* Local APIC NMI is connected to LINT 1 on all CPUs */ 30772339Sabial EFPRINTF(fp, "[0001]\t\tSubtable Type : 04\n"); 30872339Sabial EFPRINTF(fp, "[0001]\t\tLength : 06\n"); 30972339Sabial EFPRINTF(fp, "[0001]\t\tProcessorId : FF\n"); 31072339Sabial EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n"); 31172339Sabial EFPRINTF(fp, "\t\t\tPolarity : 1\n"); 31272339Sabial EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n"); 31372339Sabial EFPRINTF(fp, "[0001]\t\tInterrupt : 01\n"); 31472339Sabial EFPRINTF(fp, "\n"); 31572339Sabial 31672339Sabial EFFLUSH(fp); 31772339Sabial 31872339Sabial return (0); 31972339Sabial 32072339Sabialerr_exit: 32172339Sabial return (errno); 32272339Sabial} 32372339Sabial 32472339Sabialstatic int 32572339Sabialbasl_fwrite_fadt(FILE *fp) 32672339Sabial{ 32772339Sabial int err; 32872339Sabial 32972339Sabial err = 0; 33072339Sabial 33172339Sabial EFPRINTF(fp, "/*\n"); 33272339Sabial EFPRINTF(fp, " * bhyve FADT template\n"); 33372339Sabial EFPRINTF(fp, " */\n"); 33472339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"FACP\"\n"); 33572339Sabial EFPRINTF(fp, "[0004]\t\tTable Length : 0000010C\n"); 33672339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 05\n"); 33772339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); 33872339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 33972339Sabial EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVFACP \"\n"); 34072339Sabial EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); 34172339Sabial /* iasl will fill in the compiler ID/revision fields */ 34272339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); 34372339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); 34472339Sabial EFPRINTF(fp, "\n"); 34572339Sabial 34672339Sabial EFPRINTF(fp, "[0004]\t\tFACS Address : %08X\n", 34772339Sabial basl_acpi_base + FACS_OFFSET); 34872339Sabial EFPRINTF(fp, "[0004]\t\tDSDT Address : %08X\n", 34972339Sabial basl_acpi_base + DSDT_OFFSET); 35072339Sabial EFPRINTF(fp, "[0001]\t\tModel : 01\n"); 35172339Sabial EFPRINTF(fp, "[0001]\t\tPM Profile : 00 [Unspecified]\n"); 35272339Sabial EFPRINTF(fp, "[0002]\t\tSCI Interrupt : %04X\n", 35372339Sabial SCI_INT); 35472339Sabial EFPRINTF(fp, "[0004]\t\tSMI Command Port : %08X\n", 35572339Sabial SMI_CMD); 35672339Sabial EFPRINTF(fp, "[0001]\t\tACPI Enable Value : %02X\n", 35772339Sabial BHYVE_ACPI_ENABLE); 35872339Sabial EFPRINTF(fp, "[0001]\t\tACPI Disable Value : %02X\n", 35972339Sabial BHYVE_ACPI_DISABLE); 36072339Sabial EFPRINTF(fp, "[0001]\t\tS4BIOS Command : 00\n"); 36172339Sabial EFPRINTF(fp, "[0001]\t\tP-State Control : 00\n"); 36272339Sabial EFPRINTF(fp, "[0004]\t\tPM1A Event Block Address : %08X\n", 36372339Sabial PM1A_EVT_ADDR); 36472339Sabial EFPRINTF(fp, "[0004]\t\tPM1B Event Block Address : 00000000\n"); 36572339Sabial EFPRINTF(fp, "[0004]\t\tPM1A Control Block Address : %08X\n", 36672339Sabial PM1A_CNT_ADDR); 36772339Sabial EFPRINTF(fp, "[0004]\t\tPM1B Control Block Address : 00000000\n"); 36872339Sabial EFPRINTF(fp, "[0004]\t\tPM2 Control Block Address : 00000000\n"); 36972339Sabial EFPRINTF(fp, "[0004]\t\tPM Timer Block Address : %08X\n", 37072339Sabial IO_PMTMR); 37172339Sabial EFPRINTF(fp, "[0004]\t\tGPE0 Block Address : 00000000\n"); 37272339Sabial EFPRINTF(fp, "[0004]\t\tGPE1 Block Address : 00000000\n"); 37372339Sabial EFPRINTF(fp, "[0001]\t\tPM1 Event Block Length : 04\n"); 37472339Sabial EFPRINTF(fp, "[0001]\t\tPM1 Control Block Length : 02\n"); 37572339Sabial EFPRINTF(fp, "[0001]\t\tPM2 Control Block Length : 00\n"); 37672339Sabial EFPRINTF(fp, "[0001]\t\tPM Timer Block Length : 04\n"); 37772339Sabial EFPRINTF(fp, "[0001]\t\tGPE0 Block Length : 00\n"); 37872339Sabial EFPRINTF(fp, "[0001]\t\tGPE1 Block Length : 00\n"); 37972339Sabial EFPRINTF(fp, "[0001]\t\tGPE1 Base Offset : 00\n"); 38072339Sabial EFPRINTF(fp, "[0001]\t\t_CST Support : 00\n"); 38172339Sabial EFPRINTF(fp, "[0002]\t\tC2 Latency : 0000\n"); 38272339Sabial EFPRINTF(fp, "[0002]\t\tC3 Latency : 0000\n"); 38372339Sabial EFPRINTF(fp, "[0002]\t\tCPU Cache Size : 0000\n"); 38472339Sabial EFPRINTF(fp, "[0002]\t\tCache Flush Stride : 0000\n"); 38572339Sabial EFPRINTF(fp, "[0001]\t\tDuty Cycle Offset : 00\n"); 38672339Sabial EFPRINTF(fp, "[0001]\t\tDuty Cycle Width : 00\n"); 38772339Sabial EFPRINTF(fp, "[0001]\t\tRTC Day Alarm Index : 00\n"); 38872339Sabial EFPRINTF(fp, "[0001]\t\tRTC Month Alarm Index : 00\n"); 38972339Sabial EFPRINTF(fp, "[0001]\t\tRTC Century Index : 32\n"); 39072339Sabial EFPRINTF(fp, "[0002]\t\tBoot Flags (decoded below) : 0000\n"); 39172339Sabial EFPRINTF(fp, "\t\t\tLegacy Devices Supported (V2) : 0\n"); 39272339Sabial EFPRINTF(fp, "\t\t\t8042 Present on ports 60/64 (V2) : 0\n"); 39372339Sabial EFPRINTF(fp, "\t\t\tVGA Not Present (V4) : 1\n"); 39472339Sabial EFPRINTF(fp, "\t\t\tMSI Not Supported (V4) : 0\n"); 39572339Sabial EFPRINTF(fp, "\t\t\tPCIe ASPM Not Supported (V4) : 1\n"); 39672339Sabial EFPRINTF(fp, "\t\t\tCMOS RTC Not Present (V5) : 0\n"); 39772339Sabial EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); 39872339Sabial EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000000\n"); 39972339Sabial EFPRINTF(fp, "\t\t\tWBINVD instruction is operational (V1) : 1\n"); 40072339Sabial EFPRINTF(fp, "\t\t\tWBINVD flushes all caches (V1) : 0\n"); 40172339Sabial EFPRINTF(fp, "\t\t\tAll CPUs support C1 (V1) : 1\n"); 40272339Sabial EFPRINTF(fp, "\t\t\tC2 works on MP system (V1) : 0\n"); 40372339Sabial EFPRINTF(fp, "\t\t\tControl Method Power Button (V1) : 0\n"); 40472339Sabial EFPRINTF(fp, "\t\t\tControl Method Sleep Button (V1) : 1\n"); 40572339Sabial EFPRINTF(fp, "\t\t\tRTC wake not in fixed reg space (V1) : 0\n"); 40672339Sabial EFPRINTF(fp, "\t\t\tRTC can wake system from S4 (V1) : 0\n"); 40772339Sabial EFPRINTF(fp, "\t\t\t32-bit PM Timer (V1) : 1\n"); 40872339Sabial EFPRINTF(fp, "\t\t\tDocking Supported (V1) : 0\n"); 40972339Sabial EFPRINTF(fp, "\t\t\tReset Register Supported (V2) : 1\n"); 41072339Sabial EFPRINTF(fp, "\t\t\tSealed Case (V3) : 0\n"); 41172339Sabial EFPRINTF(fp, "\t\t\tHeadless - No Video (V3) : 1\n"); 41272339Sabial EFPRINTF(fp, "\t\t\tUse native instr after SLP_TYPx (V3) : 0\n"); 41372339Sabial EFPRINTF(fp, "\t\t\tPCIEXP_WAK Bits Supported (V4) : 0\n"); 41472339Sabial EFPRINTF(fp, "\t\t\tUse Platform Timer (V4) : 0\n"); 41572339Sabial EFPRINTF(fp, "\t\t\tRTC_STS valid on S4 wake (V4) : 0\n"); 41672339Sabial EFPRINTF(fp, "\t\t\tRemote Power-on capable (V4) : 0\n"); 41772339Sabial EFPRINTF(fp, "\t\t\tUse APIC Cluster Model (V4) : 0\n"); 41872339Sabial EFPRINTF(fp, "\t\t\tUse APIC Physical Destination Mode (V4) : 1\n"); 41972339Sabial EFPRINTF(fp, "\t\t\tHardware Reduced (V5) : 0\n"); 42072339Sabial EFPRINTF(fp, "\t\t\tLow Power S0 Idle (V5) : 0\n"); 42172339Sabial EFPRINTF(fp, "\n"); 42272339Sabial 42372339Sabial EFPRINTF(fp, 42472339Sabial "[0012]\t\tReset Register : [Generic Address Structure]\n"); 42572339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 42672339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); 42772339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 42872339Sabial EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); 42972339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000CF9\n"); 43072339Sabial EFPRINTF(fp, "\n"); 43172339Sabial 43272339Sabial EFPRINTF(fp, "[0001]\t\tValue to cause reset : 06\n"); 43372339Sabial EFPRINTF(fp, "[0002]\t\tARM Flags (decoded below): 0000\n"); 43472339Sabial EFPRINTF(fp, "\t\t\tPSCI Compliant : 0\n"); 43572339Sabial EFPRINTF(fp, "\t\t\tMust use HVC for PSCI : 0\n"); 43672339Sabial EFPRINTF(fp, "[0001]\t\tFADT Minor Revision : 01\n"); 43772339Sabial EFPRINTF(fp, "[0008]\t\tFACS Address : 00000000%08X\n", 43872339Sabial basl_acpi_base + FACS_OFFSET); 43972339Sabial EFPRINTF(fp, "[0008]\t\tDSDT Address : 00000000%08X\n", 44072339Sabial basl_acpi_base + DSDT_OFFSET); 44172339Sabial EFPRINTF(fp, 44272339Sabial "[0012]\t\tPM1A Event Block : [Generic Address Structure]\n"); 44372339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 44472339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 20\n"); 44572339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 44672339Sabial EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 02 [Word Access:16]\n"); 44772339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", 44872339Sabial PM1A_EVT_ADDR); 44972339Sabial EFPRINTF(fp, "\n"); 45072339Sabial 45172339Sabial EFPRINTF(fp, 45272339Sabial "[0012]\t\tPM1B Event Block : [Generic Address Structure]\n"); 45372339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 45472339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); 45572339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 45672339Sabial EFPRINTF(fp, 45772339Sabial "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); 45872339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 45972339Sabial EFPRINTF(fp, "\n"); 46072339Sabial 46172339Sabial EFPRINTF(fp, 46272339Sabial "[0012]\t\tPM1A Control Block : [Generic Address Structure]\n"); 46372339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 46472339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 10\n"); 46572339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 46672339Sabial EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 02 [Word Access:16]\n"); 46772339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", 46872339Sabial PM1A_CNT_ADDR); 46972339Sabial EFPRINTF(fp, "\n"); 47072339Sabial 47172339Sabial EFPRINTF(fp, 47272339Sabial "[0012]\t\tPM1B Control Block : [Generic Address Structure]\n"); 47372339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 47472339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); 47572339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 47672339Sabial EFPRINTF(fp, 47772339Sabial "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); 47872339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 47972339Sabial EFPRINTF(fp, "\n"); 48072339Sabial 48172339Sabial EFPRINTF(fp, 48272339Sabial "[0012]\t\tPM2 Control Block : [Generic Address Structure]\n"); 48372339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 48472339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); 48572339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 48672339Sabial EFPRINTF(fp, 48772339Sabial "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); 48872339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 48972339Sabial EFPRINTF(fp, "\n"); 49072339Sabial 49172339Sabial /* Valid for bhyve */ 49272339Sabial EFPRINTF(fp, 49372339Sabial "[0012]\t\tPM Timer Block : [Generic Address Structure]\n"); 49472339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 49572339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 20\n"); 49672339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 49772339Sabial EFPRINTF(fp, 49872339Sabial "[0001]\t\tEncoded Access Width : 03 [DWord Access:32]\n"); 49972339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", 50072339Sabial IO_PMTMR); 50172339Sabial EFPRINTF(fp, "\n"); 50272339Sabial 50372339Sabial EFPRINTF(fp, "[0012]\t\tGPE0 Block : [Generic Address Structure]\n"); 50472339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 50572339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); 50672339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 50772339Sabial EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); 50872339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 50972339Sabial EFPRINTF(fp, "\n"); 51072339Sabial 51172339Sabial EFPRINTF(fp, "[0012]\t\tGPE1 Block : [Generic Address Structure]\n"); 51272339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 51372339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); 51472339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 51572339Sabial EFPRINTF(fp, 51672339Sabial "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); 51772339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 51872339Sabial EFPRINTF(fp, "\n"); 51972339Sabial 52072339Sabial EFPRINTF(fp, 52172339Sabial "[0012]\t\tSleep Control Register : [Generic Address Structure]\n"); 52272339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 52372339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); 52472339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 52572339Sabial EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); 52672339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 52772339Sabial EFPRINTF(fp, "\n"); 52872339Sabial 52972339Sabial EFPRINTF(fp, 53072339Sabial "[0012]\t\tSleep Status Register : [Generic Address Structure]\n"); 53172339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); 53272339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); 53372339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 53472339Sabial EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); 53572339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); 53672339Sabial 53772339Sabial EFFLUSH(fp); 53872339Sabial 53972339Sabial return (0); 54072339Sabial 54172339Sabialerr_exit: 54272339Sabial return (errno); 54372339Sabial} 54472339Sabial 54572339Sabialstatic int 54672339Sabialbasl_fwrite_hpet(FILE *fp) 54772339Sabial{ 54872339Sabial int err; 54972339Sabial 55072339Sabial err = 0; 55172339Sabial 55272339Sabial EFPRINTF(fp, "/*\n"); 55372339Sabial EFPRINTF(fp, " * bhyve HPET template\n"); 55472339Sabial EFPRINTF(fp, " */\n"); 55572339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"HPET\"\n"); 55672339Sabial EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); 55772339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); 55872339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); 55972339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 56072339Sabial EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVHPET \"\n"); 56172339Sabial EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); 56272339Sabial 56372339Sabial /* iasl will fill in the compiler ID/revision fields */ 56472339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); 56572339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); 56672339Sabial EFPRINTF(fp, "\n"); 56772339Sabial 56872339Sabial EFPRINTF(fp, "[0004]\t\tTimer Block ID : %08X\n", hpet_capabilities); 56972339Sabial EFPRINTF(fp, 57072339Sabial "[0012]\t\tTimer Block Register : [Generic Address Structure]\n"); 57172339Sabial EFPRINTF(fp, "[0001]\t\tSpace ID : 00 [SystemMemory]\n"); 57272339Sabial EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); 57372339Sabial EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); 57472339Sabial EFPRINTF(fp, 57572339Sabial "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); 57672339Sabial EFPRINTF(fp, "[0008]\t\tAddress : 00000000FED00000\n"); 57772339Sabial EFPRINTF(fp, "\n"); 57872339Sabial 57972339Sabial EFPRINTF(fp, "[0001]\t\tHPET Number : 00\n"); 58072339Sabial EFPRINTF(fp, "[0002]\t\tMinimum Clock Ticks : 0000\n"); 58172339Sabial EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); 58272339Sabial EFPRINTF(fp, "\t\t\t4K Page Protect : 1\n"); 58372339Sabial EFPRINTF(fp, "\t\t\t64K Page Protect : 0\n"); 58472339Sabial EFPRINTF(fp, "\n"); 58572339Sabial 58672339Sabial EFFLUSH(fp); 58772339Sabial 58872339Sabial return (0); 58972339Sabial 59072339Sabialerr_exit: 59172339Sabial return (errno); 59272339Sabial} 59372339Sabial 59472339Sabialstatic int 59572339Sabialbasl_fwrite_mcfg(FILE *fp) 59672339Sabial{ 59772339Sabial int err = 0; 59872339Sabial 59972339Sabial EFPRINTF(fp, "/*\n"); 60072339Sabial EFPRINTF(fp, " * bhyve MCFG template\n"); 60172339Sabial EFPRINTF(fp, " */\n"); 60272339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"MCFG\"\n"); 60372339Sabial EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); 60472339Sabial EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); 60572339Sabial EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); 60672339Sabial EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); 60772339Sabial EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVMCFG \"\n"); 60872339Sabial EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); 60972339Sabial 61072339Sabial /* iasl will fill in the compiler ID/revision fields */ 61172339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); 61272339Sabial EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); 61372339Sabial EFPRINTF(fp, "[0008]\t\tReserved : 0\n"); 61472339Sabial EFPRINTF(fp, "\n"); 61572339Sabial 61672339Sabial EFPRINTF(fp, "[0008]\t\tBase Address : %016lX\n", pci_ecfg_base()); 61772339Sabial EFPRINTF(fp, "[0002]\t\tSegment Group: 0000\n"); 61872339Sabial EFPRINTF(fp, "[0001]\t\tStart Bus: 00\n"); 61972339Sabial EFPRINTF(fp, "[0001]\t\tEnd Bus: FF\n"); 62072339Sabial EFPRINTF(fp, "[0004]\t\tReserved : 0\n"); 62172339Sabial EFFLUSH(fp); 62272339Sabial return (0); 62372339Sabialerr_exit: 62472339Sabial return (errno); 62572339Sabial} 62672339Sabial 62772339Sabialstatic int 62872339Sabialbasl_fwrite_facs(FILE *fp) 62972339Sabial{ 63072339Sabial int err; 63172339Sabial 63272339Sabial err = 0; 63372339Sabial 63472339Sabial EFPRINTF(fp, "/*\n"); 63572339Sabial EFPRINTF(fp, " * bhyve FACS template\n"); 63672339Sabial EFPRINTF(fp, " */\n"); 63772339Sabial EFPRINTF(fp, "[0004]\t\tSignature : \"FACS\"\n"); 63872339Sabial EFPRINTF(fp, "[0004]\t\tLength : 00000040\n"); 63972339Sabial EFPRINTF(fp, "[0004]\t\tHardware Signature : 00000000\n"); 64072339Sabial EFPRINTF(fp, "[0004]\t\t32 Firmware Waking Vector : 00000000\n"); 64172339Sabial EFPRINTF(fp, "[0004]\t\tGlobal Lock : 00000000\n"); 64272339Sabial EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000000\n"); 64372339Sabial EFPRINTF(fp, "\t\t\tS4BIOS Support Present : 0\n"); 64472339Sabial EFPRINTF(fp, "\t\t\t64-bit Wake Supported (V2) : 0\n"); 64572339Sabial EFPRINTF(fp, 64672339Sabial "[0008]\t\t64 Firmware Waking Vector : 0000000000000000\n"); 64772339Sabial EFPRINTF(fp, "[0001]\t\tVersion : 02\n"); 64872339Sabial EFPRINTF(fp, "[0003]\t\tReserved : 000000\n"); 64972339Sabial EFPRINTF(fp, "[0004]\t\tOspmFlags (decoded below) : 00000000\n"); 65072339Sabial EFPRINTF(fp, "\t\t\t64-bit Wake Env Required (V2) : 0\n"); 65172339Sabial 65272339Sabial EFFLUSH(fp); 65372339Sabial 65472339Sabial return (0); 65572339Sabial 65672339Sabialerr_exit: 65772339Sabial return (errno); 65872339Sabial} 65972339Sabial 66072339Sabial/* 66172339Sabial * Helper routines for writing to the DSDT from other modules. 66272339Sabial */ 66372339Sabialvoid 66472339Sabialdsdt_line(const char *fmt, ...) 66572339Sabial{ 66672339Sabial va_list ap; 66772339Sabial int err; 66872339Sabial 66972339Sabial if (dsdt_error != 0) 67072339Sabial return; 67172339Sabial 67272339Sabial if (strcmp(fmt, "") != 0) { 67372339Sabial if (dsdt_indent_level != 0) 67472339Sabial EFPRINTF(dsdt_fp, "%*c", dsdt_indent_level * 2, ' '); 67572339Sabial va_start(ap, fmt); 676 if (vfprintf(dsdt_fp, fmt, ap) < 0) 677 goto err_exit; 678 va_end(ap); 679 } 680 EFPRINTF(dsdt_fp, "\n"); 681 return; 682 683err_exit: 684 dsdt_error = errno; 685} 686 687void 688dsdt_indent(int levels) 689{ 690 691 dsdt_indent_level += levels; 692 assert(dsdt_indent_level >= 0); 693} 694 695void 696dsdt_unindent(int levels) 697{ 698 699 assert(dsdt_indent_level >= levels); 700 dsdt_indent_level -= levels; 701} 702 703void 704dsdt_fixed_ioport(uint16_t iobase, uint16_t length) 705{ 706 707 dsdt_line("IO (Decode16,"); 708 dsdt_line(" 0x%04X, // Range Minimum", iobase); 709 dsdt_line(" 0x%04X, // Range Maximum", iobase); 710 dsdt_line(" 0x01, // Alignment"); 711 dsdt_line(" 0x%02X, // Length", length); 712 dsdt_line(" )"); 713} 714 715void 716dsdt_fixed_irq(uint8_t irq) 717{ 718 719 dsdt_line("IRQNoFlags ()"); 720 dsdt_line(" {%d}", irq); 721} 722 723void 724dsdt_fixed_mem32(uint32_t base, uint32_t length) 725{ 726 727 dsdt_line("Memory32Fixed (ReadWrite,"); 728 dsdt_line(" 0x%08X, // Address Base", base); 729 dsdt_line(" 0x%08X, // Address Length", length); 730 dsdt_line(" )"); 731} 732 733static int 734basl_fwrite_dsdt(FILE *fp) 735{ 736 int err; 737 738 err = 0; 739 dsdt_fp = fp; 740 dsdt_error = 0; 741 dsdt_indent_level = 0; 742 743 dsdt_line("/*"); 744 dsdt_line(" * bhyve DSDT template"); 745 dsdt_line(" */"); 746 dsdt_line("DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2," 747 "\"BHYVE \", \"BVDSDT \", 0x00000001)"); 748 dsdt_line("{"); 749 dsdt_line(" Name (_S5, Package ()"); 750 dsdt_line(" {"); 751 dsdt_line(" 0x05,"); 752 dsdt_line(" Zero,"); 753 dsdt_line(" })"); 754 755 pci_write_dsdt(); 756 757 dsdt_line(""); 758 dsdt_line(" Scope (_SB.PC00)"); 759 dsdt_line(" {"); 760 dsdt_line(" Device (HPET)"); 761 dsdt_line(" {"); 762 dsdt_line(" Name (_HID, EISAID(\"PNP0103\"))"); 763 dsdt_line(" Name (_UID, 0)"); 764 dsdt_line(" Name (_CRS, ResourceTemplate ()"); 765 dsdt_line(" {"); 766 dsdt_indent(4); 767 dsdt_fixed_mem32(0xFED00000, 0x400); 768 dsdt_unindent(4); 769 dsdt_line(" })"); 770 dsdt_line(" }"); 771 dsdt_line(" }"); 772 dsdt_line("}"); 773 774 if (dsdt_error != 0) 775 return (dsdt_error); 776 777 EFFLUSH(fp); 778 779 return (0); 780 781err_exit: 782 return (errno); 783} 784 785static int 786basl_open(struct basl_fio *bf, int suffix) 787{ 788 int err; 789 790 err = 0; 791 792 if (suffix) { 793 strncpy(bf->f_name, basl_stemplate, MAXPATHLEN); 794 bf->fd = mkstemps(bf->f_name, strlen(BHYVE_ASL_SUFFIX)); 795 } else { 796 strncpy(bf->f_name, basl_template, MAXPATHLEN); 797 bf->fd = mkstemp(bf->f_name); 798 } 799 800 if (bf->fd > 0) { 801 bf->fp = fdopen(bf->fd, "w+"); 802 if (bf->fp == NULL) { 803 unlink(bf->f_name); 804 close(bf->fd); 805 } 806 } else { 807 err = 1; 808 } 809 810 return (err); 811} 812 813static void 814basl_close(struct basl_fio *bf) 815{ 816 817 if (!basl_keep_temps) 818 unlink(bf->f_name); 819 fclose(bf->fp); 820} 821 822static int 823basl_start(struct basl_fio *in, struct basl_fio *out) 824{ 825 int err; 826 827 err = basl_open(in, 0); 828 if (!err) { 829 err = basl_open(out, 1); 830 if (err) { 831 basl_close(in); 832 } 833 } 834 835 return (err); 836} 837 838static void 839basl_end(struct basl_fio *in, struct basl_fio *out) 840{ 841 842 basl_close(in); 843 basl_close(out); 844} 845 846static int 847basl_load(struct vmctx *ctx, int fd, uint64_t off) 848{ 849 struct stat sb; 850 void *gaddr; 851 852 if (fstat(fd, &sb) < 0) 853 return (errno); 854 855 gaddr = paddr_guest2host(ctx, basl_acpi_base + off, sb.st_size); 856 if (gaddr == NULL) 857 return (EFAULT); 858 859 if (read(fd, gaddr, sb.st_size) < 0) 860 return (errno); 861 862 return (0); 863} 864 865static int 866basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *), uint64_t offset) 867{ 868 struct basl_fio io[2]; 869 static char iaslbuf[3*MAXPATHLEN + 10]; 870 char *fmt; 871 int err; 872 873 err = basl_start(&io[0], &io[1]); 874 if (!err) { 875 err = (*fwrite_section)(io[0].fp); 876 877 if (!err) { 878 /* 879 * iasl sends the results of the compilation to 880 * stdout. Shut this down by using the shell to 881 * redirect stdout to /dev/null, unless the user 882 * has requested verbose output for debugging 883 * purposes 884 */ 885 fmt = basl_verbose_iasl ? 886 "%s -p %s %s" : 887 "/bin/sh -c \"%s -p %s %s\" 1> /dev/null"; 888 889 snprintf(iaslbuf, sizeof(iaslbuf), 890 fmt, 891 BHYVE_ASL_COMPILER, 892 io[1].f_name, io[0].f_name); 893 err = system(iaslbuf); 894 895 if (!err) { 896 /* 897 * Copy the aml output file into guest 898 * memory at the specified location 899 */ 900 err = basl_load(ctx, io[1].fd, offset); 901 } 902 } 903 basl_end(&io[0], &io[1]); 904 } 905 906 return (err); 907} 908 909static int 910basl_make_templates(void) 911{ 912 const char *tmpdir; 913 int err; 914 int len; 915 916 err = 0; 917 918 /* 919 * 920 */ 921 if ((tmpdir = getenv("BHYVE_TMPDIR")) == NULL || *tmpdir == '\0' || 922 (tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') { 923 tmpdir = _PATH_TMP; 924 } 925 926 len = strlen(tmpdir); 927 928 if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1) < MAXPATHLEN) { 929 strcpy(basl_template, tmpdir); 930 while (len > 0 && basl_template[len - 1] == '/') 931 len--; 932 basl_template[len] = '/'; 933 strcpy(&basl_template[len + 1], BHYVE_ASL_TEMPLATE); 934 } else 935 err = E2BIG; 936 937 if (!err) { 938 /* 939 * len has been intialized (and maybe adjusted) above 940 */ 941 if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1 + 942 sizeof(BHYVE_ASL_SUFFIX)) < MAXPATHLEN) { 943 strcpy(basl_stemplate, tmpdir); 944 basl_stemplate[len] = '/'; 945 strcpy(&basl_stemplate[len + 1], BHYVE_ASL_TEMPLATE); 946 len = strlen(basl_stemplate); 947 strcpy(&basl_stemplate[len], BHYVE_ASL_SUFFIX); 948 } else 949 err = E2BIG; 950 } 951 952 return (err); 953} 954 955static struct { 956 int (*wsect)(FILE *fp); 957 uint64_t offset; 958} basl_ftables[] = 959{ 960 { basl_fwrite_rsdp, 0}, 961 { basl_fwrite_rsdt, RSDT_OFFSET }, 962 { basl_fwrite_xsdt, XSDT_OFFSET }, 963 { basl_fwrite_madt, MADT_OFFSET }, 964 { basl_fwrite_fadt, FADT_OFFSET }, 965 { basl_fwrite_hpet, HPET_OFFSET }, 966 { basl_fwrite_mcfg, MCFG_OFFSET }, 967 { basl_fwrite_facs, FACS_OFFSET }, 968 { basl_fwrite_dsdt, DSDT_OFFSET }, 969 { NULL } 970}; 971 972int 973acpi_build(struct vmctx *ctx, int ncpu) 974{ 975 int err; 976 int i; 977 978 basl_ncpu = ncpu; 979 980 err = vm_get_hpet_capabilities(ctx, &hpet_capabilities); 981 if (err != 0) 982 return (err); 983 984 /* 985 * For debug, allow the user to have iasl compiler output sent 986 * to stdout rather than /dev/null 987 */ 988 if (getenv("BHYVE_ACPI_VERBOSE_IASL")) 989 basl_verbose_iasl = 1; 990 991 /* 992 * Allow the user to keep the generated ASL files for debugging 993 * instead of deleting them following use 994 */ 995 if (getenv("BHYVE_ACPI_KEEPTMPS")) 996 basl_keep_temps = 1; 997 998 i = 0; 999 err = basl_make_templates(); 1000 1001 /* 1002 * Run through all the ASL files, compiling them and 1003 * copying them into guest memory 1004 */ 1005 while (!err && basl_ftables[i].wsect != NULL) { 1006 err = basl_compile(ctx, basl_ftables[i].wsect, 1007 basl_ftables[i].offset); 1008 i++; 1009 } 1010 1011 return (err); 1012} 1013