summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2018-06-25 22:39:15 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2018-06-25 22:39:15 +0000
commitcf29c9170139a190998fe6a74b85e3faa576cfdf (patch)
tree2bd5a165764d8a464de99212b8128cb6897cc64b /sys
parentd4be10bb2300db550fd687cc4bbee19535681603 (diff)
Add code that builds a basic device tree from ACPI tables if the firmware
didn't provide its own device tree. ok patrick@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm64/stand/efiboot/Makefile11
-rw-r--r--sys/arch/arm64/stand/efiboot/acpi.dts56
-rw-r--r--sys/arch/arm64/stand/efiboot/dt_blob.S381
-rw-r--r--sys/arch/arm64/stand/efiboot/efiacpi.c650
-rw-r--r--sys/arch/arm64/stand/efiboot/efiboot.c5
-rw-r--r--sys/arch/arm64/stand/efiboot/efiboot.h3
6 files changed, 1101 insertions, 5 deletions
diff --git a/sys/arch/arm64/stand/efiboot/Makefile b/sys/arch/arm64/stand/efiboot/Makefile
index 49247115a75..36eecd6ca9c 100644
--- a/sys/arch/arm64/stand/efiboot/Makefile
+++ b/sys/arch/arm64/stand/efiboot/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.5 2018/04/08 13:27:22 kettenis Exp $
+# $OpenBSD: Makefile,v 1.6 2018/06/25 22:39:14 kettenis Exp $
NOMAN= #
@@ -8,8 +8,8 @@ PROG= BOOTAA64.EFI
OBJFMT= binary
INSTALL_STRIP=
BINDIR= /usr/mdec
-SRCS= start.S self_reloc.c efiboot.c conf.c exec.c efidev.c
-SRCS+= efipxe.c efirng.c fdt.c
+SRCS= start.S self_reloc.c efiboot.c conf.c exec.c efiacpi.c
+SRCS+= efidev.c efipxe.c efirng.c fdt.c dt_blob.S
S= ${.CURDIR}/../../../..
EFIDIR= ${S}/stand/efi
@@ -78,3 +78,8 @@ CLEANFILES+= machine
NOPROG=yes
.include <bsd.prog.mk>
.endif
+
+DTC= dtc
+DTCOPTS= -p 4096 -H epapr
+update-blob:
+ ${DTC} ${DTCOPTS} -O asm -o ${.CURDIR}/dt_blob.S ${.CURDIR}/acpi.dts
diff --git a/sys/arch/arm64/stand/efiboot/acpi.dts b/sys/arch/arm64/stand/efiboot/acpi.dts
new file mode 100644
index 00000000000..f392e48a86a
--- /dev/null
+++ b/sys/arch/arm64/stand/efiboot/acpi.dts
@@ -0,0 +1,56 @@
+/dts-v1/;
+
+/ {
+ model = "ACPI";
+ compatible = "openbsd,acpi";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ status = "disabled";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <0 0 0>, <0 0 0>, <0 0 0>, <0 0 0>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@0 {
+ compatible = "openbsd,gic";
+ #interrupt-cells = <3>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-controller;
+ ranges;
+ reg = <0x0 0x0 0x0 0x0>, <0x0 0x0 0x0 0x0>;
+ status = "disabled";
+ };
+
+ uart0: serial@0 {
+ compatible = "openbsd,uart";
+ reg = <0x0 0x0 0x0 0x0>;
+ status = "disabled";
+ };
+
+ acpi@0 {
+ compatible = "openbsd,acpi-5.0";
+ reg = <0x0 0x0 0x0 0x0>;
+ };
+};
diff --git a/sys/arch/arm64/stand/efiboot/dt_blob.S b/sys/arch/arm64/stand/efiboot/dt_blob.S
new file mode 100644
index 00000000000..9e42117e46c
--- /dev/null
+++ b/sys/arch/arm64/stand/efiboot/dt_blob.S
@@ -0,0 +1,381 @@
+/* autogenerated by dtc, do not edit */
+
+ .globl dt_blob_start
+dt_blob_start:
+_dt_blob_start:
+ .globl dt_header
+dt_header:
+_dt_header:
+ /* magic */
+ .byte 0xd0; .byte 0x0d; .byte 0xfe; .byte 0xed
+ /* totalsize */
+ .byte ((_dt_blob_abs_end - _dt_blob_start) >> 24) & 0xff
+ .byte ((_dt_blob_abs_end - _dt_blob_start) >> 16) & 0xff
+ .byte ((_dt_blob_abs_end - _dt_blob_start) >> 8) & 0xff
+ .byte (_dt_blob_abs_end - _dt_blob_start) & 0xff
+ /* off_dt_struct */
+ .byte ((_dt_struct_start - _dt_blob_start) >> 24) & 0xff
+ .byte ((_dt_struct_start - _dt_blob_start) >> 16) & 0xff
+ .byte ((_dt_struct_start - _dt_blob_start) >> 8) & 0xff
+ .byte (_dt_struct_start - _dt_blob_start) & 0xff
+ /* off_dt_strings */
+ .byte ((_dt_strings_start - _dt_blob_start) >> 24) & 0xff
+ .byte ((_dt_strings_start - _dt_blob_start) >> 16) & 0xff
+ .byte ((_dt_strings_start - _dt_blob_start) >> 8) & 0xff
+ .byte (_dt_strings_start - _dt_blob_start) & 0xff
+ /* off_mem_rsvmap */
+ .byte ((_dt_reserve_map - _dt_blob_start) >> 24) & 0xff
+ .byte ((_dt_reserve_map - _dt_blob_start) >> 16) & 0xff
+ .byte ((_dt_reserve_map - _dt_blob_start) >> 8) & 0xff
+ .byte (_dt_reserve_map - _dt_blob_start) & 0xff
+ /* version */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11
+ /* last_comp_version */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10
+ /* boot_cpuid_phys */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ /* size_dt_strings */
+ .byte ((_dt_strings_end - _dt_strings_start) >> 24) & 0xff
+ .byte ((_dt_strings_end - _dt_strings_start) >> 16) & 0xff
+ .byte ((_dt_strings_end - _dt_strings_start) >> 8) & 0xff
+ .byte (_dt_strings_end - _dt_strings_start) & 0xff
+ /* size_dt_struct */
+ .byte ((_dt_struct_end - _dt_struct_start) >> 24) & 0xff
+ .byte ((_dt_struct_end - _dt_struct_start) >> 16) & 0xff
+ .byte ((_dt_struct_end - _dt_struct_start) >> 8) & 0xff
+ .byte (_dt_struct_end - _dt_struct_start) & 0xff
+ .balign 8, 0
+ .globl dt_reserve_map
+dt_reserve_map:
+_dt_reserve_map:
+/* Memory reserve map from source file */
+ .long 0, 0
+ .long 0, 0
+ .globl dt_struct_start
+dt_struct_start:
+_dt_struct_start:
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string ""
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x05
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x41; .byte 0x43; .byte 0x50; .byte 0x49
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0d
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06
+ .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e
+ .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c
+ .byte 0x61; .byte 0x63; .byte 0x70; .byte 0x69
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x22
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x31
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .balign 4, 0
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "chosen"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x3d
+ .byte 0x73; .byte 0x65; .byte 0x72; .byte 0x69
+ .byte 0x61; .byte 0x6c; .byte 0x30; .byte 0x3a
+ .byte 0x31; .byte 0x31; .byte 0x35; .byte 0x32
+ .byte 0x30; .byte 0x30; .byte 0x6e; .byte 0x38
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "aliases"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0a
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x49
+ .byte 0x2f; .byte 0x73; .byte 0x65; .byte 0x72
+ .byte 0x69; .byte 0x61; .byte 0x6c; .byte 0x40
+ .byte 0x30
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "cpus"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x22
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x31
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "psci"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0d
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06
+ .byte 0x61; .byte 0x72; .byte 0x6d; .byte 0x2c
+ .byte 0x70; .byte 0x73; .byte 0x63; .byte 0x69
+ .byte 0x2d; .byte 0x31; .byte 0x2e; .byte 0x30
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x51
+ .byte 0x73; .byte 0x6d; .byte 0x63; .byte 0x00
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58
+ .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61
+ .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "timer"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06
+ .byte 0x61; .byte 0x72; .byte 0x6d; .byte 0x2c
+ .byte 0x61; .byte 0x72; .byte 0x6d; .byte 0x76
+ .byte 0x38; .byte 0x2d; .byte 0x74; .byte 0x69
+ .byte 0x6d; .byte 0x65; .byte 0x72; .byte 0x00
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x30
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x5f
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58
+ .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61
+ .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .globl gic
+gic:
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "interrupt-controller@0"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0c
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06
+ .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e
+ .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c
+ .byte 0x67; .byte 0x69; .byte 0x63; .byte 0x00
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x6a
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x22
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x31
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x7b
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x90
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x20
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x97
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58
+ .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61
+ .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x9b
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .globl gic_end
+gic_end:
+ .globl uart0
+uart0:
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "serial@0"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0d
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06
+ .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e
+ .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c
+ .byte 0x75; .byte 0x61; .byte 0x72; .byte 0x74
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x97
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58
+ .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61
+ .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ .globl uart0_end
+uart0_end:
+ /* FDT_BEGIN_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01
+ .string "acpi@0"
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06
+ .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e
+ .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c
+ .byte 0x61; .byte 0x63; .byte 0x70; .byte 0x69
+ .byte 0x2d; .byte 0x35; .byte 0x2e; .byte 0x30
+ .byte 0x0
+ .balign 4, 0
+ /* FDT_PROP */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x97
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00
+ .balign 4, 0
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ /* FDT_END_NODE */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02
+ /* FDT_END */
+ .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09
+ .globl dt_struct_end
+dt_struct_end:
+_dt_struct_end:
+ .globl dt_strings_start
+dt_strings_start:
+_dt_strings_start:
+ .string "model"
+ .string "compatible"
+ .string "interrupt-parent"
+ .string "#address-cells"
+ .string "#size-cells"
+ .string "stdout-path"
+ .string "serial0"
+ .string "method"
+ .string "status"
+ .string "interrupts"
+ .string "#interrupt-cells"
+ .string "interrupt-controller"
+ .string "ranges"
+ .string "reg"
+ .string "phandle"
+ .globl dt_strings_end
+dt_strings_end:
+_dt_strings_end:
+ .globl dt_blob_end
+dt_blob_end:
+_dt_blob_end:
+ .space 4096, 0
+ .globl dt_blob_abs_end
+dt_blob_abs_end:
+_dt_blob_abs_end:
diff --git a/sys/arch/arm64/stand/efiboot/efiacpi.c b/sys/arch/arm64/stand/efiboot/efiacpi.c
new file mode 100644
index 00000000000..703b2e2b80b
--- /dev/null
+++ b/sys/arch/arm64/stand/efiboot/efiacpi.c
@@ -0,0 +1,650 @@
+/* $OpenBSD: efiacpi.c,v 1.1 2018/06/25 22:39:14 kettenis Exp $ */
+
+/*
+ * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+
+#include <efi.h>
+#include <efiapi.h>
+
+#include "eficall.h"
+#include "fdt.h"
+#include "libsa.h"
+
+#define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID))
+
+#define fdt_node_add_string_property(n, p, s) \
+ fdt_node_add_property((n), (p), (s), strlen((s)) + 1)
+#define fdt_node_set_string_property(n, p, s) \
+ fdt_node_set_property((n), (p), (s), strlen((s)) + 1)
+
+extern EFI_SYSTEM_TABLE *ST;
+
+/* ACPI tables */
+
+struct acpi_rsdp1 {
+ uint8_t signature[8];
+#define RSDP_SIG "RSD PTR "
+#define rsdp_signature rsdp1.signature
+ uint8_t checksum; /* make sum == 0 */
+#define rsdp_checksum rsdp1.checksum
+ uint8_t oemid[6];
+#define rsdp_oemid rsdp1.oemid
+ uint8_t revision; /* 0 for 1, 2 for 2 */
+#define rsdp_revision rsdp1.revision
+ uint32_t rsdt; /* physical */
+#define rsdp_rsdt rsdp1.rsdt
+} __packed;
+
+struct acpi_rsdp {
+ struct acpi_rsdp1 rsdp1;
+ /*
+ * The following values are only valid
+ * when rsdp_revision == 2
+ */
+ uint32_t rsdp_length; /* length of rsdp */
+ uint64_t rsdp_xsdt; /* physical */
+ uint8_t rsdp_extchecksum; /* entire table */
+ uint8_t rsdp_reserved[3]; /* must be zero */
+} __packed;
+
+struct acpi_table_header {
+ uint8_t signature[4];
+#define hdr_signature hdr.signature
+ uint32_t length;
+#define hdr_length hdr.length
+ uint8_t revision;
+#define hdr_revision hdr.revision
+ uint8_t checksum;
+#define hdr_checksum hdr.checksum
+ uint8_t oemid[6];
+#define hdr_oemid hdr.oemid
+ uint8_t oemtableid[8];
+#define hdr_oemtableid hdr.oemtableid
+ uint32_t oemrevision;
+#define hdr_oemrevision hdr.oemrevision
+ uint8_t aslcompilerid[4];
+#define hdr_aslcompilerid hdr.aslcompilerid
+ uint32_t aslcompilerrevision;
+#define hdr_aslcompilerrevision hdr.aslcompilerrevision
+} __packed;
+
+struct acpi_xsdt {
+ struct acpi_table_header hdr;
+#define XSDT_SIG "XSDT"
+ uint64_t table_offsets[1];
+} __packed;
+
+struct acpi_gas {
+ uint8_t address_space_id;
+#define GAS_SYSTEM_MEMORY 0
+#define GAS_SYSTEM_IOSPACE 1
+#define GAS_PCI_CFG_SPACE 2
+#define GAS_EMBEDDED 3
+#define GAS_SMBUS 4
+#define GAS_FUNCTIONAL_FIXED 127
+ uint8_t register_bit_width;
+ uint8_t register_bit_offset;
+ uint8_t access_size;
+#define GAS_ACCESS_UNDEFINED 0
+#define GAS_ACCESS_BYTE 1
+#define GAS_ACCESS_WORD 2
+#define GAS_ACCESS_DWORD 3
+#define GAS_ACCESS_QWORD 4
+ uint64_t address;
+} __packed;
+
+struct acpi_fadt {
+ struct acpi_table_header hdr;
+#define FADT_SIG "FACP"
+ uint32_t firmware_ctl; /* phys addr FACS */
+ uint32_t dsdt; /* phys addr DSDT */
+ uint8_t int_model; /* interrupt model (hdr_revision < 3) */
+#define FADT_INT_DUAL_PIC 0
+#define FADT_INT_MULTI_APIC 1
+ uint8_t pm_profile; /* power mgmt profile */
+#define FADT_PM_UNSPEC 0
+#define FADT_PM_DESKTOP 1
+#define FADT_PM_MOBILE 2
+#define FADT_PM_WORKSTATION 3
+#define FADT_PM_ENT_SERVER 4
+#define FADT_PM_SOHO_SERVER 5
+#define FADT_PM_APPLIANCE 6
+#define FADT_PM_PERF_SERVER 7
+ uint16_t sci_int; /* SCI interrupt */
+ uint32_t smi_cmd; /* SMI command port */
+ uint8_t acpi_enable; /* value to enable */
+ uint8_t acpi_disable; /* value to disable */
+ uint8_t s4bios_req; /* value for S4 */
+ uint8_t pstate_cnt; /* value for performance (hdr_revision > 2) */
+ uint32_t pm1a_evt_blk; /* power management 1a */
+ uint32_t pm1b_evt_blk; /* power mangement 1b */
+ uint32_t pm1a_cnt_blk; /* pm control 1a */
+ uint32_t pm1b_cnt_blk; /* pm control 1b */
+ uint32_t pm2_cnt_blk; /* pm control 2 */
+ uint32_t pm_tmr_blk;
+ uint32_t gpe0_blk;
+ uint32_t gpe1_blk;
+ uint8_t pm1_evt_len;
+ uint8_t pm1_cnt_len;
+ uint8_t pm2_cnt_len;
+ uint8_t pm_tmr_len;
+ uint8_t gpe0_blk_len;
+ uint8_t gpe1_blk_len;
+ uint8_t gpe1_base;
+ uint8_t cst_cnt; /* (hdr_revision > 2) */
+ uint16_t p_lvl2_lat;
+ uint16_t p_lvl3_lat;
+ uint16_t flush_size;
+ uint16_t flush_stride;
+ uint8_t duty_offset;
+ uint8_t duty_width;
+ uint8_t day_alrm;
+ uint8_t mon_alrm;
+ uint8_t century;
+ uint16_t iapc_boot_arch; /* (hdr_revision > 2) */
+#define FADT_LEGACY_DEVICES 0x0001 /* Legacy devices supported */
+#define FADT_i8042 0x0002 /* Keyboard controller present */
+#define FADT_NO_VGA 0x0004 /* Do not probe VGA */
+ uint8_t reserved1;
+ uint32_t flags;
+#define FADT_WBINVD 0x00000001
+#define FADT_WBINVD_FLUSH 0x00000002
+#define FADT_PROC_C1 0x00000004
+#define FADT_P_LVL2_UP 0x00000008
+#define FADT_PWR_BUTTON 0x00000010
+#define FADT_SLP_BUTTON 0x00000020
+#define FADT_FIX_RTC 0x00000040
+#define FADT_RTC_S4 0x00000080
+#define FADT_TMR_VAL_EXT 0x00000100
+#define FADT_DCK_CAP 0x00000200
+#define FADT_RESET_REG_SUP 0x00000400
+#define FADT_SEALED_CASE 0x00000800
+#define FADT_HEADLESS 0x00001000
+#define FADT_CPU_SW_SLP 0x00002000
+#define FADT_PCI_EXP_WAK 0x00004000
+#define FADT_USE_PLATFORM_CLOCK 0x00008000
+#define FADT_S4_RTC_STS_VALID 0x00010000
+#define FADT_REMOTE_POWER_ON_CAPABLE 0x00020000
+#define FADT_FORCE_APIC_CLUSTER_MODEL 0x00040000
+#define FADT_FORCE_APIC_PHYS_DEST_MODE 0x00080000
+#define FADT_HW_REDUCED_ACPI 0x00100000
+#define FADT_POWER_S0_IDLE_CAPABLE 0x00200000
+ /*
+ * Following values only exist when rev > 1
+ * If the extended addresses exists, they
+ * must be used in preferense to the non-
+ * extended values above
+ */
+ struct acpi_gas reset_reg;
+ uint8_t reset_value;
+ uint16_t arm_boot_arch; /* (hdr_revision > 3) */
+#define FADT_PSCI_COMPLIANT 0x0001 /* PSCI is implemented */
+#define FADT_PSCI_USE_HVC 0x0002 /* HVC used as PSCI conduit */
+ uint8_t reserved2;
+ uint64_t x_firmware_ctl;
+ uint64_t x_dsdt;
+ struct acpi_gas x_pm1a_evt_blk;
+ struct acpi_gas x_pm1b_evt_blk;
+ struct acpi_gas x_pm1a_cnt_blk;
+ struct acpi_gas x_pm1b_cnt_blk;
+ struct acpi_gas x_pm2_cnt_blk;
+ struct acpi_gas x_pm_tmr_blk;
+ struct acpi_gas x_gpe0_blk;
+ struct acpi_gas x_gpe1_blk;
+ struct acpi_gas sleep_control_reg;
+ struct acpi_gas sleep_status_reg;
+} __packed;
+
+struct acpi_gtdt {
+ struct acpi_table_header hdr;
+#define GTDT_SIG "GTDT"
+ uint64_t cnt_ctrl_base;
+ uint32_t reserved;
+ uint32_t sec_el1_interrupt;
+ uint32_t sec_el1_flags;
+#define ACPI_GTDT_TIMER_TRIGGER_EDGE 0x1
+#define ACPI_GTDT_TIMER_POLARITY_LOW 0x2
+#define ACPI_GTDT_TIMER_ALWAYS_ON 0x4
+ uint32_t nonsec_el1_interrupt;
+ uint32_t nonsec_el1_flags;
+ uint32_t virt_interrupt;
+ uint32_t virt_flags;
+ uint32_t nonsec_el2_interrupt;
+ uint32_t nonsec_el2_flags;
+ uint64_t cnt_read_base;
+ uint32_t platform_timer_count;
+ uint32_t plaform_timer_offset;
+} __packed;
+
+struct acpi_madt {
+ struct acpi_table_header hdr;
+#define MADT_SIG "APIC"
+ uint32_t local_apic_address;
+ uint32_t flags;
+#define ACPI_APIC_PCAT_COMPAT 0x00000001
+} __packed;
+
+struct acpi_madt_gic {
+ uint8_t apic_type;
+#define ACPI_MADT_GIC 11
+ uint8_t length;
+ uint16_t reserved1;
+ uint32_t gic_id;
+ uint32_t acpi_proc_uid;
+ uint32_t flags;
+#define ACPI_PROC_ENABLE 0x00000001
+ uint32_t parking_protocol_version;
+ uint32_t performance_interrupt;
+ uint64_t parked_address;
+ uint64_t base_address;
+ uint64_t gicv_base_address;
+ uint64_t gich_base_address;
+ uint32_t maintenance_interrupt;
+ uint64_t gicr_base_address;
+ uint64_t mpidr;
+ uint8_t efficiency_class;
+ uint8_t reserved2[3];
+} __packed;
+
+struct acpi_madt_gicd {
+ uint8_t apic_type;
+#define ACPI_MADT_GICD 12
+ uint8_t length;
+ uint16_t reserved1;
+ uint32_t gic_id;
+ uint64_t base_address;
+ uint32_t interrupt_base;
+ uint8_t version;
+ uint8_t reserved2[3];
+} __packed;
+
+struct acpi_madt_gic_msi {
+ uint8_t apic_type;
+#define ACPI_MADT_GIC_MSI 13
+ uint8_t length;
+ uint16_t reserved1;
+ uint32_t msi_frame_id;
+ uint64_t base_address;
+ uint32_t flags;
+#define ACPI_MADT_GIC_MSI_SPI_SELECT 0x00000001
+ uint16_t spi_count;
+ uint16_t spi_base;
+} __packed;
+
+union acpi_madt_entry {
+ struct acpi_madt_gic madt_gic;
+ struct acpi_madt_gicd madt_gicd;
+ struct acpi_madt_gic_msi madt_gic_msi;
+} __packed;
+
+struct acpi_spcr {
+ struct acpi_table_header hdr;
+#define SPCR_SIG "SPCR"
+ uint8_t interface_type;
+#define SPCR_16550 0
+#define SPCR_16450 1
+#define SPCR_ARM_PL011 3
+#define SPCR_ARM_SBSA 14
+ uint8_t reserved1[3];
+ struct acpi_gas base_address;
+ uint8_t interrupt_type;
+ uint8_t irq;
+ uint32_t gsiv;
+ uint8_t baud_rate;
+ uint8_t parity;
+ uint8_t stop_bits;
+ uint8_t flow_control;
+ uint8_t terminal_type;
+ uint8_t reserved2;
+ uint16_t pci_device_id;
+ uint16_t pci_vendor_id;
+ uint8_t pci_bus;
+ uint8_t pci_device;
+ uint8_t pci_function;
+ uint32_t pci_flags;
+ uint8_t pci_segment;
+ uint32_t reserved3;
+};
+
+/* We'll never see ACPI 1.0 tables on ARM. */
+static EFI_GUID acpi_guid = ACPI_20_TABLE_GUID;
+
+void
+efi_acpi_fadt(struct acpi_table_header *hdr)
+{
+ struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
+ void *node;
+
+ /* The PSCI flags were introduced in ACPI 6.0. */
+ if (fadt->hdr_revision < 6)
+ return;
+
+ node = fdt_find_node("/psci");
+ if (fadt->arm_boot_arch & FADT_PSCI_COMPLIANT)
+ fdt_node_set_string_property(node, "status", "okay");
+ if (fadt->arm_boot_arch & FADT_PSCI_USE_HVC)
+ fdt_node_set_string_property(node, "method", "hvc");
+}
+
+void
+efi_acpi_gtdt(struct acpi_table_header *hdr)
+{
+ struct acpi_gtdt *gtdt = (struct acpi_gtdt *)hdr;
+ const uint32_t map[] = { 0x4, 0x1, 0x8, 0x2 };
+ const uint32_t mask = ACPI_GTDT_TIMER_TRIGGER_EDGE |
+ ACPI_GTDT_TIMER_POLARITY_LOW;
+ uint32_t interrupts[12];
+ void *node;
+
+ /* All interrupts are supposed to be PPIs. */
+ interrupts[0] = htobe32(1);
+ interrupts[1] = htobe32(gtdt->sec_el1_interrupt - 16);
+ interrupts[2] = htobe32(map[gtdt->sec_el1_flags & mask]);
+ interrupts[3] = htobe32(1);
+ interrupts[4] = htobe32(gtdt->nonsec_el1_interrupt - 16);
+ interrupts[5] = htobe32(map[gtdt->nonsec_el1_flags & mask]);
+ interrupts[6] = htobe32(1);
+ interrupts[7] = htobe32(gtdt->virt_interrupt - 16);
+ interrupts[8] = htobe32(map[gtdt->virt_flags & mask]);
+ interrupts[9] = htobe32(1);
+ interrupts[10] = htobe32(gtdt->nonsec_el2_interrupt - 16);
+ interrupts[11] = htobe32(map[gtdt->virt_flags & mask]);
+
+ node = fdt_find_node("/timer");
+ fdt_node_set_property(node, "interrupts",
+ interrupts, sizeof(interrupts));
+ fdt_node_set_string_property(node, "status", "okay");
+}
+
+static int gic_version;
+static uint64_t gicc_base;
+static uint64_t gicd_base;
+static uint64_t gicr_base;
+
+void
+efi_acpi_madt_gic(struct acpi_madt_gic *gic, uint8_t revision)
+{
+ uint64_t mpidr = gic->mpidr;
+ void *node, *child;
+ uint64_t reg;
+ char name[32];
+
+ /*
+ * MPIDR field was introduced in ACPI 6.0. Fall back on the
+ * ACPI Processor UID on ACPI 5.x.
+ */
+ mpidr = (revision > 3) ? gic->mpidr : gic->acpi_proc_uid;
+
+ snprintf(name, sizeof(name), "cpu@%llx", mpidr);
+ reg = htobe64(mpidr);
+
+ /* Create "cpu" node. */
+ node = fdt_find_node("/cpus");
+ fdt_node_add_node(node, name, &child);
+ fdt_node_add_string_property(child, "device_type", "cpu");
+ fdt_node_add_string_property(child, "compatible", "arm,armv8");
+ fdt_node_add_property(child, "reg", &reg, sizeof(reg));
+ if (gic->parking_protocol_version == 0)
+ fdt_node_add_string_property(child, "enable-method", "psci");
+ if ((gic->flags & ACPI_PROC_ENABLE) == 0)
+ fdt_node_add_string_property(child, "status", "disabled");
+
+ /* Stash GIC information. */
+ gicc_base = gic->base_address;
+ if (revision > 3)
+ gicr_base = gic->gicr_base_address;
+}
+
+void
+efi_acpi_madt_gicd(struct acpi_madt_gicd *gicd)
+{
+ /* Stash GIC information. */
+ gic_version = gicd->version;
+ gicd_base = gicd->base_address;
+}
+
+void
+efi_acpi_madt_gic_msi(struct acpi_madt_gic_msi *msi)
+{
+ void *node, *child;
+ uint64_t reg[2];
+ char name[32];
+
+ snprintf(name, sizeof(name), "v2m@%llx", msi->base_address);
+ reg[0] = htobe64(msi->base_address);
+ reg[1] = htobe64(0x1000);
+
+ /* Create "v2m" node. */
+ node = fdt_find_node("/interrupt-controller");
+ fdt_node_add_node(node, name, &child);
+ fdt_node_add_string_property(child, "compatible", "arm,gic-v2m-frame");
+ fdt_node_add_property(child, "msi-controller", NULL, 0);
+ fdt_node_add_property(child, "reg", reg, sizeof(reg));
+ if (msi->flags & ACPI_MADT_GIC_MSI_SPI_SELECT) {
+ uint32_t spi_base = msi->spi_base;
+ uint32_t spi_count = msi->spi_count;
+
+ fdt_node_add_property(child, "arm,msi-base-spi",
+ &spi_base, sizeof(spi_base));
+ fdt_node_add_property(child, "arm,msi-num-spis",
+ &spi_count, sizeof(spi_count));
+ }
+}
+
+void
+efi_acpi_madt(struct acpi_table_header *hdr)
+{
+ struct acpi_madt *madt = (struct acpi_madt *)hdr;
+ char *compat;
+ uint64_t reg[4];
+ char *addr;
+ void *node;
+
+ /* GIC support was introduced in ACPI 5.0. */
+ if (madt->hdr_revision < 3)
+ return;
+
+ addr = (char *)(madt + 1);
+ while (addr < (char *)madt + madt->hdr.length) {
+ union acpi_madt_entry *entry = (union acpi_madt_entry *)addr;
+ uint8_t length = entry->madt_gic.length;
+
+ if (length < 2)
+ return;
+
+ if (addr + length > (char *)madt + madt->hdr_length)
+ return;
+
+ switch (entry->madt_gic.apic_type) {
+ case ACPI_MADT_GIC:
+ efi_acpi_madt_gic(&entry->madt_gic, madt->hdr_revision);
+ break;
+ case ACPI_MADT_GICD:
+ efi_acpi_madt_gicd(&entry->madt_gicd);
+ break;
+ case ACPI_MADT_GIC_MSI:
+ efi_acpi_madt_gic_msi(&entry->madt_gic_msi);
+ break;
+ }
+
+ addr += length;
+ }
+
+ /*
+ * Now that we've collected all the necessary information, fix
+ * up the "interrupt-controller" node.
+ */
+
+ switch (gic_version) {
+ case 2:
+ /* GICv2 */
+ compat = "arm,gic-400";
+ reg[0] = htobe64(gicd_base);
+ reg[1] = htobe64(0x1000);
+ reg[2] = htobe64(gicc_base);
+ reg[3] = htobe64(0x100);
+ break;
+ case 3:
+ /* GICv3 */
+ compat = "arm,gic-v3";
+ reg[0] = htobe64(gicd_base);
+ reg[1] = htobe64(0x10000);
+ reg[2] = htobe64(gicr_base);
+ reg[3] = htobe64(0x10000);
+ break;
+ default:
+ return;
+ }
+
+ /* Update "interrupt-controller" node. */
+ node = fdt_find_node("/interrupt-controller");
+ fdt_node_set_string_property(node, "compatible", compat);
+ fdt_node_set_property(node, "reg", reg, sizeof(reg));
+ fdt_node_set_string_property(node, "status", "okay");
+}
+
+void
+efi_acpi_spcr(struct acpi_table_header *hdr)
+{
+ struct acpi_spcr *spcr = (struct acpi_spcr *)hdr;
+ uint64_t reg[2], reg_shift, reg_io_width;
+ void *node;
+
+ /* Minimal revision required by Server Base Boot Requirements is 2. */
+ if (spcr->hdr_revision < 2)
+ return;
+
+ /* No idea how to support anything else on ARM. */
+ if (spcr->base_address.address_space_id != GAS_SYSTEM_MEMORY)
+ return;
+
+ reg[0] = htobe64(spcr->base_address.address);
+
+ switch (spcr->base_address.access_size) {
+ case GAS_ACCESS_BYTE:
+ reg_io_width = 1;
+ break;
+ case GAS_ACCESS_WORD:
+ reg_io_width = 2;
+ break;
+ case GAS_ACCESS_DWORD:
+ reg_io_width = 4;
+ break;
+ case GAS_ACCESS_QWORD:
+ reg_io_width = 8;
+ break;
+ default:
+ return;
+ }
+ reg_io_width = htobe32(reg_io_width);
+
+ reg_shift = 0;
+ if (spcr->base_address.register_bit_width > 8)
+ reg_shift = 1;
+ if (spcr->base_address.register_bit_width > 16)
+ reg_shift = 2;
+ if (spcr->base_address.register_bit_width > 32)
+ reg_shift = 3;
+ reg_shift = htobe32(reg_shift);
+
+ /* Update "serial" node. */
+ node = fdt_find_node("/serial");
+ switch (spcr->interface_type) {
+ case SPCR_16550:
+ case SPCR_16450:
+ fdt_node_set_string_property(node, "compatible",
+ "snps,dw-apb-uart");
+ fdt_node_add_property(node, "reg-shift",
+ &reg_shift, sizeof(reg_shift));
+ fdt_node_add_property(node, "reg-io-width",
+ &reg_io_width, sizeof(reg_io_width));
+ reg[1] = htobe64(0x100);
+ break;
+ case SPCR_ARM_PL011:
+ case SPCR_ARM_SBSA:
+ fdt_node_set_string_property(node, "compatible", "arm,pl011");
+ reg[1] = htobe64(0x1000);
+ break;
+ default:
+ return;
+ }
+ fdt_node_set_property(node, "reg", reg, sizeof(reg));
+}
+
+void *
+efi_acpi(void)
+{
+ extern u_char dt_blob_start[];
+ void *fdt = dt_blob_start;
+ struct acpi_table_header *hdr;
+ struct acpi_rsdp *rsdp = NULL;
+ struct acpi_xsdt *xsdt;
+ uint64_t reg[2];
+ int i, ntables;
+ size_t len;
+ void *node;
+
+ for (i = 0; i < ST->NumberOfTableEntries; i++) {
+ if (efi_guidcmp(&acpi_guid,
+ &ST->ConfigurationTable[i].VendorGuid) == 0)
+ rsdp = ST->ConfigurationTable[i].VendorTable;
+ }
+
+ if (rsdp == NULL)
+ return NULL;
+
+ if (memcmp(rsdp->rsdp_signature, RSDP_SIG, 8) != 0 ||
+ rsdp->rsdp_revision < 2)
+ return NULL;
+
+ xsdt = (struct acpi_xsdt *)rsdp->rsdp_xsdt;
+ len = xsdt->hdr.length;
+ ntables = (len - sizeof(struct acpi_table_header)) /
+ sizeof(xsdt->table_offsets[0]);
+ if (ntables == 0)
+ return NULL;
+
+ if (!fdt_init(fdt))
+ return NULL;
+
+ for (i = 0; i < ntables; i++) {
+ hdr = (struct acpi_table_header *)xsdt->table_offsets[i];
+ printf("%c%c%c%c ", hdr->signature[0], hdr->signature[1],
+ hdr->signature[2], hdr->signature[3]);
+ if (memcmp(hdr->signature, FADT_SIG, 4) == 0)
+ efi_acpi_fadt(hdr);
+ if (memcmp(hdr->signature, GTDT_SIG, 4) == 0)
+ efi_acpi_gtdt(hdr);
+ if (memcmp(hdr->signature, MADT_SIG, 4) == 0)
+ efi_acpi_madt(hdr);
+ if (memcmp(hdr->signature, SPCR_SIG, 4) == 0)
+ efi_acpi_spcr(hdr);
+ }
+ printf("\n");
+
+ reg[0] = htobe64((uint64_t)rsdp);
+ reg[1] = htobe64(rsdp->rsdp_length);
+
+ /* Update "acpi" node. */
+ node = fdt_find_node("/acpi");
+ fdt_node_set_property(node, "reg", reg, sizeof(reg));
+
+ fdt_finalize();
+
+ return fdt;
+}
diff --git a/sys/arch/arm64/stand/efiboot/efiboot.c b/sys/arch/arm64/stand/efiboot/efiboot.c
index 9ced90a2b31..adf9b434457 100644
--- a/sys/arch/arm64/stand/efiboot/efiboot.c
+++ b/sys/arch/arm64/stand/efiboot/efiboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.c,v 1.16 2018/03/02 03:11:23 jsg Exp $ */
+/* $OpenBSD: efiboot.c,v 1.17 2018/06/25 22:39:14 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -380,6 +380,9 @@ efi_makebootargs(char *bootargs)
fdt = ST->ConfigurationTable[i].VendorTable;
}
+ if (fdt == NULL)
+ fdt = efi_acpi();
+
if (!fdt_init(fdt))
return NULL;
diff --git a/sys/arch/arm64/stand/efiboot/efiboot.h b/sys/arch/arm64/stand/efiboot/efiboot.h
index 8f69bb715a1..43888bc4908 100644
--- a/sys/arch/arm64/stand/efiboot/efiboot.h
+++ b/sys/arch/arm64/stand/efiboot/efiboot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.h,v 1.2 2018/01/21 21:35:34 patrick Exp $ */
+/* $OpenBSD: efiboot.h,v 1.3 2018/06/25 22:39:14 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -16,6 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+void *efi_acpi(void);
void efi_cleanup(void);
void efi_diskprobe(void);
void efi_pxeprobe(void);