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