Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ASL compiler support (ACPI) #199

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions include/xhyve/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@

#include <stdint.h>

/* if set, create AML instead of ASL and calling out to iasl */
#define ACPITBL_AML 1

#define SCI_INT 9

#define SMI_CMD 0xb2
Expand All @@ -45,13 +42,32 @@

#define IO_PMTMR 0x408 /* 4-byte i/o port for the timer */

int acpi_build(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);
void dsdt_fixup(int bus, uint16_t iobase, uint16_t iolimit, uint32_t membase32,
uint32_t memlimit32, uint64_t membase64, uint64_t memlimit64);
extern char* asl_compiler_path;

typedef int (*acpi_build_func_t)(int ncpu);
typedef void (*dsdt_line_func_t)(const char *fmt, ...);
typedef void (*dsdt_fixed_ioport_func_t)(uint16_t iobase, uint16_t length);
typedef void (*dsdt_fixed_irq_func_t)(uint8_t irq);
typedef void (*dsdt_fixed_mem32_func_t)(uint32_t base, uint32_t length);
typedef void (*dsdt_indent_func_t)(int levels);
typedef void (*dsdt_unindent_func_t)(int levels);
typedef void (*dsdt_fixup_func_t)(int bus, uint16_t iobase, uint16_t iolimit, uint32_t membase32, uint32_t memlimit32,
uint64_t membase64, uint64_t memlimit64);

struct acpi_ops_t {
acpi_build_func_t acpi_build;
dsdt_line_func_t dsdt_line;
dsdt_fixed_ioport_func_t dsdt_fixed_ioport;
dsdt_fixed_irq_func_t dsdt_fixed_irq;
dsdt_fixed_mem32_func_t dsdt_fixed_mem32;
dsdt_indent_func_t dsdt_indent;
dsdt_unindent_func_t dsdt_unindent;
dsdt_fixup_func_t dsdt_fixup;
};

extern struct acpi_ops_t acpi_ops;
extern struct acpi_ops_t acpi_ops_compile;
extern struct acpi_ops_t acpi_ops_prebuilt_aml;

void acpi_init(void);
void sci_init(void);
96 changes: 70 additions & 26 deletions src/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
* The tables are placed in the guest's ROM area just below 1MB physical,
* above the MPTable.
*
* Layout
* Layout (No longer correct at FADT and beyond due to properly
* calculating the size of the MADT to allow for changes to
* VM_MAXCPU above 21 which overflows this layout.)
* ------
* RSDP -> 0xf2400 (36 bytes fixed)
* RSDT -> 0xf2440 (36 bytes + 4*7 table addrs, 4 used)
Expand Down Expand Up @@ -67,22 +69,34 @@
#include <xhyve/pci_emul.h>

/*
* Define the base address of the ACPI tables, and the offsets to
* the individual tables
* Define the base address of the ACPI tables, the sizes of some tables,
* and the offsets to the individual tables,
*/
#define BHYVE_ACPI_BASE 0xf2400
#define RSDT_OFFSET 0x040
#define XSDT_OFFSET 0x080
#define MADT_OFFSET 0x100
#define FADT_OFFSET 0x200
#define HPET_OFFSET 0x340
#define MCFG_OFFSET 0x380
#define FACS_OFFSET 0x3C0
#define DSDT_OFFSET 0x400
/*
* The MADT consists of:
* 44 Fixed Header
* 8 * maxcpu Processor Local APIC entries
* 12 I/O APIC entry
* 2 * 10 Interrupt Source Override entires
* 6 Local APIC NMI entry
*/
#define MADT_SIZE (44 + VM_MAXCPU*8 + 12 + 2*10 + 6)
#define FADT_OFFSET (MADT_OFFSET + MADT_SIZE)
#define FADT_SIZE 0x140
#define HPET_OFFSET (FADT_OFFSET + FADT_SIZE)
#define HPET_SIZE 0x40
#define MCFG_OFFSET (HPET_OFFSET + HPET_SIZE)
#define MCFG_SIZE 0x40
#define FACS_OFFSET (MCFG_OFFSET + MCFG_SIZE)
#define FACS_SIZE 0x40
#define DSDT_OFFSET (FACS_OFFSET + FACS_SIZE)

#define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX"
#define BHYVE_ASL_SUFFIX ".aml"
#define BHYVE_ASL_COMPILER "/usr/sbin/iasl"

static int basl_keep_temps;
static int basl_verbose_iasl;
Expand Down Expand Up @@ -267,6 +281,7 @@ basl_fwrite_madt(FILE *fp)
EFPRINTF(fp, "[0001]\t\tLocal Apic ID : %02x\n", i);
EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n");
EFPRINTF(fp, "\t\t\tProcessor Enabled : 1\n");
EFPRINTF(fp, "\t\t\tRuntime Online Capable : 0\n");
EFPRINTF(fp, "\n");
}

Expand Down Expand Up @@ -304,11 +319,11 @@ basl_fwrite_madt(FILE *fp)
/* Local APIC NMI is connected to LINT 1 on all CPUs */
EFPRINTF(fp, "[0001]\t\tSubtable Type : 04\n");
EFPRINTF(fp, "[0001]\t\tLength : 06\n");
EFPRINTF(fp, "[0001]\t\tProcessorId : FF\n");
EFPRINTF(fp, "[0001]\t\tProcessor ID : FF\n");
EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n");
EFPRINTF(fp, "\t\t\tPolarity : 1\n");
EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n");
EFPRINTF(fp, "[0001]\t\tInterrupt : 01\n");
EFPRINTF(fp, "[0001]\t\tInterrupt Input LINT : 01\n");
EFPRINTF(fp, "\n");

EFFLUSH(fp);
Expand Down Expand Up @@ -563,7 +578,7 @@ basl_fwrite_hpet(FILE *fp)
EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n");
EFPRINTF(fp, "\n");

EFPRINTF(fp, "[0004]\t\tTimer Block ID : %08X\n", hpet_capabilities);
EFPRINTF(fp, "[0004]\t\tHardware Block ID : %08X\n", hpet_capabilities);
EFPRINTF(fp,
"[0012]\t\tTimer Block Register : [Generic Address Structure]\n");
EFPRINTF(fp, "[0001]\t\tSpace ID : 00 [SystemMemory]\n");
Expand All @@ -574,7 +589,7 @@ basl_fwrite_hpet(FILE *fp)
EFPRINTF(fp, "[0008]\t\tAddress : 00000000FED00000\n");
EFPRINTF(fp, "\n");

EFPRINTF(fp, "[0001]\t\tHPET Number : 00\n");
EFPRINTF(fp, "[0001]\t\tSequence Number : 00\n");
EFPRINTF(fp, "[0002]\t\tMinimum Clock Ticks : 0000\n");
EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n");
EFPRINTF(fp, "\t\t\t4K Page Protect : 1\n");
Expand Down Expand Up @@ -611,10 +626,10 @@ basl_fwrite_mcfg(FILE *fp)
EFPRINTF(fp, "[0008]\t\tReserved : 0\n");
EFPRINTF(fp, "\n");

EFPRINTF(fp, "[0008]\t\tBase Address : %016llx\n", pci_ecfg_base());
EFPRINTF(fp, "[0002]\t\tSegment Group: 0000\n");
EFPRINTF(fp, "[0001]\t\tStart Bus: 00\n");
EFPRINTF(fp, "[0001]\t\tEnd Bus: FF\n");
EFPRINTF(fp, "[0008]\t\tBase Address : %016llX\n", pci_ecfg_base());
EFPRINTF(fp, "[0002]\t\tSegment Group Number : 0000\n");
EFPRINTF(fp, "[0001]\t\tStart Bus Number : 00\n");
EFPRINTF(fp, "[0001]\t\tEnd Bus Number : FF\n");
EFPRINTF(fp, "[0004]\t\tReserved : 0\n");
EFFLUSH(fp);
return (0);
Expand Down Expand Up @@ -660,7 +675,7 @@ basl_fwrite_facs(FILE *fp)
/*
* Helper routines for writing to the DSDT from other modules.
*/
void
static void
dsdt_line(const char *fmt, ...)
{
va_list ap;
Expand All @@ -675,8 +690,10 @@ dsdt_line(const char *fmt, ...)
if (dsdt_indent_level != 0)
EFPRINTF(dsdt_fp, "%*c", dsdt_indent_level * 2, ' ');
va_start(ap, fmt);
if (vfprintf(dsdt_fp, fmt, ap) < 0)
if (vfprintf(dsdt_fp, fmt, ap) < 0) {
va_end(ap);
goto err_exit;
}
va_end(ap);
}
EFPRINTF(dsdt_fp, "\n");
Expand All @@ -687,23 +704,23 @@ dsdt_line(const char *fmt, ...)
}
#pragma clang diagnostic pop

void
static void
dsdt_indent(int levels)
{

dsdt_indent_level += levels;
assert(dsdt_indent_level >= 0);
}

void
static void
dsdt_unindent(int levels)
{

assert(dsdt_indent_level >= levels);
dsdt_indent_level -= levels;
}

void
static void
dsdt_fixed_ioport(uint16_t iobase, uint16_t length)
{

Expand All @@ -715,15 +732,15 @@ dsdt_fixed_ioport(uint16_t iobase, uint16_t length)
dsdt_line(" )");
}

void
static void
dsdt_fixed_irq(uint8_t irq)
{

dsdt_line("IRQNoFlags ()");
dsdt_line(" {%d}", irq);
}

void
static void
dsdt_fixed_mem32(uint32_t base, uint32_t length)
{

Expand Down Expand Up @@ -892,7 +909,7 @@ basl_compile(int (*fwrite_section)(FILE *), uint64_t offset)

snprintf(iaslbuf, sizeof(iaslbuf),
fmt,
BHYVE_ASL_COMPILER,
asl_compiler_path,
io[1].f_name, io[0].f_name);
err = system(iaslbuf);

Expand All @@ -911,6 +928,11 @@ basl_compile(int (*fwrite_section)(FILE *), uint64_t offset)
}
#pragma clang diagnostic pop

static void dsdt_fixup(UNUSED int bus, UNUSED uint16_t iobase, UNUSED uint16_t iolimit, UNUSED uint32_t membase32,
UNUSED uint32_t memlimit32, UNUSED uint64_t membase64, UNUSED uint64_t memlimit64) {

}

static int
basl_make_templates(void)
{
Expand Down Expand Up @@ -974,7 +996,7 @@ static struct {
{ NULL , 0}
};

int
static int
acpi_build(int ncpu)
{
int err;
Expand Down Expand Up @@ -1015,3 +1037,25 @@ acpi_build(int ncpu)

return (err);
}

struct acpi_ops_t acpi_ops;

struct acpi_ops_t acpi_ops_compile = {
acpi_build,
dsdt_line,
dsdt_fixed_ioport,
dsdt_fixed_irq,
dsdt_fixed_mem32,
dsdt_indent,
dsdt_unindent,
dsdt_fixup
};

void acpi_init(void)
{
if (asl_compiler_path != NULL) {
acpi_ops = acpi_ops_compile;
} else {
acpi_ops = acpi_ops_prebuilt_aml;
}
}
Loading