2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2012 NetApp, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * bhyve ACPI table generator.
34 * Create the minimal set of ACPI tables required to boot FreeBSD (and
35 * hopefully other o/s's).
37 * The tables are placed in the guest's ROM area just below 1MB physical,
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
44 #include <sys/param.h>
45 #include <sys/endian.h>
46 #include <sys/errno.h>
58 #include <machine/vmm.h>
67 #define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX"
68 #define BHYVE_ASL_SUFFIX ".aml"
69 #define BHYVE_ASL_COMPILER "/usr/sbin/iasl"
71 #define BHYVE_ADDRESS_IOAPIC 0xFEC00000
72 #define BHYVE_ADDRESS_HPET 0xFED00000
73 #define BHYVE_ADDRESS_LAPIC 0xFEE00000
75 static int basl_keep_temps
;
76 static int basl_verbose_iasl
;
78 static uint32_t hpet_capabilities
;
81 * Contains the full pathname of the template to be passed
82 * to mkstemp/mktemps(3)
84 static char basl_template
[MAXPATHLEN
];
85 static char basl_stemplate
[MAXPATHLEN
];
88 * State for dsdt_line(), dsdt_indent(), and dsdt_unindent().
91 static int dsdt_indent_level
;
92 static int dsdt_error
;
94 static struct basl_table
*rsdt
;
95 static struct basl_table
*xsdt
;
100 char f_name
[MAXPATHLEN
];
103 #define EFPRINTF(...) \
104 if (fprintf(__VA_ARGS__) < 0) goto err_exit;
107 if (fflush(x) != 0) goto err_exit;
110 * Helper routines for writing to the DSDT from other modules.
113 dsdt_line(const char *fmt
, ...)
120 if (strcmp(fmt
, "") != 0) {
121 if (dsdt_indent_level
!= 0)
122 EFPRINTF(dsdt_fp
, "%*c", dsdt_indent_level
* 2, ' ');
124 if (vfprintf(dsdt_fp
, fmt
, ap
) < 0) {
130 EFPRINTF(dsdt_fp
, "\n");
138 dsdt_indent(int levels
)
141 dsdt_indent_level
+= levels
;
142 assert(dsdt_indent_level
>= 0);
146 dsdt_unindent(int levels
)
149 assert(dsdt_indent_level
>= levels
);
150 dsdt_indent_level
-= levels
;
154 dsdt_fixed_ioport(uint16_t iobase
, uint16_t length
)
157 dsdt_line("IO (Decode16,");
158 dsdt_line(" 0x%04X, // Range Minimum", iobase
);
159 dsdt_line(" 0x%04X, // Range Maximum", iobase
);
160 dsdt_line(" 0x01, // Alignment");
161 dsdt_line(" 0x%02X, // Length", length
);
166 dsdt_fixed_irq(uint8_t irq
)
169 dsdt_line("IRQNoFlags ()");
170 dsdt_line(" {%d}", irq
);
174 dsdt_fixed_mem32(uint32_t base
, uint32_t length
)
177 dsdt_line("Memory32Fixed (ReadWrite,");
178 dsdt_line(" 0x%08X, // Address Base", base
);
179 dsdt_line(" 0x%08X, // Address Length", length
);
184 basl_fwrite_dsdt(FILE *fp
)
188 dsdt_indent_level
= 0;
191 dsdt_line(" * bhyve DSDT template");
193 dsdt_line("DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2,"
194 "\"BHYVE \", \"BVDSDT \", 0x00000001)");
196 dsdt_line(" Name (_S5, Package ()");
205 dsdt_line(" Scope (_SB.PC00)");
207 dsdt_line(" Device (HPET)");
209 dsdt_line(" Name (_HID, EISAID(\"PNP0103\"))");
210 dsdt_line(" Name (_UID, 0)");
211 dsdt_line(" Name (_CRS, ResourceTemplate ()");
214 dsdt_fixed_mem32(0xFED00000, 0x400);
236 basl_open(struct basl_fio
*bf
, int suffix
)
243 strlcpy(bf
->f_name
, basl_stemplate
, MAXPATHLEN
);
244 bf
->fd
= mkstemps(bf
->f_name
, strlen(BHYVE_ASL_SUFFIX
));
246 strlcpy(bf
->f_name
, basl_template
, MAXPATHLEN
);
247 bf
->fd
= mkstemp(bf
->f_name
);
251 bf
->fp
= fdopen(bf
->fd
, "w+");
252 if (bf
->fp
== NULL
) {
264 basl_close(struct basl_fio
*bf
)
267 if (!basl_keep_temps
)
273 basl_start(struct basl_fio
*in
, struct basl_fio
*out
)
277 err
= basl_open(in
, 0);
279 err
= basl_open(out
, 1);
289 basl_end(struct basl_fio
*in
, struct basl_fio
*out
)
297 basl_load(struct vmctx
*ctx
, int fd
)
302 if (fstat(fd
, &sb
) < 0)
305 addr
= calloc(1, sb
.st_size
);
309 if (read(fd
, addr
, sb
.st_size
) < 0)
312 struct basl_table
*table
;
314 uint8_t name
[ACPI_NAMESEG_SIZE
+ 1] = { 0 };
315 memcpy(name
, addr
, sizeof(name
) - 1 /* last char is '\0' */);
316 BASL_EXEC(basl_table_create(&table
, ctx
, name
, BASL_TABLE_ALIGNMENT
));
317 BASL_EXEC(basl_table_append_bytes(table
, addr
, sb
.st_size
));
323 basl_compile(struct vmctx
*ctx
, int (*fwrite_section
)(FILE *))
325 struct basl_fio io
[2];
326 static char iaslbuf
[3*MAXPATHLEN
+ 10];
330 err
= basl_start(&io
[0], &io
[1]);
332 err
= (*fwrite_section
)(io
[0].fp
);
336 * iasl sends the results of the compilation to
337 * stdout. Shut this down by using the shell to
338 * redirect stdout to /dev/null, unless the user
339 * has requested verbose output for debugging
342 fmt
= basl_verbose_iasl
?
344 "/bin/sh -c \"%s -p %s %s\" 1> /dev/null";
346 snprintf(iaslbuf
, sizeof(iaslbuf
),
349 io
[1].f_name
, io
[0].f_name
);
350 err
= system(iaslbuf
);
354 * Copy the aml output file into guest
355 * memory at the specified location
357 err
= basl_load(ctx
, io
[1].fd
);
360 basl_end(&io
[0], &io
[1]);
367 basl_make_templates(void)
378 if ((tmpdir
= getenv("BHYVE_TMPDIR")) == NULL
|| *tmpdir
== '\0' ||
379 (tmpdir
= getenv("TMPDIR")) == NULL
|| *tmpdir
== '\0') {
383 len
= strlen(tmpdir
);
385 if ((len
+ sizeof(BHYVE_ASL_TEMPLATE
) + 1) < MAXPATHLEN
) {
386 strcpy(basl_template
, tmpdir
);
387 while (len
> 0 && basl_template
[len
- 1] == '/')
389 basl_template
[len
] = '/';
390 strcpy(&basl_template
[len
+ 1], BHYVE_ASL_TEMPLATE
);
396 * len has been intialized (and maybe adjusted) above
398 if ((len
+ sizeof(BHYVE_ASL_TEMPLATE
) + 1 +
399 sizeof(BHYVE_ASL_SUFFIX
)) < MAXPATHLEN
) {
400 strcpy(basl_stemplate
, tmpdir
);
401 basl_stemplate
[len
] = '/';
402 strcpy(&basl_stemplate
[len
+ 1], BHYVE_ASL_TEMPLATE
);
403 len
= strlen(basl_stemplate
);
404 strcpy(&basl_stemplate
[len
], BHYVE_ASL_SUFFIX
);
413 build_dsdt(struct vmctx
*const ctx
)
415 BASL_EXEC(basl_compile(ctx
, basl_fwrite_dsdt
));
421 build_facs(struct vmctx
*const ctx
)
423 ACPI_TABLE_FACS facs
;
424 struct basl_table
*table
;
425 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_SIG_FACS
,
426 BASL_TABLE_ALIGNMENT_FACS
));
428 memset(&facs
, 0, sizeof(facs
));
429 memcpy(facs
.Signature
, ACPI_SIG_FACS
, ACPI_NAMESEG_SIZE
);
430 facs
.Length
= sizeof(facs
);
431 facs
.Version
= htole32(2);
432 BASL_EXEC(basl_table_append_bytes(table
, &facs
, sizeof(facs
)));
438 build_fadt(struct vmctx
*const ctx
)
440 ACPI_TABLE_FADT fadt
;
441 struct basl_table
*table
;
443 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_SIG_FADT
,
444 BASL_TABLE_ALIGNMENT
));
446 memset(&fadt
, 0, sizeof(fadt
));
447 BASL_EXEC(basl_table_append_header(table
, ACPI_SIG_FADT
, 5, 1));
448 fadt
.Facs
= htole32(0); /* patched by basl */
449 fadt
.Dsdt
= htole32(0); /* patched by basl */
450 fadt
.SciInterrupt
= htole16(SCI_INT
);
451 fadt
.SmiCommand
= htole32(SMI_CMD
);
452 fadt
.AcpiEnable
= BHYVE_ACPI_ENABLE
;
453 fadt
.AcpiDisable
= BHYVE_ACPI_DISABLE
;
454 fadt
.Pm1aEventBlock
= htole32(PM1A_EVT_ADDR
);
455 fadt
.Pm1aControlBlock
= htole32(PM1A_CNT_ADDR
);
456 fadt
.PmTimerBlock
= htole32(IO_PMTMR
);
457 fadt
.Gpe0Block
= htole32(IO_GPE0_BLK
);
458 fadt
.Pm1EventLength
= 4;
459 fadt
.Pm1ControlLength
= 2;
460 fadt
.PmTimerLength
= 4;
461 fadt
.Gpe0BlockLength
= IO_GPE0_LEN
;
463 fadt
.BootFlags
= htole16(ACPI_FADT_NO_VGA
| ACPI_FADT_NO_ASPM
);
464 fadt
.Flags
= htole32(ACPI_FADT_WBINVD
| ACPI_FADT_C1_SUPPORTED
|
465 ACPI_FADT_SLEEP_BUTTON
| ACPI_FADT_32BIT_TIMER
|
466 ACPI_FADT_RESET_REGISTER
| ACPI_FADT_HEADLESS
|
467 ACPI_FADT_APIC_PHYSICAL
);
468 basl_fill_gas(&fadt
.ResetRegister
, ACPI_ADR_SPACE_SYSTEM_IO
, 8, 0,
469 ACPI_GAS_ACCESS_WIDTH_BYTE
, 0xCF9);
471 fadt
.MinorRevision
= 1;
472 fadt
.XFacs
= htole64(0); /* patched by basl */
473 fadt
.XDsdt
= htole64(0); /* patched by basl */
474 basl_fill_gas(&fadt
.XPm1aEventBlock
, ACPI_ADR_SPACE_SYSTEM_IO
, 0x20, 0,
475 ACPI_GAS_ACCESS_WIDTH_WORD
, PM1A_EVT_ADDR
);
476 basl_fill_gas(&fadt
.XPm1bEventBlock
, ACPI_ADR_SPACE_SYSTEM_IO
, 0, 0,
477 ACPI_GAS_ACCESS_WIDTH_UNDEFINED
, 0);
478 basl_fill_gas(&fadt
.XPm1aControlBlock
, ACPI_ADR_SPACE_SYSTEM_IO
, 0x10,
479 0, ACPI_GAS_ACCESS_WIDTH_WORD
, PM1A_CNT_ADDR
);
480 basl_fill_gas(&fadt
.XPm1bControlBlock
, ACPI_ADR_SPACE_SYSTEM_IO
, 0, 0,
481 ACPI_GAS_ACCESS_WIDTH_UNDEFINED
, 0);
482 basl_fill_gas(&fadt
.XPm2ControlBlock
, ACPI_ADR_SPACE_SYSTEM_IO
, 8, 0,
483 ACPI_GAS_ACCESS_WIDTH_UNDEFINED
, 0);
484 basl_fill_gas(&fadt
.XPmTimerBlock
, ACPI_ADR_SPACE_SYSTEM_IO
, 0x20, 0,
485 ACPI_GAS_ACCESS_WIDTH_DWORD
, IO_PMTMR
);
486 basl_fill_gas(&fadt
.XGpe0Block
, ACPI_ADR_SPACE_SYSTEM_IO
,
487 IO_GPE0_LEN
* 8, 0, ACPI_GAS_ACCESS_WIDTH_BYTE
, IO_GPE0_BLK
);
488 basl_fill_gas(&fadt
.XGpe1Block
, ACPI_ADR_SPACE_SYSTEM_IO
, 0, 0,
489 ACPI_GAS_ACCESS_WIDTH_UNDEFINED
, 0);
490 basl_fill_gas(&fadt
.SleepControl
, ACPI_ADR_SPACE_SYSTEM_IO
, 8, 0,
491 ACPI_GAS_ACCESS_WIDTH_BYTE
, 0);
492 basl_fill_gas(&fadt
.SleepStatus
, ACPI_ADR_SPACE_SYSTEM_IO
, 8, 0,
493 ACPI_GAS_ACCESS_WIDTH_BYTE
, 0);
494 BASL_EXEC(basl_table_append_content(table
, &fadt
, sizeof(fadt
)));
496 BASL_EXEC(basl_table_add_pointer(table
, ACPI_SIG_FACS
,
497 offsetof(ACPI_TABLE_FADT
, Facs
), sizeof(fadt
.Facs
)));
498 BASL_EXEC(basl_table_add_pointer(table
, ACPI_SIG_DSDT
,
499 offsetof(ACPI_TABLE_FADT
, Dsdt
), sizeof(fadt
.Dsdt
)));
500 BASL_EXEC(basl_table_add_pointer(table
, ACPI_SIG_FACS
,
501 offsetof(ACPI_TABLE_FADT
, XFacs
), sizeof(fadt
.XFacs
)));
502 BASL_EXEC(basl_table_add_pointer(table
, ACPI_SIG_DSDT
,
503 offsetof(ACPI_TABLE_FADT
, XDsdt
), sizeof(fadt
.XDsdt
)));
505 BASL_EXEC(basl_table_append_pointer(rsdt
, ACPI_SIG_FADT
,
506 ACPI_RSDT_ENTRY_SIZE
));
507 BASL_EXEC(basl_table_append_pointer(xsdt
, ACPI_SIG_FADT
,
508 ACPI_XSDT_ENTRY_SIZE
));
514 build_hpet(struct vmctx
*const ctx
)
516 ACPI_TABLE_HPET hpet
;
517 struct basl_table
*table
;
519 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_SIG_HPET
,
520 BASL_TABLE_ALIGNMENT
));
522 memset(&hpet
, 0, sizeof(hpet
));
523 BASL_EXEC(basl_table_append_header(table
, ACPI_SIG_HPET
, 1, 1));
524 hpet
.Id
= htole32(hpet_capabilities
);
525 basl_fill_gas(&hpet
.Address
, ACPI_ADR_SPACE_SYSTEM_MEMORY
, 0, 0,
526 ACPI_GAS_ACCESS_WIDTH_LEGACY
, BHYVE_ADDRESS_HPET
);
527 hpet
.Flags
= ACPI_HPET_PAGE_PROTECT4
;
528 BASL_EXEC(basl_table_append_content(table
, &hpet
, sizeof(hpet
)));
530 BASL_EXEC(basl_table_append_pointer(rsdt
, ACPI_SIG_HPET
,
531 ACPI_RSDT_ENTRY_SIZE
));
532 BASL_EXEC(basl_table_append_pointer(xsdt
, ACPI_SIG_HPET
,
533 ACPI_XSDT_ENTRY_SIZE
));
539 build_madt(struct vmctx
*const ctx
)
541 ACPI_TABLE_MADT madt
;
542 ACPI_MADT_LOCAL_APIC madt_lapic
;
543 ACPI_MADT_IO_APIC madt_ioapic
;
544 ACPI_MADT_INTERRUPT_OVERRIDE madt_irq_override
;
545 ACPI_MADT_LOCAL_APIC_NMI madt_lapic_nmi
;
546 struct basl_table
*table
;
548 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_SIG_MADT
,
549 BASL_TABLE_ALIGNMENT
));
551 memset(&madt
, 0, sizeof(madt
));
552 BASL_EXEC(basl_table_append_header(table
, ACPI_SIG_MADT
, 1, 1));
553 madt
.Address
= htole32(BHYVE_ADDRESS_LAPIC
);
554 madt
.Flags
= htole32(ACPI_MADT_PCAT_COMPAT
);
555 BASL_EXEC(basl_table_append_content(table
, &madt
, sizeof(madt
)));
557 /* Local APIC for each CPU */
558 for (int i
= 0; i
< basl_ncpu
; ++i
) {
559 memset(&madt_lapic
, 0, sizeof(madt_lapic
));
560 madt_lapic
.Header
.Type
= ACPI_MADT_TYPE_LOCAL_APIC
;
561 madt_lapic
.Header
.Length
= sizeof(madt_lapic
);
562 madt_lapic
.ProcessorId
= i
;
564 madt_lapic
.LapicFlags
= htole32(ACPI_MADT_ENABLED
);
565 BASL_EXEC(basl_table_append_bytes(table
, &madt_lapic
,
566 sizeof(madt_lapic
)));
570 memset(&madt_ioapic
, 0, sizeof(madt_ioapic
));
571 madt_ioapic
.Header
.Type
= ACPI_MADT_TYPE_IO_APIC
;
572 madt_ioapic
.Header
.Length
= sizeof(madt_ioapic
);
573 madt_ioapic
.Address
= htole32(BHYVE_ADDRESS_IOAPIC
);
575 basl_table_append_bytes(table
, &madt_ioapic
, sizeof(madt_ioapic
)));
577 /* Legacy IRQ0 is connected to pin 2 of the I/O APIC */
578 memset(&madt_irq_override
, 0, sizeof(madt_irq_override
));
579 madt_irq_override
.Header
.Type
= ACPI_MADT_TYPE_INTERRUPT_OVERRIDE
;
580 madt_irq_override
.Header
.Length
= sizeof(madt_irq_override
);
581 madt_irq_override
.GlobalIrq
= htole32(2);
582 madt_irq_override
.IntiFlags
= htole16(
583 ACPI_MADT_POLARITY_ACTIVE_HIGH
| ACPI_MADT_TRIGGER_EDGE
);
584 BASL_EXEC(basl_table_append_bytes(table
, &madt_irq_override
,
585 sizeof(madt_irq_override
)));
587 memset(&madt_irq_override
, 0, sizeof(madt_irq_override
));
588 madt_irq_override
.Header
.Type
= ACPI_MADT_TYPE_INTERRUPT_OVERRIDE
;
589 madt_irq_override
.Header
.Length
= sizeof(madt_irq_override
);
590 madt_irq_override
.SourceIrq
= SCI_INT
;
591 madt_irq_override
.GlobalIrq
= htole32(SCI_INT
);
592 madt_irq_override
.IntiFlags
= htole16(
593 ACPI_MADT_POLARITY_ACTIVE_LOW
| ACPI_MADT_TRIGGER_LEVEL
);
594 BASL_EXEC(basl_table_append_bytes(table
, &madt_irq_override
,
595 sizeof(madt_irq_override
)));
597 /* Local APIC NMI is conntected to LINT 1 on all CPUs */
598 memset(&madt_lapic_nmi
, 0, sizeof(madt_lapic_nmi
));
599 madt_lapic_nmi
.Header
.Type
= ACPI_MADT_TYPE_LOCAL_APIC_NMI
;
600 madt_lapic_nmi
.Header
.Length
= sizeof(madt_lapic_nmi
);
601 madt_lapic_nmi
.ProcessorId
= 0xFF;
602 madt_lapic_nmi
.IntiFlags
= htole16(
603 ACPI_MADT_POLARITY_ACTIVE_HIGH
| ACPI_MADT_TRIGGER_EDGE
);
604 madt_lapic_nmi
.Lint
= 1;
605 BASL_EXEC(basl_table_append_bytes(table
, &madt_lapic_nmi
,
606 sizeof(madt_lapic_nmi
)));
608 BASL_EXEC(basl_table_append_pointer(rsdt
, ACPI_SIG_MADT
,
609 ACPI_RSDT_ENTRY_SIZE
));
610 BASL_EXEC(basl_table_append_pointer(xsdt
, ACPI_SIG_MADT
,
611 ACPI_XSDT_ENTRY_SIZE
));
617 build_mcfg(struct vmctx
*const ctx
)
619 ACPI_TABLE_MCFG mcfg
;
620 ACPI_MCFG_ALLOCATION mcfg_allocation
;
621 struct basl_table
*table
;
623 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_SIG_MCFG
,
624 BASL_TABLE_ALIGNMENT
));
626 memset(&mcfg
, 0, sizeof(mcfg
));
627 BASL_EXEC(basl_table_append_header(table
, ACPI_SIG_MCFG
, 1, 1));
628 BASL_EXEC(basl_table_append_content(table
, &mcfg
, sizeof(mcfg
)));
630 memset(&mcfg_allocation
, 0, sizeof(mcfg_allocation
));
631 mcfg_allocation
.Address
= htole64(pci_ecfg_base());
632 mcfg_allocation
.EndBusNumber
= 0xFF;
633 BASL_EXEC(basl_table_append_bytes(table
, &mcfg_allocation
,
634 sizeof(mcfg_allocation
)));
636 BASL_EXEC(basl_table_append_pointer(rsdt
, ACPI_SIG_MCFG
,
637 ACPI_RSDT_ENTRY_SIZE
));
638 BASL_EXEC(basl_table_append_pointer(xsdt
, ACPI_SIG_MCFG
,
639 ACPI_XSDT_ENTRY_SIZE
));
645 build_rsdp(struct vmctx
*const ctx
)
647 ACPI_TABLE_RSDP rsdp
;
648 struct basl_table
*table
;
650 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_RSDP_NAME
,
651 BASL_TABLE_ALIGNMENT
));
653 memset(&rsdp
, 0, sizeof(rsdp
));
654 memcpy(rsdp
.Signature
, ACPI_SIG_RSDP
, 8);
655 rsdp
.Checksum
= 0; /* patched by basl */
656 memcpy(rsdp
.OemId
, "BHYVE ", ACPI_OEM_ID_SIZE
);
658 rsdp
.RsdtPhysicalAddress
= htole32(0); /* patched by basl */
659 rsdp
.Length
= htole32(0); /* patched by basl */
660 rsdp
.XsdtPhysicalAddress
= htole64(0); /* patched by basl */
661 rsdp
.ExtendedChecksum
= 0; /* patched by basl */
662 BASL_EXEC(basl_table_append_bytes(table
, &rsdp
, sizeof(rsdp
)));
664 BASL_EXEC(basl_table_add_checksum(table
,
665 offsetof(ACPI_TABLE_RSDP
, Checksum
), 0, 20));
666 BASL_EXEC(basl_table_add_pointer(table
, ACPI_SIG_RSDT
,
667 offsetof(ACPI_TABLE_RSDP
, RsdtPhysicalAddress
),
668 sizeof(rsdp
.RsdtPhysicalAddress
)));
669 BASL_EXEC(basl_table_add_length(table
,
670 offsetof(ACPI_TABLE_RSDP
, Length
), sizeof(rsdp
.Length
)));
671 BASL_EXEC(basl_table_add_pointer(table
, ACPI_SIG_XSDT
,
672 offsetof(ACPI_TABLE_RSDP
, XsdtPhysicalAddress
),
673 sizeof(rsdp
.XsdtPhysicalAddress
)));
674 BASL_EXEC(basl_table_add_checksum(table
,
675 offsetof(ACPI_TABLE_RSDP
, ExtendedChecksum
), 0,
676 BASL_TABLE_CHECKSUM_LEN_FULL_TABLE
));
682 build_rsdt(struct vmctx
*const ctx
)
685 basl_table_create(&rsdt
, ctx
, ACPI_SIG_RSDT
, BASL_TABLE_ALIGNMENT
));
688 BASL_EXEC(basl_table_append_header(rsdt
, ACPI_SIG_RSDT
, 1, 1));
689 /* Pointers (added by other build_XXX funcs) */
695 build_spcr(struct vmctx
*const ctx
)
697 ACPI_TABLE_SPCR spcr
;
698 struct basl_table
*table
;
700 BASL_EXEC(basl_table_create(&table
, ctx
, ACPI_SIG_SPCR
,
701 BASL_TABLE_ALIGNMENT
));
703 memset(&spcr
, 0, sizeof(spcr
));
704 BASL_EXEC(basl_table_append_header(table
, ACPI_SIG_SPCR
, 1, 1));
705 spcr
.InterfaceType
= ACPI_DBG2_16550_COMPATIBLE
;
706 basl_fill_gas(&spcr
.SerialPort
, ACPI_ADR_SPACE_SYSTEM_IO
, 8, 0,
707 ACPI_GAS_ACCESS_WIDTH_LEGACY
, 0x3F8);
708 spcr
.InterruptType
= ACPI_SPCR_INTERRUPT_TYPE_8259
;
709 spcr
.PcInterrupt
= 4;
710 spcr
.BaudRate
= ACPI_SPCR_BAUD_RATE_115200
;
711 spcr
.Parity
= ACPI_SPCR_PARITY_NO_PARITY
;
712 spcr
.StopBits
= ACPI_SPCR_STOP_BITS_1
;
713 spcr
.FlowControl
= 3; /* RTS/CTS | DCD */
714 spcr
.TerminalType
= ACPI_SPCR_TERMINAL_TYPE_VT_UTF8
;
715 BASL_EXEC(basl_table_append_content(table
, &spcr
, sizeof(spcr
)));
717 BASL_EXEC(basl_table_append_pointer(rsdt
, ACPI_SIG_SPCR
,
718 ACPI_RSDT_ENTRY_SIZE
));
719 BASL_EXEC(basl_table_append_pointer(xsdt
, ACPI_SIG_SPCR
,
720 ACPI_XSDT_ENTRY_SIZE
));
726 build_xsdt(struct vmctx
*const ctx
)
729 basl_table_create(&xsdt
, ctx
, ACPI_SIG_XSDT
, BASL_TABLE_ALIGNMENT
));
732 BASL_EXEC(basl_table_append_header(xsdt
, ACPI_SIG_XSDT
, 1, 1));
733 /* Pointers (added by other build_XXX funcs) */
739 acpi_build(struct vmctx
*ctx
, int ncpu
)
745 err
= vm_get_hpet_capabilities(ctx
, &hpet_capabilities
);
750 * For debug, allow the user to have iasl compiler output sent
751 * to stdout rather than /dev/null
753 if (getenv("BHYVE_ACPI_VERBOSE_IASL"))
754 basl_verbose_iasl
= 1;
757 * Allow the user to keep the generated ASL files for debugging
758 * instead of deleting them following use
760 if (getenv("BHYVE_ACPI_KEEPTMPS"))
763 BASL_EXEC(basl_init());
765 BASL_EXEC(basl_make_templates());
768 * Generate ACPI tables and copy them into guest memory.
770 * According to UEFI Specification v6.3 chapter 5.1 the FADT should be
771 * the first table pointed to by XSDT. For that reason, build it as the
772 * first table after XSDT.
774 BASL_EXEC(build_rsdp(ctx
));
775 BASL_EXEC(build_rsdt(ctx
));
776 BASL_EXEC(build_xsdt(ctx
));
777 BASL_EXEC(build_fadt(ctx
));
778 BASL_EXEC(build_madt(ctx
));
779 BASL_EXEC(build_hpet(ctx
));
780 BASL_EXEC(build_mcfg(ctx
));
781 BASL_EXEC(build_facs(ctx
));
782 BASL_EXEC(build_spcr(ctx
));
783 BASL_EXEC(build_dsdt(ctx
));
785 BASL_EXEC(basl_finish());