summaryrefslogtreecommitdiff
path: root/sys/include
diff options
context:
space:
mode:
Diffstat (limited to 'sys/include')
-rw-r--r--sys/include/arch/aarch64/cdefs.h41
-rw-r--r--sys/include/arch/aarch64/cpu.h51
-rw-r--r--sys/include/arch/aarch64/exception.h54
-rw-r--r--sys/include/arch/aarch64/frame.h92
-rw-r--r--sys/include/arch/aarch64/frameasm.h89
-rw-r--r--sys/include/arch/aarch64/intr.h57
-rw-r--r--sys/include/arch/aarch64/pcb.h40
-rw-r--r--sys/include/arch/aarch64/pci/pci.h40
-rw-r--r--sys/include/arch/aarch64/pio.h43
-rw-r--r--sys/include/arch/aarch64/sync.h35
-rw-r--r--sys/include/arch/aarch64/syscall.h85
-rw-r--r--sys/include/arch/aarch64/vas.h45
-rw-r--r--sys/include/arch/amd64/bus.h8
-rw-r--r--sys/include/arch/amd64/cdefs.h10
-rw-r--r--sys/include/arch/amd64/cpu.h9
-rw-r--r--sys/include/arch/amd64/frame.h2
-rw-r--r--sys/include/arch/amd64/frameasm.h10
-rw-r--r--sys/include/arch/amd64/gdt.h79
-rw-r--r--sys/include/arch/amd64/intr.h52
-rw-r--r--sys/include/arch/amd64/ioapic.h3
-rw-r--r--sys/include/arch/amd64/isa/i8042var.h2
-rw-r--r--sys/include/arch/amd64/pci/pci.h40
-rw-r--r--sys/include/arch/amd64/syscall.h105
-rw-r--r--sys/include/dev/acpi/acpi.h7
-rw-r--r--sys/include/dev/acpi/tables.h61
-rw-r--r--sys/include/dev/acpi/uacpi.h35
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/acpi.h1430
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/context.h53
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/event.h286
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/helpers.h12
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/compiler.h3
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/context.h155
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/dynamic_array.h185
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/event.h25
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/helpers.h7
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/interpreter.h24
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/io.h77
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/log.h23
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/mutex.h82
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/namespace.h123
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/notify.h13
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/opcodes.h1390
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/opregion.h49
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/osi.h8
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/registers.h7
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/resources.h327
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/shareable.h21
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/stdlib.h131
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/tables.h70
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/types.h310
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/internal/utilities.h45
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/io.h36
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/kernel_api.h375
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/log.h40
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/namespace.h186
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/notify.h30
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/opregion.h47
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/osi.h125
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/platform/arch_helpers.h38
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/platform/atomic.h347
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/platform/compiler.h123
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/platform/config.h162
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/platform/libc.h28
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/platform/types.h64
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/registers.h105
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/resources.h740
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/sleep.h67
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/status.h57
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/tables.h141
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/types.h547
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/uacpi.h269
-rw-r--r--sys/include/dev/acpi/uacpi/uacpi/utilities.h188
-rw-r--r--sys/include/dev/cons/ansi.h75
-rw-r--r--sys/include/dev/cons/cons.h12
-rw-r--r--sys/include/dev/cons/consvar.h86
-rw-r--r--sys/include/dev/dmi/dmi.h40
-rw-r--r--sys/include/dev/ic/ahciregs.h36
-rw-r--r--sys/include/dev/ic/ahcivar.h198
-rw-r--r--sys/include/dev/pci/pci.h6
-rw-r--r--sys/include/dev/phy/e1000regs.h119
-rw-r--r--sys/include/dev/phy/rtl.h (renamed from sys/include/dev/phy/rt8139.h)16
-rw-r--r--sys/include/dev/timer.h1
-rw-r--r--sys/include/dev/usb/xhciregs.h7
-rw-r--r--sys/include/dev/usb/xhcivar.h5
-rw-r--r--sys/include/dev/video/fbdev.h2
-rw-r--r--sys/include/fs/ctlfs.h64
-rw-r--r--sys/include/fs/tmpfs.h73
-rw-r--r--sys/include/lib/stdbool.h38
-rw-r--r--sys/include/lib/stddef.h36
-rw-r--r--sys/include/lib/stdint.h36
-rw-r--r--sys/include/lib/string.h1
-rw-r--r--sys/include/net/ethertypes.h36
-rw-r--r--sys/include/net/if.h35
-rw-r--r--sys/include/net/if_arp.h51
-rw-r--r--sys/include/net/if_var.h82
-rw-r--r--sys/include/net/netbuf.h40
-rw-r--r--sys/include/netinet/if_ether.h56
-rw-r--r--sys/include/sys/bitops.h52
-rw-r--r--sys/include/sys/cdefs.h2
-rw-r--r--sys/include/sys/device.h9
-rw-r--r--sys/include/sys/disklabel.h48
-rw-r--r--sys/include/sys/driver.h56
-rw-r--r--sys/include/sys/elf.h66
-rw-r--r--sys/include/sys/endian.h54
-rw-r--r--sys/include/sys/exec.h3
-rw-r--r--sys/include/sys/fbdev.h40
-rw-r--r--sys/include/sys/fcntl.h1
-rw-r--r--sys/include/sys/filedesc.h11
-rw-r--r--sys/include/sys/krq.h40
-rw-r--r--sys/include/sys/limits.h5
-rw-r--r--sys/include/sys/mman.h24
-rw-r--r--sys/include/sys/mount.h4
-rw-r--r--sys/include/sys/namei.h3
-rw-r--r--sys/include/sys/param.h6
-rw-r--r--sys/include/sys/proc.h25
-rw-r--r--sys/include/sys/reboot.h9
-rw-r--r--sys/include/sys/sched.h4
-rw-r--r--sys/include/sys/schedvar.h2
-rw-r--r--sys/include/sys/spawn.h41
-rw-r--r--sys/include/sys/stat.h4
-rw-r--r--sys/include/sys/syscall.h85
-rw-r--r--sys/include/sys/syslog.h2
-rw-r--r--sys/include/sys/time.h60
-rw-r--r--sys/include/sys/types.h8
-rw-r--r--sys/include/sys/vfs.h1
-rw-r--r--sys/include/sys/vnode.h11
-rw-r--r--sys/include/vm/pmap.h16
-rw-r--r--sys/include/vm/vm_device.h43
128 files changed, 11408 insertions, 144 deletions
diff --git a/sys/include/arch/aarch64/cdefs.h b/sys/include/arch/aarch64/cdefs.h
new file mode 100644
index 0000000..aaf8649
--- /dev/null
+++ b/sys/include/arch/aarch64/cdefs.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _AARCH64_CDEFS_H_
+#define _AARCH64_CDEFS_H_
+
+#include <sys/cdefs.h>
+#include <machine/sync.h>
+
+#define md_pause() __ASMV("yield")
+#define md_intoff() __ASMV("msr daifset, #2")
+#define md_inton() __ASMV("msr daifclr, #2")
+#define md_hlt() __ASMV("hlt #0")
+
+#endif /* !_AARCH64_CDEFS_H_ */
diff --git a/sys/include/arch/aarch64/cpu.h b/sys/include/arch/aarch64/cpu.h
new file mode 100644
index 0000000..8c2d837
--- /dev/null
+++ b/sys/include/arch/aarch64/cpu.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_CPU_H_
+#define _MACHINE_CPU_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/proc.h>
+
+struct cpu_info {
+ struct proc *curtd;
+ struct cpu_info *self;
+};
+
+__dead void cpu_halt_all(void);
+void cpu_startup(struct cpu_info *ci);
+void cpu_halt_others(void);
+
+void mp_bootstrap_aps(struct cpu_info *ci);
+struct cpu_info *this_cpu(void);
+
+extern struct cpu_info g_bsp_ci;
+
+#endif /* !_MACHINE_CPU_H_ */
diff --git a/sys/include/arch/aarch64/exception.h b/sys/include/arch/aarch64/exception.h
new file mode 100644
index 0000000..9e89c81
--- /dev/null
+++ b/sys/include/arch/aarch64/exception.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_EXCEPTION_H_
+#define _MACHINE_EXCEPTION_H_
+
+#include <sys/types.h>
+#include <machine/frame.h>
+
+/* Exception class */
+#define EC_UNKNOWN 0x00 /* Unknown type */
+#define EC_WF 0x01 /* Trapped WF instruction */
+#define EC_MCRMRC 0x03 /* Trapped MCR/MRC */
+#define EC_MCRRC 0x04 /* Trapped MCRR/MRRC */
+#define EC_LDCSTC 0x06 /* Trapped LDC/STC */
+#define EC_SVE 0x07 /* Trapped SVE/SIMD/FP op */
+#define EC_BRE 0x0D /* Branch target exception */
+#define EC_ILLX 0x0E /* Illegal execution state */
+#define EC_SVC64 0x15 /* AARCH64 SVC */
+#define EC_PCALIGN 0x22 /* PC alignment fault */
+#define EC_DABORT 0x24 /* Data abort (w/o ELx change) */
+#define EC_EDABORT 0x25 /* Data abort (w/ ELx change) */
+#define EC_SPALIGN 0x26 /* SP alignment fault */
+#define EC_SERR 0x2F /* System error (what the fuck!) */
+
+void handle_exception(struct trapframe *tf);
+
+#endif /* !_MACHINE_EXCEPTION_H_ */
diff --git a/sys/include/arch/aarch64/frame.h b/sys/include/arch/aarch64/frame.h
new file mode 100644
index 0000000..143f4d0
--- /dev/null
+++ b/sys/include/arch/aarch64/frame.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_FRAME_H_
+#define _MACHINE_FRAME_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+typedef uint64_t lreg_t;
+typedef uint64_t frament_t;
+
+/* Stack regs */
+struct sregs {
+ lreg_t sp_el0;
+ lreg_t sp_el1;
+ lreg_t sp_el2;
+};
+
+/* Program status */
+struct pstat {
+ lreg_t spsr_el1;
+ lreg_t spsr_el2;
+ lreg_t spsr_el3;
+};
+
+struct __aligned(16) trapframe {
+ lreg_t x30;
+ lreg_t x29;
+ lreg_t x28;
+ lreg_t x27;
+ lreg_t x26;
+ lreg_t x25;
+ lreg_t x24;
+ lreg_t x23;
+ lreg_t x22;
+ lreg_t x21;
+ lreg_t x20;
+ lreg_t x19;
+ lreg_t x18;
+ lreg_t x17;
+ lreg_t x16;
+ lreg_t x15;
+ lreg_t x14;
+ lreg_t x13;
+ lreg_t x12;
+ lreg_t x11;
+ lreg_t x10;
+ lreg_t x9;
+ lreg_t x8;
+ lreg_t x7;
+ lreg_t x6;
+ lreg_t x5;
+ lreg_t x4;
+ lreg_t x3;
+ lreg_t x2;
+ lreg_t x1;
+ lreg_t x0;
+ lreg_t elr;
+ lreg_t esr;
+ frament_t trapno;
+};
+
+#define TF_IP(TFP) ((TFP)->pc)
+
+#endif /* !_MACHINE_FRAME_H_ */
diff --git a/sys/include/arch/aarch64/frameasm.h b/sys/include/arch/aarch64/frameasm.h
new file mode 100644
index 0000000..ca7f81a
--- /dev/null
+++ b/sys/include/arch/aarch64/frameasm.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_FRAMEASM_H_
+#define _MACHINE_FRAMEASM_H_
+
+/* XXX: Must be 16-byte aligned!!! */
+#define XFRAME_STACK_SIZE (38 * 8)
+
+/* Trap numbers */
+#define TRAPNO_UNKNOWN #0
+#define TRAPNO_XSYNC #1 /* Synchronous */
+#define TRAPNO_XIRQ #2 /* IRQ */
+#define TRAPNO_XFIQ #3 /* FIQ */
+#define TRAPNO_XSERR #4 /* System error */
+
+#define PUSH_XFRAME(TRAPNO) \
+ sub sp, sp, #XFRAME_STACK_SIZE ; \
+ stp x30, x29, [sp, #(0 * 8)] ; \
+ stp x28, x27, [sp, #(2 * 8)] ; \
+ stp x26, x25, [sp, #(4 * 8)] ; \
+ stp x24, x23, [sp, #(6 * 8)] ; \
+ stp x22, x21, [sp, #(8 * 8)] ; \
+ stp x20, x19, [sp, #(10 * 8)] ; \
+ stp x18, x17, [sp, #(12 * 8)] ; \
+ stp x16, x15, [sp, #(14 * 8)] ; \
+ stp x14, x13, [sp, #(16 * 8)] ; \
+ stp x12, x11, [sp, #(18 * 8)] ; \
+ stp x10, x9, [sp, #(20 * 8)] ; \
+ stp x8, x7, [sp, #(22 * 8)] ; \
+ stp x6, x5, [sp, #(24 * 8)] ; \
+ stp x4, x3, [sp, #(26 * 8)] ; \
+ stp x2, x1, [sp, #(28 * 8)] ; \
+ str x0, [sp, #(30 * 8)] ; \
+ ; \
+ mrs x0, elr_el1 ; \
+ str x0, [sp, #(31 * 8)] ; \
+ mrs x0, esr_el1 ; \
+ str x0, [sp, #(32 * 8)] ; \
+ mov x0, TRAPNO ; \
+ str x0, [sp, #(33 * 8)] ; \
+ mov x0, sp
+
+#define POP_XFRAME() \
+ ldr x0, [sp, #(30 * 8)] ; \
+ ldp x2, x1, [sp, #(28 * 8)] ; \
+ ldp x4, x3, [sp, #(26 * 8)] ; \
+ ldp x6, x5, [sp, #(24 * 8)] ; \
+ ldp x8, x7, [sp, #(22 * 8)] ; \
+ ldp x10, x9, [sp, #(20 * 8)] ; \
+ ldp x12, x11, [sp, #(18 * 8)] ; \
+ ldp x14, x13, [sp, #(16 * 8)] ; \
+ ldp x16, x15, [sp, #(14 * 8)] ; \
+ ldp x18, x17, [sp, #(12 * 8)] ; \
+ ldp x20, x19, [sp, #(10 * 8)] ; \
+ ldp x22, x21, [sp, #(8 * 8)] ; \
+ ldp x24, x23, [sp, #(6 * 8)] ; \
+ ldp x26, x25, [sp, #(4 * 8)] ; \
+ ldp x28, x27, [sp, #(2 * 8)] ; \
+ ldp x30, x29, [sp, #(0 * 8)] ; \
+ add sp, sp, #XFRAME_STACK_SIZE
+
+#endif /* !_MACHINE_FRAMEASM_H_ */
diff --git a/sys/include/arch/aarch64/intr.h b/sys/include/arch/aarch64/intr.h
new file mode 100644
index 0000000..b85564f
--- /dev/null
+++ b/sys/include/arch/aarch64/intr.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_INTR_H_
+#define _MACHINE_INTR_H_
+
+#include <sys/types.h>
+
+/*
+ * Interrupt priority levels
+ */
+#define IPL_NONE 0 /* Don't defer anything */
+#define IPL_BIO 1 /* Block I/O */
+#define IPL_CLOCK 2 /* Clock */
+#define IPL_HIGH 3 /* Defer everything */
+
+struct intr_entry {
+ int priority;
+};
+
+struct intr_hand {
+ int(*func)(void *);
+ char *name;
+ int priority;
+ int irq;
+ int vector;
+};
+
+void *intr_register(const char *name, const struct intr_hand *ih);
+
+#endif /* !_MACHINE_INTR_H_ */
diff --git a/sys/include/arch/aarch64/pcb.h b/sys/include/arch/aarch64/pcb.h
new file mode 100644
index 0000000..f9a0b1a
--- /dev/null
+++ b/sys/include/arch/aarch64/pcb.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_PCB_H_
+#define _MACHINE_PCB_H_
+
+#include <sys/types.h>
+#include <vm/pmap.h>
+
+struct pcb {
+ struct vas addrsp;
+};
+
+#endif /* !_MACHINE_PCB_H_ */
diff --git a/sys/include/arch/aarch64/pci/pci.h b/sys/include/arch/aarch64/pci/pci.h
new file mode 100644
index 0000000..189a423
--- /dev/null
+++ b/sys/include/arch/aarch64/pci/pci.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_PCI_H_
+#define _MACHINE_PCI_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <dev/pci/pci.h>
+
+__weak pcireg_t md_pci_readl(struct pci_device *dev, uint32_t off);
+__weak void md_pci_writel(struct pci_device *dev, uint32_t off, pcireg_t val);
+
+#endif /* !_MACHINE_PCI_H_ */
diff --git a/sys/include/arch/aarch64/pio.h b/sys/include/arch/aarch64/pio.h
new file mode 100644
index 0000000..4aaeece
--- /dev/null
+++ b/sys/include/arch/aarch64/pio.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_PIO_H_
+#define _MACHINE_PIO_H_
+
+#include <sys/cdefs.h>
+
+#define inb(...) (uint8_t)0
+#define inw(...) (uint16_t)0
+#define inl(...) (uint32_t)0
+#define outb(...) __nothing
+#define outw(...) __nothing
+#define outl(...) __nothing
+
+
+#endif /* _MACHINE_PIO_H_ */
diff --git a/sys/include/arch/aarch64/sync.h b/sys/include/arch/aarch64/sync.h
new file mode 100644
index 0000000..f331f43
--- /dev/null
+++ b/sys/include/arch/aarch64/sync.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYNC_H_
+#define _MACHINE_SYNC_H_
+
+int md_sync_all(void);
+
+#endif /* !_MACHINE_SYNC_H_ */
diff --git a/sys/include/arch/aarch64/syscall.h b/sys/include/arch/aarch64/syscall.h
new file mode 100644
index 0000000..84a51e0
--- /dev/null
+++ b/sys/include/arch/aarch64/syscall.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYSCALL_H_
+#define _MACHINE_SYSCALL_H_
+
+#if !defined(__ASSEMBLER__)
+__always_inline static inline long
+syscall0(uint64_t code)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall1(uint64_t code, uint64_t arg0)
+{
+ return 0;
+}
+
+__always_inline static long inline
+syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
+{
+ return 0;
+}
+
+__always_inline static inline long
+syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
+{
+ return 0;
+}
+
+#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
+ name
+
+#define syscall(...) \
+_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
+ syscall4, syscall3, syscall2, syscall1, \
+ syscall0)(__VA_ARGS__)
+
+#endif /* !__ASSEMBLER__ */
+#endif /* !_MACHINE_SYSCALL_H_ */
diff --git a/sys/include/arch/aarch64/vas.h b/sys/include/arch/aarch64/vas.h
new file mode 100644
index 0000000..07cd576
--- /dev/null
+++ b/sys/include/arch/aarch64/vas.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_VAS_H_
+#define _MACHINE_VAS_H_
+
+#include <sys/types.h>
+#include <sys/spinlock.h>
+
+/*
+ * VAS structure - describes a virtual address space
+ */
+struct vas {
+ paddr_t ttbr0_el1; /* Lower half */
+ paddr_t ttbr1_el1; /* Higher half */
+ struct spinlock *lock;
+};
+
+#endif /* !_MACHINE_VAS_H_ */
diff --git a/sys/include/arch/amd64/bus.h b/sys/include/arch/amd64/bus.h
index 00cb3ba..25088b4 100644
--- a/sys/include/arch/amd64/bus.h
+++ b/sys/include/arch/amd64/bus.h
@@ -36,13 +36,7 @@
struct bus_resource;
-/*
- * Hyra assumes that the bootloader uses PDE[256] for some
- * higher half mappings. To avoid conflicts with those mappings,
- * this offset is used to start device memory at PDE[257]. This
- * will give us more than enough space.
- */
-#define MMIO_OFFSET (VM_HIGHER_HALF + 0x8000000000)
+#define MMIO_OFFSET VM_HIGHER_HALF
/* Resource signature size max */
#define RSIG_MAX 16
diff --git a/sys/include/arch/amd64/cdefs.h b/sys/include/arch/amd64/cdefs.h
index 256fd8b..0a20324 100644
--- a/sys/include/arch/amd64/cdefs.h
+++ b/sys/include/arch/amd64/cdefs.h
@@ -41,5 +41,15 @@
#define md_pause() __ASMV("rep; nop") /* (F3 90) PAUSE */
#define md_intoff() __ASMV("cli") /* Clear interrupts */
#define md_inton() __ASMV("sti") /* Enable interrupts */
+#define md_hlt() __ASMV("hlt") /* Halt the processor */
+
+/*
+ * AMD64 specific defines
+ */
+#define __invlpg(VA) \
+ __ASMV("invlpg %0" \
+ : \
+ : "m" ((VA)) \
+ : "memory")
#endif /* !_AMD64_CDEFS_H_ */
diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h
index ce42416..2d08d6e 100644
--- a/sys/include/arch/amd64/cpu.h
+++ b/sys/include/arch/amd64/cpu.h
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/proc.h>
+#include <sys/spinlock.h>
#include <machine/tss.h>
#define CPU_IRQ(IRQ_N) (BIT((IRQ_N)) & 0xFF)
@@ -40,17 +41,25 @@
struct cpu_info {
uint32_t apicid;
uint8_t has_x2apic : 1;
+ uint8_t tlb_shootdown : 1;
uint8_t ipl;
size_t lapic_tmr_freq;
uint8_t irq_mask;
+ vaddr_t shootdown_va;
struct tss_entry *tss;
struct proc *curtd;
+ struct spinlock lock;
struct cpu_info *self;
};
__dead void cpu_halt_all(void);
+void cpu_halt_others(void);
void cpu_startup(struct cpu_info *ci);
+struct cpu_info *cpu_get(uint32_t index);
+uint32_t cpu_count(void);
+void cpu_shootdown_tlb(vaddr_t va);
+
struct cpu_info *this_cpu(void);
void mp_bootstrap_aps(struct cpu_info *ci);
diff --git a/sys/include/arch/amd64/frame.h b/sys/include/arch/amd64/frame.h
index 31dcdef..2bd9a7c 100644
--- a/sys/include/arch/amd64/frame.h
+++ b/sys/include/arch/amd64/frame.h
@@ -58,4 +58,6 @@ struct trapframe {
uint64_t ss;
};
+#define TF_IP(TFP) ((TFP)->rip)
+
#endif /* !_MACHINE_FRAME_H_ */
diff --git a/sys/include/arch/amd64/frameasm.h b/sys/include/arch/amd64/frameasm.h
index 22217eb..4dc075e 100644
--- a/sys/include/arch/amd64/frameasm.h
+++ b/sys/include/arch/amd64/frameasm.h
@@ -30,6 +30,8 @@
#ifndef _MACHINE_FRAMEASM_H_
#define _MACHINE_FRAMEASM_H_
+#define ALIGN_TEXT .align 8, 0x90
+
/*
* If the interrupt has an error code, this macro shall
* be used to create the trapframe.
@@ -121,6 +123,7 @@
*/
#define TRAPENTRY_EC(ENTLABEL, TRAPNO) \
ENTLABEL: ; \
+ cli ; \
testq $0x3, 16(%rsp) ; \
jz 1f ; \
lfence ; \
@@ -133,7 +136,8 @@
jz 2f ; \
lfence ; \
swapgs ; \
- 2: iretq
+ 2: sti ; \
+ iretq
/*
* Trap entry where no error code is on
@@ -141,6 +145,7 @@
*/
#define TRAPENTRY(ENTLABEL, TRAPNO) \
ENTLABEL: ; \
+ cli ; \
testq $0x3, 8(%rsp) ; \
jz 1f ; \
lfence ; \
@@ -153,6 +158,7 @@
jz 2f ; \
lfence ; \
swapgs ; \
- 2: iretq
+ 2: sti ; \
+ iretq
#endif /* !_MACHINE_FRAMEASM_H_ */
diff --git a/sys/include/arch/amd64/gdt.h b/sys/include/arch/amd64/gdt.h
index f87416f..0c5faf1 100644
--- a/sys/include/arch/amd64/gdt.h
+++ b/sys/include/arch/amd64/gdt.h
@@ -4,18 +4,48 @@
#include <sys/types.h>
#include <sys/cdefs.h>
+#define GDT_TSS_INDEX 5
+#define GDT_ENTRY_COUNT 7
+
+/* Segment selectors */
#define KERNEL_CS 0x08
#define KERNEL_DS 0x10
-#define USER_CS 0x18
-#define USER_DS 0x20
-#define GDT_TSS 5
+#define USER_CS 0x18
+#define USER_DS 0x20
+
+/*
+ * Bit definitions for regular segment descriptors
+ *
+ * See Intel SPG 3/25 Section 3.4.5 - Segment Descriptors
+ */
+
+#define GDT_ATTRIBUTE_ACCESSED BIT(0) /* Accessed */
+#define GDT_ATTRIBUTE_EXECUTABLE BIT(3) /* Executable */
+#define GDT_ATTRIBUTE_NONSYSTEM BIT(4) /* Code/data */
+#define GDT_ATTRIBUTE_PRESENT BIT(7) /* Present */
+#define GDT_ATTRIBUTE_64BIT_CODE BIT(13) /* 64-bit code */
+#define GDT_ATTRIBUTE_32BIT BIT(14) /* 32-bit code/data */
+#define GDT_ATTRIBUTE_GRANULARITY BIT(15) /* 4KiB limit granularity */
+
+/* Attributes for executable segments */
+#define GDT_ATTRIBUTE_READABLE BIT(1) /* Readable */
+#define GDT_ATTRIBUTE_CONFORMING BIT(2) /* Conforming */
+
+/* Attributes for non-executable segments */
+#define GDT_ATTRIBUTE_WRITABLE BIT(1) /* Writable */
+#define GDT_ATTRIBUTE_EXPANDS_DOWN BIT(2) /* See SPG 3/25 Section 6.8.1 */
+
+/* DPL (Descriptor Privilege Level) specifier */
+#define GDT_ATTRIBUTE_DPL0 0
+#define GDT_ATTRIBUTE_DPL1 (1 << 5)
+#define GDT_ATTRIBUTE_DPL2 (2 << 5)
+#define GDT_ATTRIBUTE_DPL3 (3 << 5)
struct __packed gdt_entry {
uint16_t limit;
uint16_t base_low;
uint8_t base_mid;
- uint8_t access;
- uint8_t granularity;
+ uint16_t attributes;
uint8_t base_hi;
};
@@ -24,27 +54,28 @@ struct __packed gdtr {
uintptr_t offset;
};
+extern struct gdt_entry g_gdt_data[GDT_ENTRY_COUNT];
+extern const struct gdtr g_gdtr;
+
__always_inline static inline void
-gdt_load(struct gdtr *gdtr)
+gdt_load(void)
{
- __ASMV("lgdt %0\n"
- "push $8\n" /* Push CS */
- "lea 1f(%%rip), %%rax\n" /* Load 1 label address into RAX */
- "push %%rax\n" /* Push the return address (label 1) */
- "lretq\n" /* Far return to update CS */
- "1:\n"
- " mov $0x10, %%eax\n"
- " mov %%eax, %%ds\n"
- " mov %%eax, %%es\n"
- " mov %%eax, %%fs\n"
- " mov %%eax, %%gs\n"
- " mov %%eax, %%ss\n"
- :
- : "m" (*gdtr)
- : "rax", "memory"
- );
+ __ASMV("lgdt %0\n"
+ "push %1\n" /* Push code segment selector */
+ "lea 1f(%%rip), %%rax\n" /* Load label 1 address into RAX */
+ "push %%rax\n" /* Push return address (label 1) */
+ "lretq\n" /* Far return to update CS */
+ "1:\n"
+ " mov %2, %%ax\n" /* Load data segment selectors */
+ " mov %%ax, %%ds\n"
+ " mov %%ax, %%es\n"
+ " mov %%ax, %%fs\n"
+ " mov %%ax, %%gs\n"
+ " mov %%ax, %%ss\n"
+ :
+ : "m" (g_gdtr), "i"(KERNEL_CS), "i"(KERNEL_DS)
+ : "rax", "memory"
+ );
}
-extern struct gdt_entry g_gdt_data[256];
-
#endif /* !AMD64_GDT_H_ */
diff --git a/sys/include/arch/amd64/intr.h b/sys/include/arch/amd64/intr.h
index c643945..c848b6f 100644
--- a/sys/include/arch/amd64/intr.h
+++ b/sys/include/arch/amd64/intr.h
@@ -47,11 +47,59 @@
#define IPL_CLOCK 2 /* Clock */
#define IPL_HIGH 3 /* Defer everything */
-struct intr_entry {
+struct intr_hand;
+
+/*
+ * Contains information passed to driver
+ *
+ * @ihp: Interrupt handler
+ * @data: Driver specific data
+ */
+struct intr_data {
+ struct intr_hand *ihp;
+ union {
+ void *data;
+ uint64_t data_u64;
+ };
+};
+
+/*
+ * Interrupt handler
+ *
+ * [r]: Required for intr_register()
+ * [o]: Not required for intr_register()
+ * [v]: Returned by intr_register()
+ *
+ * @func: The actual handler [r]
+ * @data: Interrupt data [o/v]
+ * @name: Interrupt name [v]
+ * @priority: Interrupt priority [r]
+ * @irq: Interrupt request number [o]
+ * @vector: Interrupt vector [v]
+ *
+ * XXX: `name' must be null terminated ('\0')
+ *
+ * XXX: `irq` can be set to -1 for MSI/MSI-X
+ * interrupts.
+ *
+ * XXX: `func` must be the first field in this
+ * structure so that it may be called through
+ * assembly.
+ *
+ * XXX: `ist' should usually be set to -1 but can be
+ * used if an interrupt requires its own stack.
+ */
+struct intr_hand {
+ int(*func)(void *);
+ struct intr_data data;
+ char *name;
int priority;
+ int irq;
+ int vector;
};
-int intr_alloc_vector(const char *name, uint8_t priority);
+void *intr_register(const char *name, const struct intr_hand *ih);
+
int splraise(uint8_t s);
void splx(uint8_t s);
diff --git a/sys/include/arch/amd64/ioapic.h b/sys/include/arch/amd64/ioapic.h
index c11a85c..4cae800 100644
--- a/sys/include/arch/amd64/ioapic.h
+++ b/sys/include/arch/amd64/ioapic.h
@@ -31,7 +31,8 @@
#define _MACHINE_IOAPIC_H_
#include <sys/types.h>
-#include <dev/acpi/tables.h>
+
+struct ioapic;
void ioapic_init(struct ioapic *p);
void ioapic_gsi_mask(uint8_t gsi);
diff --git a/sys/include/arch/amd64/isa/i8042var.h b/sys/include/arch/amd64/isa/i8042var.h
index ebd96ad..13c3095 100644
--- a/sys/include/arch/amd64/isa/i8042var.h
+++ b/sys/include/arch/amd64/isa/i8042var.h
@@ -82,7 +82,5 @@ void i8042_quirk(int mask);
/* Internal - do not use */
void i8042_sync(void);
-void i8042_kb_isr(void);
-void i8042_kb_event(void);
#endif /* _I8042VAR_H_ */
diff --git a/sys/include/arch/amd64/pci/pci.h b/sys/include/arch/amd64/pci/pci.h
new file mode 100644
index 0000000..189a423
--- /dev/null
+++ b/sys/include/arch/amd64/pci/pci.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_PCI_H_
+#define _MACHINE_PCI_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <dev/pci/pci.h>
+
+__weak pcireg_t md_pci_readl(struct pci_device *dev, uint32_t off);
+__weak void md_pci_writel(struct pci_device *dev, uint32_t off, pcireg_t val);
+
+#endif /* !_MACHINE_PCI_H_ */
diff --git a/sys/include/arch/amd64/syscall.h b/sys/include/arch/amd64/syscall.h
new file mode 100644
index 0000000..cc401e9
--- /dev/null
+++ b/sys/include/arch/amd64/syscall.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SYSCALL_H_
+#define _MACHINE_SYSCALL_H_
+
+#if !defined(__ASSEMBLER__)
+__always_inline static inline long
+syscall0(uint64_t code)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code));
+ return ret;
+}
+
+__always_inline static inline long
+syscall1(uint64_t code, uint64_t arg0)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0) : "memory");
+ return ret;
+}
+
+__always_inline static long inline
+syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+ volatile long ret;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4) : "memory");
+ return ret;
+}
+
+__always_inline static inline long
+syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ register uint64_t _arg5 asm("r8") = arg5;
+ __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) : "memory");
+ return ret;
+}
+
+#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
+ name
+
+#define syscall(...) \
+_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
+ syscall4, syscall3, syscall2, syscall1, \
+ syscall0)(__VA_ARGS__)
+
+#endif /* !__ASSEMBLER__ */
+#endif /* !_MACHINE_SYSCALL_H_ */
diff --git a/sys/include/dev/acpi/acpi.h b/sys/include/dev/acpi/acpi.h
index 9cd6b87..5108748 100644
--- a/sys/include/dev/acpi/acpi.h
+++ b/sys/include/dev/acpi/acpi.h
@@ -30,8 +30,15 @@
#ifndef _ACPI_H_
#define _ACPI_H_
+#include <sys/types.h>
+
+#define ACPI_SLEEP_S5 0x00000000
+
const char *acpi_oemid(void);
void *acpi_query(const char *query);
+
+paddr_t acpi_rsdp(void);
+int acpi_sleep(int type);
void acpi_init(void);
#endif /* !_ACPI_H_ */
diff --git a/sys/include/dev/acpi/tables.h b/sys/include/dev/acpi/tables.h
index 5215c86..5340c7f 100644
--- a/sys/include/dev/acpi/tables.h
+++ b/sys/include/dev/acpi/tables.h
@@ -132,4 +132,65 @@ struct __packed acpi_hpet {
uint8_t page_protection;
};
+/*
+ * PCIe / ACPI MCFG base address description
+ * table.
+ *
+ * @base_pa: Enhanced configuration base [physical]
+ * @seg_grpno: PCI segment group number
+ * @bus_start: Host bridge bus start
+ * @bus_end: Host bridge bus end
+ */
+struct __packed acpi_mcfg_base {
+ uint64_t base_pa;
+ uint16_t seg_grpno;
+ uint8_t bus_start;
+ uint8_t bus_end;
+ uint32_t reserved;
+};
+
+/*
+ * PCIe / ACPI MCFG structure
+ *
+ * @hdr: ACPI header
+ * @reserved: Do not use
+ * @base: ECAM MMIO address list
+ */
+struct __packed acpi_mcfg {
+ struct acpi_header hdr;
+ uint32_t reserved[2];
+ struct acpi_mcfg_base base[1];
+};
+
+struct __packed dmi_entry32 {
+ char signature[4]; /* _SM_ */
+ uint8_t checksum; /* Sum of table bytes */
+ uint8_t length; /* Length of entry table */
+ uint8_t major; /* DMI major */
+ uint8_t minor; /* DMI minor */
+ uint16_t max_size; /* Max structure size */
+ uint8_t rev; /* Entry revision */
+ char fmt_area[5]; /* Formatted area */
+ char isignature[5]; /* Intermediate signature */
+ uint8_t ichecksum; /* Intermediate checksum */
+ uint16_t table_len; /* Length of SMBIOS structure table */
+ uint32_t addr; /* 32-bit physical start of SMBIOS structure table */
+ uint16_t nstruct; /* Total number of structures */
+ uint8_t bcd_rev;
+};
+
+struct __packed dmi_entry64 {
+ char signature[5]; /* _SM_ */
+ uint8_t checksum; /* Sum of table bytes */
+ uint8_t length; /* Length of entry table */
+ uint8_t major; /* DMI major */
+ uint8_t minor; /* DMI minor */
+ uint8_t docrev;
+ uint8_t entry_rev;
+ uint8_t reserved;
+ uint16_t max_size; /* Max structure size */
+ uint16_t padding;
+ uint64_t addr; /* 64-bit physical address */
+};
+
#endif /* _ACPI_TABLES_H_ */
diff --git a/sys/include/dev/acpi/uacpi.h b/sys/include/dev/acpi/uacpi.h
new file mode 100644
index 0000000..d38e087
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UACPI_BRIDGE_H_
+#define _UACPI_BRIDGE_H_
+
+int uacpi_init(void);
+
+#endif /* !_UACPI_BRIDGE_H_ */
diff --git a/sys/include/dev/acpi/uacpi/uacpi/acpi.h b/sys/include/dev/acpi/uacpi/uacpi/acpi.h
new file mode 100644
index 0000000..79eb31b
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/acpi.h
@@ -0,0 +1,1430 @@
+#pragma once
+
+#include <uacpi/platform/compiler.h>
+#include <uacpi/helpers.h>
+#include <uacpi/types.h>
+
+/*
+ * -----------------------------------------------------
+ * Common structures provided by the ACPI specification
+ * -----------------------------------------------------
+ */
+
+#define ACPI_RSDP_SIGNATURE "RSD PTR "
+#define ACPI_RSDT_SIGNATURE "RSDT"
+#define ACPI_XSDT_SIGNATURE "XSDT"
+#define ACPI_MADT_SIGNATURE "APIC"
+#define ACPI_FADT_SIGNATURE "FACP"
+#define ACPI_FACS_SIGNATURE "FACS"
+#define ACPI_MCFG_SIGNATURE "MCFG"
+#define ACPI_HPET_SIGNATURE "HPET"
+#define ACPI_SRAT_SIGNATURE "SRAT"
+#define ACPI_SLIT_SIGNATURE "SLIT"
+#define ACPI_DSDT_SIGNATURE "DSDT"
+#define ACPI_SSDT_SIGNATURE "SSDT"
+#define ACPI_PSDT_SIGNATURE "PSDT"
+#define ACPI_ECDT_SIGNATURE "ECDT"
+#define ACPI_RHCT_SIGNATURE "RHCT"
+
+#define ACPI_AS_ID_SYS_MEM 0x00
+#define ACPI_AS_ID_SYS_IO 0x01
+#define ACPI_AS_ID_PCI_CFG_SPACE 0x02
+#define ACPI_AS_ID_EC 0x03
+#define ACPI_AS_ID_SMBUS 0x04
+#define ACPI_AS_ID_SYS_CMOS 0x05
+#define ACPI_AS_ID_PCI_BAR_TGT 0x06
+#define ACPI_AS_ID_IPMI 0x07
+#define ACPI_AS_ID_GP_IO 0x08
+#define ACPI_AS_ID_GENERIC_SBUS 0x09
+#define ACPI_AS_ID_PCC 0x0A
+#define ACPI_AS_ID_FFH 0x7F
+#define ACPI_AS_ID_OEM_BASE 0xC0
+#define ACPI_AS_ID_OEM_END 0xFF
+
+#define ACPI_ACCESS_UD 0
+#define ACPI_ACCESS_BYTE 1
+#define ACPI_ACCESS_WORD 2
+#define ACPI_ACCESS_DWORD 3
+#define ACPI_ACCESS_QWORD 4
+
+UACPI_PACKED(struct acpi_gas {
+ uacpi_u8 address_space_id;
+ uacpi_u8 register_bit_width;
+ uacpi_u8 register_bit_offset;
+ uacpi_u8 access_size;
+ uacpi_u64 address;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_gas, 12);
+
+UACPI_PACKED(struct acpi_rsdp {
+ uacpi_char signature[8];
+ uacpi_u8 checksum;
+ uacpi_char oemid[6];
+ uacpi_u8 revision;
+ uacpi_u32 rsdt_addr;
+
+ // vvvv available if .revision >= 2.0 only
+ uacpi_u32 length;
+ uacpi_u64 xsdt_addr;
+ uacpi_u8 extended_checksum;
+ uacpi_u8 rsvd[3];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rsdp, 36);
+
+UACPI_PACKED(struct acpi_sdt_hdr {
+ uacpi_char signature[4];
+ uacpi_u32 length;
+ uacpi_u8 revision;
+ uacpi_u8 checksum;
+ uacpi_char oemid[6];
+ uacpi_char oem_table_id[8];
+ uacpi_u32 oem_revision;
+ uacpi_u32 creator_id;
+ uacpi_u32 creator_revision;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_sdt_hdr, 36);
+
+UACPI_PACKED(struct acpi_rsdt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u32 entries[];
+})
+
+UACPI_PACKED(struct acpi_xsdt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u64 entries[];
+})
+
+UACPI_PACKED(struct acpi_entry_hdr {
+ /*
+ * - acpi_madt_entry_type for the APIC table
+ * - acpi_srat_entry_type for the SRAT table
+ */
+ uacpi_u8 type;
+ uacpi_u8 length;
+})
+
+// acpi_madt->flags
+#define ACPI_PCAT_COMPAT (1 << 0)
+
+enum acpi_madt_entry_type {
+ ACPI_MADT_ENTRY_TYPE_LAPIC = 0,
+ ACPI_MADT_ENTRY_TYPE_IOAPIC = 1,
+ ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE = 2,
+ ACPI_MADT_ENTRY_TYPE_NMI_SOURCE = 3,
+ ACPI_MADT_ENTRY_TYPE_LAPIC_NMI = 4,
+ ACPI_MADT_ENTRY_TYPE_LAPIC_ADDRESS_OVERRIDE = 5,
+ ACPI_MADT_ENTRY_TYPE_IOSAPIC = 6,
+ ACPI_MADT_ENTRY_TYPE_LSAPIC = 7,
+ ACPI_MADT_ENTRY_TYPE_PLATFORM_INTERRUPT_SOURCES = 8,
+ ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC = 9,
+ ACPI_MADT_ENTRY_TYPE_LOCAL_X2APIC_NMI = 0xA,
+ ACPI_MADT_ENTRY_TYPE_GICC = 0xB,
+ ACPI_MADT_ENTRY_TYPE_GICD = 0xC,
+ ACPI_MADT_ENTRY_TYPE_GIC_MSI_FRAME = 0xD,
+ ACPI_MADT_ENTRY_TYPE_GICR = 0xE,
+ ACPI_MADT_ENTRY_TYPE_GIC_ITS = 0xF,
+ ACPI_MADT_ENTRY_TYPE_MULTIPROCESSOR_WAKEUP = 0x10,
+ ACPI_MADT_ENTRY_TYPE_CORE_PIC = 0x11,
+ ACPI_MADT_ENTRY_TYPE_LIO_PIC = 0x12,
+ ACPI_MADT_ENTRY_TYPE_HT_PIC = 0x13,
+ ACPI_MADT_ENTRY_TYPE_EIO_PIC = 0x14,
+ ACPI_MADT_ENTRY_TYPE_MSI_PIC = 0x15,
+ ACPI_MADT_ENTRY_TYPE_BIO_PIC = 0x16,
+ ACPI_MADT_ENTRY_TYPE_LPC_PIC = 0x17,
+ ACPI_MADT_ENTRY_TYPE_RINTC = 0x18,
+ ACPI_MADT_ENTRY_TYPE_IMSIC = 0x19,
+ ACPI_MADT_ENTRY_TYPE_APLIC = 0x1A,
+ ACPI_MADT_ENTRY_TYPE_PLIC = 0x1B,
+ ACPI_MADT_ENTRY_TYPE_RESERVED = 0x1C, // 0x1C..0x7F
+ ACPI_MADT_ENTRY_TYPE_OEM = 0x80, // 0x80..0xFF
+};
+
+UACPI_PACKED(struct acpi_madt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u32 local_interrupt_controller_address;
+ uacpi_u32 flags;
+ struct acpi_entry_hdr entries[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt, 44);
+
+/*
+ * - acpi_madt_lapic->flags
+ * - acpi_madt_lsapic->flags
+ * - acpi_madt_x2apic->flags
+ */
+#define ACPI_PIC_ENABLED (1 << 0)
+#define ACPI_PIC_ONLINE_CAPABLE (1 << 1)
+
+UACPI_PACKED(struct acpi_madt_lapic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 uid;
+ uacpi_u8 id;
+ uacpi_u32 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_lapic, 8);
+
+UACPI_PACKED(struct acpi_madt_ioapic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 id;
+ uacpi_u8 rsvd;
+ uacpi_u32 address;
+ uacpi_u32 gsi_base;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_ioapic, 12);
+
+/*
+ * - acpi_madt_interrupt_source_override->flags
+ * - acpi_madt_nmi_source->flags
+ * - acpi_madt_lapic_nmi->flags
+ * - acpi_madt_platform_interrupt_source->flags
+ * - acpi_madt_x2apic_nmi->flags
+ */
+#define ACPI_MADT_POLARITY_MASK 0b11
+#define ACPI_MADT_POLARITY_CONFORMING 0b00
+#define ACPI_MADT_POLARITY_ACTIVE_HIGH 0b01
+#define ACPI_MADT_POLARITY_ACTIVE_LOW 0b11
+
+#define ACPI_MADT_TRIGGERING_MASK 0b1100
+#define ACPI_MADT_TRIGGERING_CONFORMING 0b0000
+#define ACPI_MADT_TRIGGERING_EDGE 0b0100
+#define ACPI_MADT_TRIGGERING_LEVEL 0b1100
+
+UACPI_PACKED(struct acpi_madt_interrupt_source_override {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 bus;
+ uacpi_u8 source;
+ uacpi_u32 gsi;
+ uacpi_u16 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_interrupt_source_override, 10);
+
+UACPI_PACKED(struct acpi_madt_nmi_source {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 flags;
+ uacpi_u32 gsi;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_nmi_source, 8);
+
+UACPI_PACKED(struct acpi_madt_lapic_nmi {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 uid;
+ uacpi_u16 flags;
+ uacpi_u8 lint;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_lapic_nmi, 6);
+
+UACPI_PACKED(struct acpi_madt_lapic_address_override {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd;
+ uacpi_u64 address;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_lapic_address_override, 12);
+
+UACPI_PACKED(struct acpi_madt_iosapic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 id;
+ uacpi_u8 rsvd;
+ uacpi_u32 gsi_base;
+ uacpi_u64 address;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_iosapic, 16);
+
+UACPI_PACKED(struct acpi_madt_lsapic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 acpi_id;
+ uacpi_u8 id;
+ uacpi_u8 eid;
+ uacpi_u8 reserved[3];
+ uacpi_u32 flags;
+ uacpi_u32 uid;
+ uacpi_char uid_string[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_lsapic, 16);
+
+// acpi_madt_platform_interrupt_source->platform_flags
+#define ACPI_CPEI_PROCESSOR_OVERRIDE (1 << 0)
+
+UACPI_PACKED(struct acpi_madt_platform_interrupt_source {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 flags;
+ uacpi_u8 type;
+ uacpi_u8 processor_id;
+ uacpi_u8 processor_eid;
+ uacpi_u8 iosapic_vector;
+ uacpi_u32 gsi;
+ uacpi_u32 platform_flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_platform_interrupt_source, 16);
+
+UACPI_PACKED(struct acpi_madt_x2apic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd;
+ uacpi_u32 id;
+ uacpi_u32 flags;
+ uacpi_u32 uid;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_x2apic, 16);
+
+UACPI_PACKED(struct acpi_madt_x2apic_nmi {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 flags;
+ uacpi_u32 uid;
+ uacpi_u8 lint;
+ uacpi_u8 reserved[3];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_x2apic_nmi, 12);
+
+// acpi_madt_gicc->flags
+#define ACPI_GICC_ENABLED (1 << 0)
+#define ACPI_GICC_PERF_INTERRUPT_MODE (1 << 1)
+#define ACPI_GICC_VGIC_MAINTENANCE_INTERRUPT_MODE (1 << 2)
+#define ACPI_GICC_ONLINE_CAPABLE (1 << 3)
+
+// ACPI_GICC_*_INTERRUPT_MODE
+#define ACPI_GICC_TRIGGERING_EDGE 1
+#define ACPI_GICC_TRIGGERING_LEVEL 0
+
+UACPI_PACKED(struct acpi_madt_gicc {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd0;
+ uacpi_u32 interface_number;
+ uacpi_u32 acpi_id;
+ uacpi_u32 flags;
+ uacpi_u32 parking_protocol_version;
+ uacpi_u32 perf_interrupt_gsiv;
+ uacpi_u64 parked_address;
+ uacpi_u64 address;
+ uacpi_u64 gicv;
+ uacpi_u64 gich;
+ uacpi_u32 vgic_maitenante_interrupt;
+ uacpi_u64 gicr_base_address;
+ uacpi_u64 mpidr;
+ uacpi_u8 power_efficiency_class;
+ uacpi_u8 rsvd1;
+ uacpi_u16 spe_overflow_interrupt;
+ uacpi_u16 trbe_interrupt;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_gicc, 82);
+
+UACPI_PACKED(struct acpi_madt_gicd {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd0;
+ uacpi_u32 id;
+ uacpi_u64 address;
+ uacpi_u32 system_vector_base;
+ uacpi_u8 gic_version;
+ uacpi_u8 reserved1[3];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_gicd, 24);
+
+// acpi_madt_gic_msi_frame->flags
+#define ACPI_SPI_SELECT (1 << 0)
+
+UACPI_PACKED(struct acpi_madt_gic_msi_frame {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd;
+ uacpi_u32 id;
+ uacpi_u64 address;
+ uacpi_u32 flags;
+ uacpi_u16 spi_count;
+ uacpi_u16 spi_base;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_gic_msi_frame, 24);
+
+UACPI_PACKED(struct acpi_madt_gicr {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd;
+ uacpi_u64 address;
+ uacpi_u32 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_gicr, 16);
+
+UACPI_PACKED(struct acpi_madt_gic_its {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd0;
+ uacpi_u32 id;
+ uacpi_u64 address;
+ uacpi_u32 rsvd1;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_gic_its, 20);
+
+UACPI_PACKED(struct acpi_madt_multiprocessor_wakeup {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 mailbox_version;
+ uacpi_u32 rsvd;
+ uacpi_u64 mailbox_address;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_multiprocessor_wakeup, 16);
+
+#define ACPI_CORE_PIC_ENABLED (1 << 0)
+
+UACPI_PACKED(struct acpi_madt_core_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u32 acpi_id;
+ uacpi_u32 id;
+ uacpi_u32 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_core_pic, 15);
+
+UACPI_PACKED(struct acpi_madt_lio_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u64 address;
+ uacpi_u16 size;
+ uacpi_u16 cascade_vector;
+ uacpi_u64 cascade_vector_mapping;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_lio_pic, 23);
+
+UACPI_PACKED(struct acpi_madt_ht_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u64 address;
+ uacpi_u16 size;
+ uacpi_u64 cascade_vector;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_ht_pic, 21);
+
+UACPI_PACKED(struct acpi_madt_eio_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u8 cascade_vector;
+ uacpi_u8 node;
+ uacpi_u64 node_map;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_eio_pic, 13);
+
+UACPI_PACKED(struct acpi_madt_msi_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u64 address;
+ uacpi_u32 start;
+ uacpi_u32 count;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_msi_pic, 19);
+
+UACPI_PACKED(struct acpi_madt_bio_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u64 address;
+ uacpi_u16 size;
+ uacpi_u16 hardware_id;
+ uacpi_u16 gsi_base;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_bio_pic, 17);
+
+UACPI_PACKED(struct acpi_madt_lpc_pic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u64 address;
+ uacpi_u16 size;
+ uacpi_u16 cascade_vector;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_lpc_pic, 15);
+
+UACPI_PACKED(struct acpi_madt_rintc {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u8 rsvd;
+ uacpi_u32 flags;
+ uacpi_u64 hart_id;
+ uacpi_u32 uid;
+ uacpi_u32 ext_intc_id;
+ uacpi_u64 address;
+ uacpi_u32 size;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_rintc, 36);
+
+UACPI_PACKED(struct acpi_madt_imsic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u8 rsvd;
+ uacpi_u32 flags;
+ uacpi_u16 num_ids;
+ uacpi_u16 num_guest_ids;
+ uacpi_u8 guest_index_bits;
+ uacpi_u8 hart_index_bits;
+ uacpi_u8 group_index_bits;
+ uacpi_u8 group_index_shift;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_imsic, 16);
+
+UACPI_PACKED(struct acpi_madt_aplic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u8 id;
+ uacpi_u32 flags;
+ uacpi_u64 hardware_id;
+ uacpi_u16 idc_count;
+ uacpi_u16 sources_count;
+ uacpi_u32 gsi_base;
+ uacpi_u64 address;
+ uacpi_u32 size;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_aplic, 36);
+
+UACPI_PACKED(struct acpi_madt_plic {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 version;
+ uacpi_u8 id;
+ uacpi_u64 hardware_id;
+ uacpi_u16 sources_count;
+ uacpi_u16 max_priority;
+ uacpi_u32 flags;
+ uacpi_u32 size;
+ uacpi_u64 address;
+ uacpi_u32 gsi_base;
+
+})
+UACPI_EXPECT_SIZEOF(struct acpi_madt_plic, 36);
+
+enum acpi_srat_entry_type {
+ ACPI_SRAT_ENTRY_TYPE_PROCESSOR_AFFINITY = 0,
+ ACPI_SRAT_ENTRY_TYPE_MEMORY_AFFINITY = 1,
+ ACPI_SRAT_ENTRY_TYPE_X2APIC_AFFINITY = 2,
+ ACPI_SRAT_ENTRY_TYPE_GICC_AFFINITY = 3,
+ ACPI_SRAT_ENTRY_TYPE_GIC_ITS_AFFINITY = 4,
+ ACPI_SRAT_ENTRY_TYPE_GENERIC_INITIATOR_AFFINITY = 5,
+ ACPI_SRAT_ENTRY_TYPE_GENERIC_PORT_AFFINITY = 6,
+ ACPI_SRAT_ENTRY_TYPE_RINTC_AFFINITY = 7,
+};
+
+UACPI_PACKED(struct acpi_srat {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u32 rsvd0;
+ uacpi_u64 rsvd1;
+ struct acpi_entry_hdr entries[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat, 48);
+
+/*
+ * acpi_srat_processor_affinity->flags
+ * acpi_srat_x2apic_affinity->flags
+ */
+#define ACPI_SRAT_PROCESSOR_ENABLED (1 << 0)
+
+UACPI_PACKED(struct acpi_srat_processor_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 proximity_domain_low;
+ uacpi_u8 id;
+ uacpi_u32 flags;
+ uacpi_u8 eid;
+ uacpi_u8 proximity_domain_high[3];
+ uacpi_u32 clock_domain;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_processor_affinity, 16);
+
+// acpi_srat_memory_affinity->flags
+#define ACPI_SRAT_MEMORY_ENABLED (1 << 0)
+#define ACPI_SRAT_MEMORY_HOTPLUGGABLE (1 << 1)
+#define ACPI_SRAT_MEMORY_NON_VOLATILE (1 << 2)
+
+UACPI_PACKED(struct acpi_srat_memory_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u32 proximity_domain;
+ uacpi_u16 rsvd0;
+ uacpi_u64 address;
+ uacpi_u64 length;
+ uacpi_u32 rsvd1;
+ uacpi_u32 flags;
+ uacpi_u64 rsdv2;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_memory_affinity, 40);
+
+UACPI_PACKED(struct acpi_srat_x2apic_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd0;
+ uacpi_u32 proximity_domain;
+ uacpi_u32 id;
+ uacpi_u32 flags;
+ uacpi_u32 clock_domain;
+ uacpi_u32 rsvd1;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_x2apic_affinity, 24);
+
+// acpi_srat_gicc_affinity->flags
+#define ACPI_SRAT_GICC_ENABLED (1 << 0)
+
+UACPI_PACKED(struct acpi_srat_gicc_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u32 proximity_domain;
+ uacpi_u32 uid;
+ uacpi_u32 flags;
+ uacpi_u32 clock_domain;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_gicc_affinity, 18);
+
+UACPI_PACKED(struct acpi_srat_gic_its_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u32 proximity_domain;
+ uacpi_u16 rsvd;
+ uacpi_u32 id;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_gic_its_affinity, 12);
+
+// acpi_srat_generic_affinity->flags
+#define ACPI_GENERIC_AFFINITY_ENABLED (1 << 0)
+#define ACPI_GENERIC_AFFINITY_ARCH_TRANSACTIONS (1 << 1)
+
+UACPI_PACKED(struct acpi_srat_generic_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u8 rsvd0;
+ uacpi_u8 handle_type;
+ uacpi_u32 proximity_domain;
+ uacpi_u8 handle[16];
+ uacpi_u32 flags;
+ uacpi_u32 rsvd1;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_generic_affinity, 32);
+
+// acpi_srat_rintc_affinity->flags
+#define ACPI_SRAT_RINTC_AFFINITY_ENABLED (1 << 0)
+
+UACPI_PACKED(struct acpi_srat_rintc_affinity {
+ struct acpi_entry_hdr hdr;
+ uacpi_u16 rsvd;
+ uacpi_u32 proximity_domain;
+ uacpi_u32 uid;
+ uacpi_u32 flags;
+ uacpi_u32 clock_domain;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_srat_rintc_affinity, 20);
+
+UACPI_PACKED(struct acpi_slit {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u64 num_localities;
+ uacpi_u8 matrix[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_slit, 44);
+
+/*
+ * acpi_gtdt->el*_flags
+ * acpi_gtdt_timer_entry->physical_flags
+ * acpi_gtdt_timer_entry->virtual_flags
+ * acpi_gtdt_watchdog->flags
+ */
+#define ACPI_GTDT_TRIGGERING (1 << 0)
+#define ACPI_GTDT_TRIGGERING_EDGE 1
+#define ACPI_GTDT_TRIGGERING_LEVEL 0
+
+/*
+ * acpi_gtdt->el*_flags
+ * acpi_gtdt_timer_entry->physical_flags
+ * acpi_gtdt_timer_entry->virtual_flags
+ * acpi_gtdt_watchdog->flags
+ */
+#define ACPI_GTDT_POLARITY (1 << 1)
+#define ACPI_GTDT_POLARITY_ACTIVE_LOW 1
+#define ACPI_GTDT_POLARITY_ACTIVE_HIGH 0
+
+// acpi_gtdt->el*_flags
+#define ACPI_GTDT_ALWAYS_ON_CAPABLE (1 << 2)
+
+UACPI_PACKED(struct acpi_gtdt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u64 cnt_control_base;
+ uacpi_u32 rsvd;
+ uacpi_u32 el1_secure_gsiv;
+ uacpi_u32 el1_secure_flags;
+ uacpi_u32 el1_non_secure_gsiv;
+ uacpi_u32 el1_non_secure_flags;
+ uacpi_u32 el1_virtual_gsiv;
+ uacpi_u32 el1_virtual_flags;
+ uacpi_u32 el2_gsiv;
+ uacpi_u32 el2_flags;
+ uacpi_u64 cnt_read_base;
+ uacpi_u32 platform_timer_count;
+ uacpi_u32 platform_timer_offset;
+
+ // revision >= 3
+ uacpi_u32 el2_virtual_gsiv;
+ uacpi_u32 el2_virtual_flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_gtdt, 104);
+
+enum acpi_gtdt_entry_type {
+ ACPI_GTDT_ENTRY_TYPE_TIMER = 0,
+ ACPI_GTDT_ENTRY_TYPE_WATCHDOG = 1,
+};
+
+UACPI_PACKED(struct acpi_gtdt_entry_hdr {
+ uacpi_u8 type;
+ uacpi_u16 length;
+})
+
+UACPI_PACKED(struct acpi_gtdt_timer {
+ struct acpi_gtdt_entry_hdr hdr;
+ uacpi_u8 rsvd;
+ uacpi_u64 cnt_ctl_base;
+ uacpi_u32 timer_count;
+ uacpi_u32 timer_offset;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_gtdt_timer, 20);
+
+// acpi_gtdt_timer_entry->common_flags
+#define ACPI_GTDT_TIMER_ENTRY_SECURE (1 << 0)
+#define ACPI_GTDT_TIMER_ENTRY_ALWAYS_ON_CAPABLE (1 << 1)
+
+UACPI_PACKED(struct acpi_gtdt_timer_entry {
+ uacpi_u8 frame_number;
+ uacpi_u8 rsvd[3];
+ uacpi_u64 cnt_base;
+ uacpi_u64 el0_cnt_base;
+ uacpi_u32 physical_gsiv;
+ uacpi_u32 physical_flags;
+ uacpi_u32 virtual_gsiv;
+ uacpi_u32 virtual_flags;
+ uacpi_u32 common_flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_gtdt_timer_entry, 40);
+
+// acpi_gtdt_watchdog->flags
+#define ACPI_GTDT_WATCHDOG_SECURE (1 << 2)
+
+UACPI_PACKED(struct acpi_gtdt_watchdog {
+ struct acpi_gtdt_entry_hdr hdr;
+ uacpi_u8 rsvd;
+ uacpi_u64 refresh_frame;
+ uacpi_u64 control_frame;
+ uacpi_u32 gsiv;
+ uacpi_u32 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_gtdt_watchdog, 28);
+
+// acpi_fdt->iapc_flags
+#define ACPI_IA_PC_LEGACY_DEVS (1 << 0)
+#define ACPI_IA_PC_8042 (1 << 1)
+#define ACPI_IA_PC_NO_VGA (1 << 2)
+#define ACPI_IA_PC_NO_MSI (1 << 3)
+#define ACPI_IA_PC_NO_PCIE_ASPM (1 << 4)
+#define ACPI_IA_PC_NO_CMOS_RTC (1 << 5)
+
+// acpi_fdt->flags
+#define ACPI_WBINVD (1 << 0)
+#define ACPI_WBINVD_FLUSH (1 << 1)
+#define ACPI_PROC_C1 (1 << 2)
+#define ACPI_P_LVL2_UP (1 << 3)
+#define ACPI_PWR_BUTTON (1 << 4)
+#define ACPI_SLP_BUTTON (1 << 5)
+#define ACPI_FIX_RTC (1 << 6)
+#define ACPI_RTC_S4 (1 << 7)
+#define ACPI_TMR_VAL_EXT (1 << 8)
+#define ACPI_DCK_CAP (1 << 9)
+#define ACPI_RESET_REG_SUP (1 << 10)
+#define ACPI_SEALED_CASE (1 << 11)
+#define ACPI_HEADLESS (1 << 12)
+#define ACPI_CPU_SW_SLP (1 << 13)
+#define ACPI_PCI_EXP_WAK (1 << 14)
+#define ACPI_USE_PLATFORM_CLOCK (1 << 15)
+#define ACPI_S4_RTC_STS_VALID (1 << 16)
+#define ACPI_REMOTE_POWER_ON_CAPABLE (1 << 17)
+#define ACPI_FORCE_APIC_CLUSTER_MODEL (1 << 18)
+#define ACPI_FORCE_APIC_PHYS_DEST_MODE (1 << 19)
+#define ACPI_HW_REDUCED_ACPI (1 << 20)
+#define ACPI_LOW_POWER_S0_IDLE_CAPABLE (1 << 21)
+
+// acpi_fdt->arm_flags
+#define ACPI_ARM_PSCI_COMPLIANT (1 << 0)
+#define ACPI_ARM_PSCI_USE_HVC (1 << 1)
+
+UACPI_PACKED(struct acpi_fadt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u32 firmware_ctrl;
+ uacpi_u32 dsdt;
+ uacpi_u8 int_model;
+ uacpi_u8 preferred_pm_profile;
+ uacpi_u16 sci_int;
+ uacpi_u32 smi_cmd;
+ uacpi_u8 acpi_enable;
+ uacpi_u8 acpi_disable;
+ uacpi_u8 s4bios_req;
+ uacpi_u8 pstate_cnt;
+ uacpi_u32 pm1a_evt_blk;
+ uacpi_u32 pm1b_evt_blk;
+ uacpi_u32 pm1a_cnt_blk;
+ uacpi_u32 pm1b_cnt_blk;
+ uacpi_u32 pm2_cnt_blk;
+ uacpi_u32 pm_tmr_blk;
+ uacpi_u32 gpe0_blk;
+ uacpi_u32 gpe1_blk;
+ uacpi_u8 pm1_evt_len;
+ uacpi_u8 pm1_cnt_len;
+ uacpi_u8 pm2_cnt_len;
+ uacpi_u8 pm_tmr_len;
+ uacpi_u8 gpe0_blk_len;
+ uacpi_u8 gpe1_blk_len;
+ uacpi_u8 gpe1_base;
+ uacpi_u8 cst_cnt;
+ uacpi_u16 p_lvl2_lat;
+ uacpi_u16 p_lvl3_lat;
+ uacpi_u16 flush_size;
+ uacpi_u16 flush_stride;
+ uacpi_u8 duty_offset;
+ uacpi_u8 duty_width;
+ uacpi_u8 day_alrm;
+ uacpi_u8 mon_alrm;
+ uacpi_u8 century;
+ uacpi_u16 iapc_boot_arch;
+ uacpi_u8 rsvd;
+ uacpi_u32 flags;
+ struct acpi_gas reset_reg;
+ uacpi_u8 reset_value;
+ uacpi_u16 arm_boot_arch;
+ uacpi_u8 fadt_minor_verison;
+ uacpi_u64 x_firmware_ctrl;
+ uacpi_u64 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;
+ uacpi_u64 hypervisor_vendor_identity;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_fadt, 276);
+
+// acpi_facs->flags
+#define ACPI_S4BIOS_F (1 << 0)
+#define ACPI_64BIT_WAKE_SUPPORTED_F (1 << 1)
+
+// acpi_facs->ospm_flags
+#define ACPI_64BIT_WAKE_F (1 << 0)
+
+struct acpi_facs {
+ uacpi_char signature[4];
+ uacpi_u32 length;
+ uacpi_u32 hardware_signature;
+ uacpi_u32 firmware_waking_vector;
+ uacpi_u32 global_lock;
+ uacpi_u32 flags;
+ uacpi_u64 x_firmware_waking_vector;
+ uacpi_u8 version;
+ uacpi_char rsvd0[3];
+ uacpi_u32 ospm_flags;
+ uacpi_char rsvd1[24];
+};
+UACPI_EXPECT_SIZEOF(struct acpi_facs, 64);
+
+UACPI_PACKED(struct acpi_mcfg_allocation {
+ uacpi_u64 address;
+ uacpi_u16 segment;
+ uacpi_u8 start_bus;
+ uacpi_u8 end_bus;
+ uacpi_u32 rsvd;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_mcfg_allocation, 16);
+
+UACPI_PACKED(struct acpi_mcfg {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u64 rsvd;
+ struct acpi_mcfg_allocation entries[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_mcfg, 44);
+
+// acpi_hpet->block_id
+#define ACPI_HPET_PCI_VENDOR_ID_SHIFT 16
+#define ACPI_HPET_LEGACY_REPLACEMENT_IRQ_ROUTING_CAPABLE (1 << 15)
+#define ACPI_HPET_COUNT_SIZE_CAP (1 << 13)
+#define ACPI_HPET_NUMBER_OF_COMPARATORS_SHIFT 8
+#define ACPI_HPET_NUMBER_OF_COMPARATORS_MASK 0b11111
+#define ACPI_HPET_HARDWARE_REV_ID_MASK 0b11111111
+
+// acpi_hpet->flags
+#define ACPI_HPET_PAGE_PROTECTION_MASK 0b11
+#define ACPI_HPET_PAGE_NO_PROTECTION 0
+#define ACPI_HPET_PAGE_4K_PROTECTED 1
+#define ACPI_HPET_PAGE_64K_PROTECTED 2
+
+UACPI_PACKED(struct acpi_hpet {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u32 block_id;
+ struct acpi_gas address;
+ uacpi_u8 number;
+ uacpi_u16 min_clock_tick;
+ uacpi_u8 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_hpet, 56);
+
+// PM1{a,b}_STS
+#define ACPI_PM1_STS_TMR_STS_IDX 0
+#define ACPI_PM1_STS_BM_STS_IDX 4
+#define ACPI_PM1_STS_GBL_STS_IDX 5
+#define ACPI_PM1_STS_PWRBTN_STS_IDX 8
+#define ACPI_PM1_STS_SLPBTN_STS_IDX 9
+#define ACPI_PM1_STS_RTC_STS_IDX 10
+#define ACPI_PM1_STS_IGN0_IDX 11
+#define ACPI_PM1_STS_PCIEXP_WAKE_STS_IDX 14
+#define ACPI_PM1_STS_WAKE_STS_IDX 15
+
+#define ACPI_PM1_STS_TMR_STS_MASK (1 << ACPI_PM1_STS_TMR_STS_IDX)
+#define ACPI_PM1_STS_BM_STS_MASK (1 << ACPI_PM1_STS_BM_STS_IDX)
+#define ACPI_PM1_STS_GBL_STS_MASK (1 << ACPI_PM1_STS_GBL_STS_IDX)
+#define ACPI_PM1_STS_PWRBTN_STS_MASK (1 << ACPI_PM1_STS_PWRBTN_STS_IDX)
+#define ACPI_PM1_STS_SLPBTN_STS_MASK (1 << ACPI_PM1_STS_SLPBTN_STS_IDX)
+#define ACPI_PM1_STS_RTC_STS_MASK (1 << ACPI_PM1_STS_RTC_STS_IDX)
+#define ACPI_PM1_STS_IGN0_MASK (1 << ACPI_PM1_STS_IGN0_IDX)
+#define ACPI_PM1_STS_PCIEXP_WAKE_STS_MASK (1 << ACPI_PM1_STS_PCIEXP_WAKE_STS_IDX)
+#define ACPI_PM1_STS_WAKE_STS_MASK (1 << ACPI_PM1_STS_WAKE_STS_IDX)
+
+#define ACPI_PM1_STS_CLEAR 1
+
+// PM1{a,b}_EN
+#define ACPI_PM1_EN_TMR_EN_IDX 0
+#define ACPI_PM1_EN_GBL_EN_IDX 5
+#define ACPI_PM1_EN_PWRBTN_EN_IDX 8
+#define ACPI_PM1_EN_SLPBTN_EN_IDX 9
+#define ACPI_PM1_EN_RTC_EN_IDX 10
+#define ACPI_PM1_EN_PCIEXP_WAKE_DIS_IDX 14
+
+#define ACPI_PM1_EN_TMR_EN_MASK (1 << ACPI_PM1_EN_TMR_EN_IDX)
+#define ACPI_PM1_EN_GBL_EN_MASK (1 << ACPI_PM1_EN_GBL_EN_IDX)
+#define ACPI_PM1_EN_PWRBTN_EN_MASK (1 << ACPI_PM1_EN_PWRBTN_EN_IDX)
+#define ACPI_PM1_EN_SLPBTN_EN_MASK (1 << ACPI_PM1_EN_SLPBTN_EN_IDX)
+#define ACPI_PM1_EN_RTC_EN_MASK (1 << ACPI_PM1_EN_RTC_EN_IDX)
+#define ACPI_PM1_EN_PCIEXP_WAKE_DIS_MASK (1 << ACPI_PM1_EN_PCIEXP_WAKE_DIS_IDX)
+
+// PM1{a,b}_CNT_BLK
+#define ACPI_PM1_CNT_SCI_EN_IDX 0
+#define ACPI_PM1_CNT_BM_RLD_IDX 1
+#define ACPI_PM1_CNT_GBL_RLS_IDX 2
+#define ACPI_PM1_CNT_RSVD0_IDX 3
+#define ACPI_PM1_CNT_RSVD1_IDX 4
+#define ACPI_PM1_CNT_RSVD2_IDX 5
+#define ACPI_PM1_CNT_RSVD3_IDX 6
+#define ACPI_PM1_CNT_RSVD4_IDX 7
+#define ACPI_PM1_CNT_RSVD5_IDX 8
+#define ACPI_PM1_CNT_IGN0_IDX 9
+#define ACPI_PM1_CNT_SLP_TYP_IDX 10
+#define ACPI_PM1_CNT_SLP_EN_IDX 13
+#define ACPI_PM1_CNT_RSVD6_IDX 14
+#define ACPI_PM1_CNT_RSVD7_IDX 15
+
+#define ACPI_SLP_TYP_MAX 0x7
+
+#define ACPI_PM1_CNT_SCI_EN_MASK (1 << ACPI_PM1_CNT_SCI_EN_IDX)
+#define ACPI_PM1_CNT_BM_RLD_MASK (1 << ACPI_PM1_CNT_BM_RLD_IDX)
+#define ACPI_PM1_CNT_GBL_RLS_MASK (1 << ACPI_PM1_CNT_GBL_RLS_IDX)
+#define ACPI_PM1_CNT_SLP_TYP_MASK (ACPI_SLP_TYP_MAX << ACPI_PM1_CNT_SLP_TYP_IDX)
+#define ACPI_PM1_CNT_SLP_EN_MASK (1 << ACPI_PM1_CNT_SLP_EN_IDX)
+
+/*
+ * SCI_EN is not in this mask even though the spec says it must be preserved.
+ * This is because it's known to be bugged on some hardware that relies on
+ * software writing 1 to it after resume (as indicated by a similar comment in
+ * ACPICA)
+ */
+#define ACPI_PM1_CNT_PRESERVE_MASK ( \
+ (1 << ACPI_PM1_CNT_RSVD0_IDX) | \
+ (1 << ACPI_PM1_CNT_RSVD1_IDX) | \
+ (1 << ACPI_PM1_CNT_RSVD2_IDX) | \
+ (1 << ACPI_PM1_CNT_RSVD3_IDX) | \
+ (1 << ACPI_PM1_CNT_RSVD4_IDX) | \
+ (1 << ACPI_PM1_CNT_RSVD5_IDX) | \
+ (1 << ACPI_PM1_CNT_IGN0_IDX ) | \
+ (1 << ACPI_PM1_CNT_RSVD6_IDX) | \
+ (1 << ACPI_PM1_CNT_RSVD7_IDX) \
+)
+
+// PM2_CNT
+#define ACPI_PM2_CNT_ARB_DIS_IDX 0
+#define ACPI_PM2_CNT_ARB_DIS_MASK (1 << ACPI_PM2_CNT_ARB_DIS_IDX)
+
+// All bits are reserved but this first one
+#define ACPI_PM2_CNT_PRESERVE_MASK (~((uacpi_u64)ACPI_PM2_CNT_ARB_DIS_MASK))
+
+// SLEEP_CONTROL_REG
+#define ACPI_SLP_CNT_RSVD0_IDX 0
+#define ACPI_SLP_CNT_IGN0_IDX 1
+#define ACPI_SLP_CNT_SLP_TYP_IDX 2
+#define ACPI_SLP_CNT_SLP_EN_IDX 5
+#define ACPI_SLP_CNT_RSVD1_IDX 6
+#define ACPI_SLP_CNT_RSVD2_IDX 7
+
+#define ACPI_SLP_CNT_SLP_TYP_MASK (ACPI_SLP_TYP_MAX << ACPI_SLP_CNT_SLP_TYP_IDX)
+#define ACPI_SLP_CNT_SLP_EN_MASK (1 << ACPI_SLP_CNT_SLP_EN_IDX)
+
+#define ACPI_SLP_CNT_PRESERVE_MASK ( \
+ (1 << ACPI_SLP_CNT_RSVD0_IDX) | \
+ (1 << ACPI_SLP_CNT_IGN0_IDX) | \
+ (1 << ACPI_SLP_CNT_RSVD1_IDX) | \
+ (1 << ACPI_SLP_CNT_RSVD2_IDX) \
+)
+
+// SLEEP_STATUS_REG
+#define ACPI_SLP_STS_WAK_STS_IDX 7
+
+#define ACPI_SLP_STS_WAK_STS_MASK (1 << ACPI_SLP_STS_WAK_STS_IDX)
+
+// All bits are reserved but this last one
+#define ACPI_SLP_STS_PRESERVE_MASK (~((uacpi_u64)ACPI_SLP_STS_WAK_STS_MASK))
+
+#define ACPI_SLP_STS_CLEAR 1
+
+UACPI_PACKED(struct acpi_dsdt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u8 definition_block[];
+})
+
+UACPI_PACKED(struct acpi_ssdt {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u8 definition_block[];
+})
+
+/*
+ * ACPI 6.5 specification:
+ * Bit [0] - Set if the device is present.
+ * Bit [1] - Set if the device is enabled and decoding its resources.
+ * Bit [2] - Set if the device should be shown in the UI.
+ * Bit [3] - Set if the device is functioning properly (cleared if device
+ * failed its diagnostics).
+ * Bit [4] - Set if the battery is present.
+ */
+#define ACPI_STA_RESULT_DEVICE_PRESENT (1 << 0)
+#define ACPI_STA_RESULT_DEVICE_ENABLED (1 << 1)
+#define ACPI_STA_RESULT_DEVICE_SHOWN_IN_UI (1 << 2)
+#define ACPI_STA_RESULT_DEVICE_FUNCTIONING (1 << 3)
+#define ACPI_STA_RESULT_DEVICE_BATTERY_PRESENT (1 << 4)
+
+#define ACPI_REG_DISCONNECT 0
+#define ACPI_REG_CONNECT 1
+
+UACPI_PACKED(struct acpi_ecdt {
+ struct acpi_sdt_hdr hdr;
+ struct acpi_gas ec_control;
+ struct acpi_gas ec_data;
+ uacpi_u32 uid;
+ uacpi_u8 gpe_bit;
+ uacpi_char ec_id[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_ecdt, 65);
+
+UACPI_PACKED(struct acpi_rhct_hdr {
+ uacpi_u16 type;
+ uacpi_u16 length;
+ uacpi_u16 revision;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rhct_hdr, 6);
+
+// acpi_rhct->flags
+#define ACPI_TIMER_CANNOT_WAKE_CPU (1 << 0)
+
+UACPI_PACKED(struct acpi_rhct {
+ struct acpi_sdt_hdr hdr;
+ uacpi_u32 flags;
+ uacpi_u64 timebase_frequency;
+ uacpi_u32 node_count;
+ uacpi_u32 nodes_offset;
+ struct acpi_rhct_hdr entries[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rhct, 56);
+
+enum acpi_rhct_entry_type {
+ ACPI_RHCT_ENTRY_TYPE_ISA_STRING = 0,
+ ACPI_RHCT_ENTRY_TYPE_CMO = 1,
+ ACPI_RHCT_ENTRY_TYPE_MMU = 2,
+ ACPI_RHCT_ENTRY_TYPE_HART_INFO = 65535,
+};
+
+UACPI_PACKED(struct acpi_rhct_isa_string {
+ struct acpi_rhct_hdr hdr;
+ uacpi_u16 length;
+ uacpi_u8 isa[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rhct_isa_string, 8);
+
+UACPI_PACKED(struct acpi_rhct_cmo {
+ struct acpi_rhct_hdr hdr;
+ uacpi_u8 rsvd;
+ uacpi_u8 cbom_size;
+ uacpi_u8 cbop_size;
+ uacpi_u8 cboz_size;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rhct_cmo, 10);
+
+enum acpi_rhct_mmu_type {
+ ACPI_RHCT_MMU_TYPE_SV39 = 0,
+ ACPI_RHCT_MMU_TYPE_SV48 = 1,
+ ACPI_RHCT_MMU_TYPE_SV57 = 2,
+};
+
+UACPI_PACKED(struct acpi_rhct_mmu {
+ struct acpi_rhct_hdr hdr;
+ uacpi_u8 rsvd;
+ uacpi_u8 type;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rhct_mmu, 8);
+
+UACPI_PACKED(struct acpi_rhct_hart_info {
+ struct acpi_rhct_hdr hdr;
+ uacpi_u16 offset_count;
+ uacpi_u32 uid;
+ uacpi_u32 offsets[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_rhct_hart_info, 12);
+
+#define ACPI_LARGE_ITEM (1 << 7)
+
+#define ACPI_SMALL_ITEM_NAME_IDX 3
+#define ACPI_SMALL_ITEM_NAME_MASK 0xF
+#define ACPI_SMALL_ITEM_LENGTH_MASK 0x7
+
+#define ACPI_LARGE_ITEM_NAME_MASK 0x7F
+
+// Small items
+#define ACPI_RESOURCE_IRQ 0x04
+#define ACPI_RESOURCE_DMA 0x05
+#define ACPI_RESOURCE_START_DEPENDENT 0x06
+#define ACPI_RESOURCE_END_DEPENDENT 0x07
+#define ACPI_RESOURCE_IO 0x08
+#define ACPI_RESOURCE_FIXED_IO 0x09
+#define ACPI_RESOURCE_FIXED_DMA 0x0A
+#define ACPI_RESOURCE_VENDOR_TYPE0 0x0E
+#define ACPI_RESOURCE_END_TAG 0x0F
+
+// Large items
+#define ACPI_RESOURCE_MEMORY24 0x01
+#define ACPI_RESOURCE_GENERIC_REGISTER 0x02
+#define ACPI_RESOURCE_VENDOR_TYPE1 0x04
+#define ACPI_RESOURCE_MEMORY32 0x05
+#define ACPI_RESOURCE_FIXED_MEMORY32 0x06
+#define ACPI_RESOURCE_ADDRESS32 0x07
+#define ACPI_RESOURCE_ADDRESS16 0x08
+#define ACPI_RESOURCE_EXTENDED_IRQ 0x09
+#define ACPI_RESOURCE_ADDRESS64 0x0A
+#define ACPI_RESOURCE_ADDRESS64_EXTENDED 0x0B
+#define ACPI_RESOURCE_GPIO_CONNECTION 0x0C
+#define ACPI_RESOURCE_PIN_FUNCTION 0x0D
+#define ACPI_RESOURCE_SERIAL_CONNECTION 0x0E
+#define ACPI_RESOURCE_PIN_CONFIGURATION 0x0F
+#define ACPI_RESOURCE_PIN_GROUP 0x10
+#define ACPI_RESOURCE_PIN_GROUP_FUNCTION 0x11
+#define ACPI_RESOURCE_PIN_GROUP_CONFIGURATION 0x12
+#define ACPI_RESOURCE_CLOCK_INPUT 0x13
+
+/*
+ * Resources as encoded by the raw AML byte stream.
+ * For decode API & human usable structures refer to uacpi/resources.h
+ */
+UACPI_PACKED(struct acpi_small_item {
+ uacpi_u8 type_and_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_small_item, 1);
+
+UACPI_PACKED(struct acpi_resource_irq {
+ struct acpi_small_item common;
+ uacpi_u16 irq_mask;
+ uacpi_u8 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_irq, 4);
+
+UACPI_PACKED(struct acpi_resource_dma {
+ struct acpi_small_item common;
+ uacpi_u8 channel_mask;
+ uacpi_u8 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_dma, 3);
+
+UACPI_PACKED(struct acpi_resource_start_dependent {
+ struct acpi_small_item common;
+ uacpi_u8 flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_start_dependent, 2);
+
+UACPI_PACKED(struct acpi_resource_end_dependent {
+ struct acpi_small_item common;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_end_dependent, 1);
+
+UACPI_PACKED(struct acpi_resource_io {
+ struct acpi_small_item common;
+ uacpi_u8 information;
+ uacpi_u16 minimum;
+ uacpi_u16 maximum;
+ uacpi_u8 alignment;
+ uacpi_u8 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_io, 8);
+
+UACPI_PACKED(struct acpi_resource_fixed_io {
+ struct acpi_small_item common;
+ uacpi_u16 address;
+ uacpi_u8 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_fixed_io, 4);
+
+UACPI_PACKED(struct acpi_resource_fixed_dma {
+ struct acpi_small_item common;
+ uacpi_u16 request_line;
+ uacpi_u16 channel;
+ uacpi_u8 transfer_width;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_fixed_dma, 6);
+
+UACPI_PACKED(struct acpi_resource_vendor_defined_type0 {
+ struct acpi_small_item common;
+ uacpi_u8 byte_data[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_vendor_defined_type0, 1);
+
+UACPI_PACKED(struct acpi_resource_end_tag {
+ struct acpi_small_item common;
+ uacpi_u8 checksum;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_end_tag, 2);
+
+UACPI_PACKED(struct acpi_large_item {
+ uacpi_u8 type;
+ uacpi_u16 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_large_item, 3);
+
+UACPI_PACKED(struct acpi_resource_memory24 {
+ struct acpi_large_item common;
+ uacpi_u8 information;
+ uacpi_u16 minimum;
+ uacpi_u16 maximum;
+ uacpi_u16 alignment;
+ uacpi_u16 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_memory24, 12);
+
+UACPI_PACKED(struct acpi_resource_vendor_defined_type1 {
+ struct acpi_large_item common;
+ uacpi_u8 byte_data[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_vendor_defined_type1, 3);
+
+UACPI_PACKED(struct acpi_resource_memory32 {
+ struct acpi_large_item common;
+ uacpi_u8 information;
+ uacpi_u32 minimum;
+ uacpi_u32 maximum;
+ uacpi_u32 alignment;
+ uacpi_u32 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_memory32, 20);
+
+UACPI_PACKED(struct acpi_resource_fixed_memory32 {
+ struct acpi_large_item common;
+ uacpi_u8 information;
+ uacpi_u32 address;
+ uacpi_u32 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_fixed_memory32, 12);
+
+UACPI_PACKED(struct acpi_resource_address {
+ struct acpi_large_item common;
+ uacpi_u8 type;
+ uacpi_u8 flags;
+ uacpi_u8 type_flags;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_address, 6);
+
+UACPI_PACKED(struct acpi_resource_address64 {
+ struct acpi_resource_address common;
+ uacpi_u64 granularity;
+ uacpi_u64 minimum;
+ uacpi_u64 maximum;
+ uacpi_u64 translation_offset;
+ uacpi_u64 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_address64, 46);
+
+UACPI_PACKED(struct acpi_resource_address32 {
+ struct acpi_resource_address common;
+ uacpi_u32 granularity;
+ uacpi_u32 minimum;
+ uacpi_u32 maximum;
+ uacpi_u32 translation_offset;
+ uacpi_u32 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_address32, 26);
+
+UACPI_PACKED(struct acpi_resource_address16 {
+ struct acpi_resource_address common;
+ uacpi_u16 granularity;
+ uacpi_u16 minimum;
+ uacpi_u16 maximum;
+ uacpi_u16 translation_offset;
+ uacpi_u16 length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_address16, 16);
+
+UACPI_PACKED(struct acpi_resource_address64_extended {
+ struct acpi_resource_address common;
+ uacpi_u8 revision_id;
+ uacpi_u8 rsvd;
+ uacpi_u64 granularity;
+ uacpi_u64 minimum;
+ uacpi_u64 maximum;
+ uacpi_u64 translation_offset;
+ uacpi_u64 length;
+ uacpi_u64 attributes;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_address64_extended, 56);
+
+UACPI_PACKED(struct acpi_resource_extended_irq {
+ struct acpi_large_item common;
+ uacpi_u8 flags;
+ uacpi_u8 num_irqs;
+ uacpi_u32 irqs[];
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_extended_irq, 5);
+
+UACPI_PACKED(struct acpi_resource_generic_register {
+ struct acpi_large_item common;
+ uacpi_u8 address_space_id;
+ uacpi_u8 bit_width;
+ uacpi_u8 bit_offset;
+ uacpi_u8 access_size;
+ uacpi_u64 address;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_generic_register, 15);
+
+UACPI_PACKED(struct acpi_resource_gpio_connection {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u8 type;
+ uacpi_u16 general_flags;
+ uacpi_u16 connection_flags;
+ uacpi_u8 pull_configuration;
+ uacpi_u16 drive_strength;
+ uacpi_u16 debounce_timeout;
+ uacpi_u16 pin_table_offset;
+ uacpi_u8 source_index;
+ uacpi_u16 source_offset;
+ uacpi_u16 vendor_data_offset;
+ uacpi_u16 vendor_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_gpio_connection, 23);
+
+#define ACPI_SERIAL_TYPE_I2C 1
+#define ACPI_SERIAL_TYPE_SPI 2
+#define ACPI_SERIAL_TYPE_UART 3
+#define ACPI_SERIAL_TYPE_CSI2 4
+#define ACPI_SERIAL_TYPE_MAX ACPI_SERIAL_TYPE_CSI2
+
+UACPI_PACKED(struct acpi_resource_serial {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u8 source_index;
+ uacpi_u8 type;
+ uacpi_u8 flags;
+ uacpi_u16 type_specific_flags;
+ uacpi_u8 type_specific_revision_id;
+ uacpi_u16 type_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_serial, 12);
+
+UACPI_PACKED(struct acpi_resource_serial_i2c {
+ struct acpi_resource_serial common;
+ uacpi_u32 connection_speed;
+ uacpi_u16 slave_address;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_serial_i2c, 18);
+
+UACPI_PACKED(struct acpi_resource_serial_spi {
+ struct acpi_resource_serial common;
+ uacpi_u32 connection_speed;
+ uacpi_u8 data_bit_length;
+ uacpi_u8 phase;
+ uacpi_u8 polarity;
+ uacpi_u16 device_selection;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_serial_spi, 21);
+
+UACPI_PACKED(struct acpi_resource_serial_uart {
+ struct acpi_resource_serial common;
+ uacpi_u32 baud_rate;
+ uacpi_u16 rx_fifo;
+ uacpi_u16 tx_fifo;
+ uacpi_u8 parity;
+ uacpi_u8 lines_enabled;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_serial_uart, 22);
+
+UACPI_PACKED(struct acpi_resource_serial_csi2 {
+ struct acpi_resource_serial common;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_serial_csi2, 12);
+
+UACPI_PACKED(struct acpi_resource_pin_function {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u16 flags;
+ uacpi_u8 pull_configuration;
+ uacpi_u16 function_number;
+ uacpi_u16 pin_table_offset;
+ uacpi_u8 source_index;
+ uacpi_u16 source_offset;
+ uacpi_u16 vendor_data_offset;
+ uacpi_u16 vendor_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_pin_function, 18);
+
+UACPI_PACKED(struct acpi_resource_pin_configuration {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u16 flags;
+ uacpi_u8 type;
+ uacpi_u32 value;
+ uacpi_u16 pin_table_offset;
+ uacpi_u8 source_index;
+ uacpi_u16 source_offset;
+ uacpi_u16 vendor_data_offset;
+ uacpi_u16 vendor_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_pin_configuration, 20);
+
+UACPI_PACKED(struct acpi_resource_pin_group {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u16 flags;
+ uacpi_u16 pin_table_offset;
+ uacpi_u16 source_lable_offset;
+ uacpi_u16 vendor_data_offset;
+ uacpi_u16 vendor_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_pin_group, 14);
+
+UACPI_PACKED(struct acpi_resource_pin_group_function {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u16 flags;
+ uacpi_u16 function;
+ uacpi_u8 source_index;
+ uacpi_u16 source_offset;
+ uacpi_u16 source_lable_offset;
+ uacpi_u16 vendor_data_offset;
+ uacpi_u16 vendor_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_pin_group_function, 17);
+
+UACPI_PACKED(struct acpi_resource_pin_group_configuration {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u16 flags;
+ uacpi_u8 type;
+ uacpi_u32 value;
+ uacpi_u8 source_index;
+ uacpi_u16 source_offset;
+ uacpi_u16 source_lable_offset;
+ uacpi_u16 vendor_data_offset;
+ uacpi_u16 vendor_data_length;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_pin_group_configuration, 20);
+
+UACPI_PACKED(struct acpi_resource_clock_input {
+ struct acpi_large_item common;
+ uacpi_u8 revision_id;
+ uacpi_u16 flags;
+ uacpi_u16 divisor;
+ uacpi_u32 numerator;
+ uacpi_u8 source_index;
+})
+UACPI_EXPECT_SIZEOF(struct acpi_resource_clock_input, 13);
diff --git a/sys/include/dev/acpi/uacpi/uacpi/context.h b/sys/include/dev/acpi/uacpi/uacpi/context.h
new file mode 100644
index 0000000..d5a46e5
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/context.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/log.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Set the minimum log level to be accepted by the logging facilities. Any logs
+ * below this level are discarded and not passed to uacpi_kernel_log, etc.
+ *
+ * 0 is treated as a special value that resets the setting to the default value.
+ *
+ * E.g. for a log level of UACPI_LOG_INFO:
+ * UACPI_LOG_DEBUG -> discarded
+ * UACPI_LOG_TRACE -> discarded
+ * UACPI_LOG_INFO -> allowed
+ * UACPI_LOG_WARN -> allowed
+ * UACPI_LOG_ERROR -> allowed
+ */
+void uacpi_context_set_log_level(uacpi_log_level);
+
+/*
+ * Enables table checksum validation at installation time instead of first use.
+ * Note that this makes uACPI map the entire table at once, which not all
+ * hosts are able to handle at early init.
+ */
+void uacpi_context_set_proactive_table_checksum(uacpi_bool);
+
+#ifndef UACPI_BAREBONES_MODE
+/*
+ * Set the maximum number of seconds a While loop is allowed to run for before
+ * getting timed out.
+ *
+ * 0 is treated a special value that resets the setting to the default value.
+ */
+void uacpi_context_set_loop_timeout(uacpi_u32 seconds);
+
+/*
+ * Set the maximum call stack depth AML can reach before getting aborted.
+ *
+ * 0 is treated as a special value that resets the setting to the default value.
+ */
+void uacpi_context_set_max_call_stack_depth(uacpi_u32 depth);
+
+uacpi_u32 uacpi_context_get_loop_timeout(void);
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/event.h b/sys/include/dev/acpi/uacpi/uacpi/event.h
new file mode 100644
index 0000000..a21fe6e
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/event.h
@@ -0,0 +1,286 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/uacpi.h>
+#include <uacpi/acpi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef enum uacpi_fixed_event {
+ UACPI_FIXED_EVENT_TIMER_STATUS = 1,
+ UACPI_FIXED_EVENT_POWER_BUTTON,
+ UACPI_FIXED_EVENT_SLEEP_BUTTON,
+ UACPI_FIXED_EVENT_RTC,
+ UACPI_FIXED_EVENT_MAX = UACPI_FIXED_EVENT_RTC,
+} uacpi_fixed_event;
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_install_fixed_event_handler(
+ uacpi_fixed_event event, uacpi_interrupt_handler handler, uacpi_handle user
+))
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_uninstall_fixed_event_handler(
+ uacpi_fixed_event event
+))
+
+/*
+ * Enable/disable a fixed event. Note that the event is automatically enabled
+ * upon installing a handler to it.
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_enable_fixed_event(uacpi_fixed_event event)
+)
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_disable_fixed_event(uacpi_fixed_event event)
+)
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_clear_fixed_event(uacpi_fixed_event event)
+)
+
+typedef enum uacpi_event_info {
+ // Event is enabled in software
+ UACPI_EVENT_INFO_ENABLED = (1 << 0),
+
+ // Event is enabled in software (only for wake)
+ UACPI_EVENT_INFO_ENABLED_FOR_WAKE = (1 << 1),
+
+ // Event is masked
+ UACPI_EVENT_INFO_MASKED = (1 << 2),
+
+ // Event has a handler attached
+ UACPI_EVENT_INFO_HAS_HANDLER = (1 << 3),
+
+ // Hardware enable bit is set
+ UACPI_EVENT_INFO_HW_ENABLED = (1 << 4),
+
+ // Hardware status bit is set
+ UACPI_EVENT_INFO_HW_STATUS = (1 << 5),
+} uacpi_event_info;
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_fixed_event_info(
+ uacpi_fixed_event event, uacpi_event_info *out_info
+))
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_gpe_info(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx,
+ uacpi_event_info *out_info
+))
+
+// Set if the handler wishes to reenable the GPE it just handled
+#define UACPI_GPE_REENABLE (1 << 7)
+
+typedef uacpi_interrupt_ret (*uacpi_gpe_handler)(
+ uacpi_handle ctx, uacpi_namespace_node *gpe_device, uacpi_u16 idx
+);
+
+typedef enum uacpi_gpe_triggering {
+ UACPI_GPE_TRIGGERING_LEVEL = 0,
+ UACPI_GPE_TRIGGERING_EDGE = 1,
+ UACPI_GPE_TRIGGERING_MAX = UACPI_GPE_TRIGGERING_EDGE,
+} uacpi_gpe_triggering;
+
+const uacpi_char *uacpi_gpe_triggering_to_string(
+ uacpi_gpe_triggering triggering
+);
+
+/*
+ * Installs a handler to the provided GPE at 'idx' controlled by device
+ * 'gpe_device'. The GPE is automatically disabled & cleared according to the
+ * configured triggering upon invoking the handler. The event is optionally
+ * re-enabled (by returning UACPI_GPE_REENABLE from the handler)
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_install_gpe_handler(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx,
+ uacpi_gpe_triggering triggering, uacpi_gpe_handler handler, uacpi_handle ctx
+))
+
+/*
+ * Installs a raw handler to the provided GPE at 'idx' controlled by device
+ * 'gpe_device'. The handler is dispatched immediately after the event is
+ * received, status & enable bits are untouched.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_install_gpe_handler_raw(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx,
+ uacpi_gpe_triggering triggering, uacpi_gpe_handler handler, uacpi_handle ctx
+))
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_uninstall_gpe_handler(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_handler handler
+))
+
+/*
+ * Marks the GPE 'idx' managed by 'gpe_device' as wake-capable. 'wake_device' is
+ * optional and configures the GPE to generate an implicit notification whenever
+ * an event occurs.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_setup_gpe_for_wake(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx,
+ uacpi_namespace_node *wake_device
+))
+
+/*
+ * Mark a GPE managed by 'gpe_device' as enabled/disabled for wake. The GPE must
+ * have previously been marked by calling uacpi_gpe_setup_for_wake. This
+ * function only affects the GPE enable register state following the call to
+ * uacpi_gpe_enable_all_for_wake.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_enable_gpe_for_wake(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_disable_gpe_for_wake(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+
+/*
+ * Finalize GPE initialization by enabling all GPEs not configured for wake and
+ * having a matching AML handler detected.
+ *
+ * This should be called after the kernel power managment subsystem has
+ * enumerated all of the devices, executing their _PRW methods etc., and
+ * marking those it wishes to use for wake by calling uacpi_setup_gpe_for_wake
+ * or uacpi_mark_gpe_for_wake.
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_finalize_gpe_initialization(void)
+)
+
+/*
+ * Enable/disable a general purpose event managed by 'gpe_device'. Internally
+ * this uses reference counting to make sure a GPE is not disabled until all
+ * possible users of it do so. GPEs not marked for wake are enabled
+ * automatically so this API is only needed for wake events or those that don't
+ * have a corresponding AML handler.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_enable_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_disable_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+
+/*
+ * Clear the status bit of the event 'idx' managed by 'gpe_device'.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_clear_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+
+/*
+ * Suspend/resume a general purpose event managed by 'gpe_device'. This bypasses
+ * the reference counting mechanism and unconditionally clears/sets the
+ * corresponding bit in the enable registers. This is used for switching the GPE
+ * to poll mode.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_suspend_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_resume_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+
+/*
+ * Finish handling the GPE managed by 'gpe_device' at 'idx'. This clears the
+ * status registers if it hasn't been cleared yet and re-enables the event if
+ * it was enabled before.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_finish_handling_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+
+/*
+ * Hard mask/umask a general purpose event at 'idx' managed by 'gpe_device'.
+ * This is used to permanently silence an event so that further calls to
+ * enable/disable as well as suspend/resume get ignored. This might be necessary
+ * for GPEs that cause an event storm due to the kernel's inability to properly
+ * handle them. The only way to enable a masked event is by a call to unmask.
+ *
+ * NOTE: 'gpe_device' may be null for GPEs managed by \_GPE
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_mask_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_unmask_gpe(
+ uacpi_namespace_node *gpe_device, uacpi_u16 idx
+))
+
+/*
+ * Disable all GPEs currently set up on the system.
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_disable_all_gpes(void)
+)
+
+/*
+ * Enable all GPEs not marked as wake. This is only needed after the system
+ * wakes from a shallow sleep state and is called automatically by wake code.
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_enable_all_runtime_gpes(void)
+)
+
+/*
+ * Enable all GPEs marked as wake. This is only needed before the system goes
+ * to sleep is called automatically by sleep code.
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_enable_all_wake_gpes(void)
+)
+
+/*
+ * Install/uninstall a new GPE block, usually defined by a device in the
+ * namespace with a _HID of ACPI0006.
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_install_gpe_block(
+ uacpi_namespace_node *gpe_device, uacpi_u64 address,
+ uacpi_address_space address_space, uacpi_u16 num_registers,
+ uacpi_u32 irq
+))
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_uninstall_gpe_block(
+ uacpi_namespace_node *gpe_device
+))
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/helpers.h b/sys/include/dev/acpi/uacpi/uacpi/helpers.h
new file mode 100644
index 0000000..520359e
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/helpers.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include <uacpi/platform/compiler.h>
+
+#define UACPI_BUILD_BUG_ON_WITH_MSG(expr, msg) UACPI_STATIC_ASSERT(!(expr), msg)
+
+#define UACPI_BUILD_BUG_ON(expr) \
+ UACPI_BUILD_BUG_ON_WITH_MSG(expr, "BUILD BUG: " #expr " evaluated to true")
+
+#define UACPI_EXPECT_SIZEOF(type, size) \
+ UACPI_BUILD_BUG_ON_WITH_MSG(sizeof(type) != size, \
+ "BUILD BUG: invalid type size")
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/compiler.h b/sys/include/dev/acpi/uacpi/uacpi/internal/compiler.h
new file mode 100644
index 0000000..68033fd
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/compiler.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include <uacpi/platform/compiler.h>
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/context.h b/sys/include/dev/acpi/uacpi/uacpi/internal/context.h
new file mode 100644
index 0000000..ca587f6
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/context.h
@@ -0,0 +1,155 @@
+#pragma once
+
+#include <uacpi/acpi.h>
+#include <uacpi/types.h>
+#include <uacpi/uacpi.h>
+#include <uacpi/internal/dynamic_array.h>
+#include <uacpi/internal/shareable.h>
+#include <uacpi/context.h>
+
+struct uacpi_runtime_context {
+ /*
+ * A local copy of FADT that has been verified & converted to most optimal
+ * format for faster access to the registers.
+ */
+ struct acpi_fadt fadt;
+
+ uacpi_u64 flags;
+
+#ifndef UACPI_BAREBONES_MODE
+ /*
+ * A cached pointer to FACS so that we don't have to look it up in interrupt
+ * contexts as we can't take mutexes.
+ */
+ struct acpi_facs *facs;
+
+ /*
+ * pm1{a,b}_evt_blk split into two registers for convenience
+ */
+ struct acpi_gas pm1a_status_blk;
+ struct acpi_gas pm1b_status_blk;
+ struct acpi_gas pm1a_enable_blk;
+ struct acpi_gas pm1b_enable_blk;
+
+#define UACPI_SLEEP_TYP_INVALID 0xFF
+ uacpi_u8 last_sleep_typ_a;
+ uacpi_u8 last_sleep_typ_b;
+
+ uacpi_u8 s0_sleep_typ_a;
+ uacpi_u8 s0_sleep_typ_b;
+
+ uacpi_bool global_lock_acquired;
+
+#ifndef UACPI_REDUCED_HARDWARE
+ uacpi_bool was_in_legacy_mode;
+ uacpi_bool has_global_lock;
+ uacpi_bool sci_handle_valid;
+ uacpi_handle sci_handle;
+#endif
+ uacpi_u64 opcodes_executed;
+
+ uacpi_u32 loop_timeout_seconds;
+ uacpi_u32 max_call_stack_depth;
+
+ uacpi_u32 global_lock_seq_num;
+
+ /*
+ * These are stored here to protect against stuff like:
+ * - CopyObject(JUNK, \)
+ * - CopyObject(JUNK, \_GL)
+ */
+ uacpi_mutex *global_lock_mutex;
+ uacpi_object *root_object;
+
+#ifndef UACPI_REDUCED_HARDWARE
+ uacpi_handle *global_lock_event;
+ uacpi_handle *global_lock_spinlock;
+ uacpi_bool global_lock_pending;
+#endif
+
+ uacpi_bool bad_timesource;
+ uacpi_u8 init_level;
+#endif // !UACPI_BAREBONES_MODE
+
+#ifndef UACPI_REDUCED_HARDWARE
+ uacpi_bool is_hardware_reduced;
+#endif
+
+ /*
+ * This is a per-table value but we mimic the NT implementation:
+ * treat all other definition blocks as if they were the same revision
+ * as DSDT.
+ */
+ uacpi_bool is_rev1;
+
+ uacpi_u8 log_level;
+};
+
+extern struct uacpi_runtime_context g_uacpi_rt_ctx;
+
+static inline uacpi_bool uacpi_check_flag(uacpi_u64 flag)
+{
+ return (g_uacpi_rt_ctx.flags & flag) == flag;
+}
+
+static inline uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
+{
+ return lvl <= g_uacpi_rt_ctx.log_level;
+}
+
+static inline uacpi_bool uacpi_is_hardware_reduced(void)
+{
+#ifndef UACPI_REDUCED_HARDWARE
+ return g_uacpi_rt_ctx.is_hardware_reduced;
+#else
+ return UACPI_TRUE;
+#endif
+}
+
+#ifndef UACPI_BAREBONES_MODE
+
+static inline const uacpi_char *uacpi_init_level_to_string(uacpi_u8 lvl)
+{
+ switch (lvl) {
+ case UACPI_INIT_LEVEL_EARLY:
+ return "early";
+ case UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED:
+ return "subsystem initialized";
+ case UACPI_INIT_LEVEL_NAMESPACE_LOADED:
+ return "namespace loaded";
+ case UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED:
+ return "namespace initialized";
+ default:
+ return "<invalid>";
+ }
+}
+
+#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl) \
+ do { \
+ if (uacpi_unlikely(g_uacpi_rt_ctx.init_level < lvl)) { \
+ uacpi_error( \
+ "while evaluating %s: init level %d (%s) is too low, " \
+ "expected at least %d (%s)\n", __FUNCTION__, \
+ g_uacpi_rt_ctx.init_level, \
+ uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
+ uacpi_init_level_to_string(lvl) \
+ ); \
+ return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
+ } \
+ } while (0)
+
+#define UACPI_ENSURE_INIT_LEVEL_IS(lvl) \
+ do { \
+ if (uacpi_unlikely(g_uacpi_rt_ctx.init_level != lvl)) { \
+ uacpi_error( \
+ "while evaluating %s: invalid init level %d (%s), " \
+ "expected %d (%s)\n", __FUNCTION__, \
+ g_uacpi_rt_ctx.init_level, \
+ uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
+ uacpi_init_level_to_string(lvl) \
+ ); \
+ return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
+ } \
+ } while (0)
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/dynamic_array.h b/sys/include/dev/acpi/uacpi/uacpi/internal/dynamic_array.h
new file mode 100644
index 0000000..4adc00f
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/dynamic_array.h
@@ -0,0 +1,185 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/internal/stdlib.h>
+#include <uacpi/kernel_api.h>
+
+#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE(name, type, inline_capacity) \
+ struct name { \
+ type inline_storage[inline_capacity]; \
+ type *dynamic_storage; \
+ uacpi_size dynamic_capacity; \
+ uacpi_size size_including_inline; \
+ }; \
+
+#define DYNAMIC_ARRAY_SIZE(arr) ((arr)->size_including_inline)
+
+#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_EXPORTS(name, type, prefix) \
+ prefix uacpi_size name##_inline_capacity(struct name *arr); \
+ prefix type *name##_at(struct name *arr, uacpi_size idx); \
+ prefix type *name##_alloc(struct name *arr); \
+ prefix type *name##_calloc(struct name *arr); \
+ prefix void name##_pop(struct name *arr); \
+ prefix uacpi_size name##_size(struct name *arr); \
+ prefix type *name##_last(struct name *arr) \
+ prefix void name##_clear(struct name *arr);
+
+#ifndef UACPI_BAREBONES_MODE
+#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
+ UACPI_MAYBE_UNUSED \
+ prefix type *name##_alloc(struct name *arr) \
+ { \
+ uacpi_size inline_cap; \
+ type *out_ptr; \
+ \
+ inline_cap = name##_inline_capacity(arr); \
+ \
+ if (arr->size_including_inline >= inline_cap) { \
+ uacpi_size dynamic_size; \
+ \
+ dynamic_size = arr->size_including_inline - inline_cap; \
+ if (dynamic_size == arr->dynamic_capacity) { \
+ uacpi_size bytes, type_size; \
+ void *new_buf; \
+ \
+ type_size = sizeof(*arr->dynamic_storage); \
+ \
+ if (arr->dynamic_capacity == 0) { \
+ bytes = type_size * inline_cap; \
+ } else { \
+ bytes = (arr->dynamic_capacity / 2) * type_size; \
+ if (bytes == 0) \
+ bytes += type_size; \
+ \
+ bytes += arr->dynamic_capacity * type_size; \
+ } \
+ \
+ new_buf = uacpi_kernel_alloc(bytes); \
+ if (uacpi_unlikely(new_buf == UACPI_NULL)) \
+ return UACPI_NULL; \
+ \
+ arr->dynamic_capacity = bytes / type_size; \
+ \
+ if (arr->dynamic_storage) { \
+ uacpi_memcpy(new_buf, arr->dynamic_storage, \
+ dynamic_size * type_size); \
+ } \
+ uacpi_free(arr->dynamic_storage, dynamic_size * type_size); \
+ arr->dynamic_storage = new_buf; \
+ } \
+ \
+ out_ptr = &arr->dynamic_storage[dynamic_size]; \
+ goto ret; \
+ } \
+ out_ptr = &arr->inline_storage[arr->size_including_inline]; \
+ ret: \
+ arr->size_including_inline++; \
+ return out_ptr; \
+ }
+
+#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
+ prefix void name##_clear(struct name *arr) \
+ { \
+ uacpi_free( \
+ arr->dynamic_storage, \
+ arr->dynamic_capacity * sizeof(*arr->dynamic_storage) \
+ ); \
+ arr->size_including_inline = 0; \
+ arr->dynamic_capacity = 0; \
+ arr->dynamic_storage = UACPI_NULL; \
+ }
+#else
+#define DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
+ UACPI_MAYBE_UNUSED \
+ prefix type *name##_alloc(struct name *arr) \
+ { \
+ uacpi_size inline_cap; \
+ type *out_ptr; \
+ \
+ inline_cap = name##_inline_capacity(arr); \
+ \
+ if (arr->size_including_inline >= inline_cap) { \
+ uacpi_size dynamic_size; \
+ \
+ dynamic_size = arr->size_including_inline - inline_cap; \
+ if (uacpi_unlikely(dynamic_size == arr->dynamic_capacity)) \
+ return UACPI_NULL; \
+ \
+ out_ptr = &arr->dynamic_storage[dynamic_size]; \
+ goto ret; \
+ } \
+ out_ptr = &arr->inline_storage[arr->size_including_inline]; \
+ ret: \
+ arr->size_including_inline++; \
+ return out_ptr; \
+ }
+
+#define DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix) \
+ prefix void name##_clear(struct name *arr) \
+ { \
+ arr->size_including_inline = 0; \
+ arr->dynamic_capacity = 0; \
+ arr->dynamic_storage = UACPI_NULL; \
+ }
+#endif
+
+#define DYNAMIC_ARRAY_WITH_INLINE_STORAGE_IMPL(name, type, prefix) \
+ UACPI_MAYBE_UNUSED \
+ prefix uacpi_size name##_inline_capacity(struct name *arr) \
+ { \
+ return sizeof(arr->inline_storage) / sizeof(arr->inline_storage[0]); \
+ } \
+ \
+ UACPI_MAYBE_UNUSED \
+ prefix uacpi_size name##_capacity(struct name *arr) \
+ { \
+ return name##_inline_capacity(arr) + arr->dynamic_capacity; \
+ } \
+ \
+ prefix type *name##_at(struct name *arr, uacpi_size idx) \
+ { \
+ if (idx >= arr->size_including_inline) \
+ return UACPI_NULL; \
+ \
+ if (idx < name##_inline_capacity(arr)) \
+ return &arr->inline_storage[idx]; \
+ \
+ return &arr->dynamic_storage[idx - name##_inline_capacity(arr)]; \
+ } \
+ \
+ DYNAMIC_ARRAY_ALLOC_FN(name, type, prefix) \
+ \
+ UACPI_MAYBE_UNUSED \
+ prefix type *name##_calloc(struct name *arr) \
+ { \
+ type *ret; \
+ \
+ ret = name##_alloc(arr); \
+ if (ret) \
+ uacpi_memzero(ret, sizeof(*ret)); \
+ \
+ return ret; \
+ } \
+ \
+ UACPI_MAYBE_UNUSED \
+ prefix void name##_pop(struct name *arr) \
+ { \
+ if (arr->size_including_inline == 0) \
+ return; \
+ \
+ arr->size_including_inline--; \
+ } \
+ \
+ UACPI_MAYBE_UNUSED \
+ prefix uacpi_size name##_size(struct name *arr) \
+ { \
+ return arr->size_including_inline; \
+ } \
+ \
+ UACPI_MAYBE_UNUSED \
+ prefix type *name##_last(struct name *arr) \
+ { \
+ return name##_at(arr, arr->size_including_inline - 1); \
+ } \
+ \
+ DYNAMIC_ARRAY_CLEAR_FN(name, type, prefix)
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/event.h b/sys/include/dev/acpi/uacpi/uacpi/internal/event.h
new file mode 100644
index 0000000..40ced0d
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/event.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <uacpi/event.h>
+
+// This fixed event is internal-only, and we don't expose it in the enum
+#define UACPI_FIXED_EVENT_GLOBAL_LOCK 0
+
+UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_initialize_events_early(void)
+)
+
+UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_initialize_events(void)
+)
+UACPI_STUB_IF_REDUCED_HARDWARE(
+ void uacpi_deinitialize_events(void)
+)
+
+UACPI_STUB_IF_REDUCED_HARDWARE(
+ void uacpi_events_match_post_dynamic_table_load(void)
+)
+
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_clear_all_events(void)
+)
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/helpers.h b/sys/include/dev/acpi/uacpi/uacpi/internal/helpers.h
new file mode 100644
index 0000000..f02b589
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/helpers.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <uacpi/helpers.h>
+
+#define UACPI_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+#define UACPI_UNUSED(x) (void)(x)
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/interpreter.h b/sys/include/dev/acpi/uacpi/uacpi/internal/interpreter.h
new file mode 100644
index 0000000..410c379
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/interpreter.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+#include <uacpi/internal/namespace.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+enum uacpi_table_load_cause {
+ UACPI_TABLE_LOAD_CAUSE_LOAD_OP,
+ UACPI_TABLE_LOAD_CAUSE_LOAD_TABLE_OP,
+ UACPI_TABLE_LOAD_CAUSE_INIT,
+ UACPI_TABLE_LOAD_CAUSE_HOST,
+};
+
+uacpi_status uacpi_execute_table(void*, enum uacpi_table_load_cause cause);
+uacpi_status uacpi_osi(uacpi_handle handle, uacpi_object *retval);
+
+uacpi_status uacpi_execute_control_method(
+ uacpi_namespace_node *scope, uacpi_control_method *method,
+ const uacpi_object_array *args, uacpi_object **ret
+);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/io.h b/sys/include/dev/acpi/uacpi/uacpi/internal/io.h
new file mode 100644
index 0000000..839489a
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/io.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include <uacpi/internal/types.h>
+#include <uacpi/acpi.h>
+#include <uacpi/io.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef struct uacpi_mapped_gas {
+ uacpi_handle mapping;
+ uacpi_u8 access_bit_width;
+ uacpi_u8 total_bit_width;
+ uacpi_u8 bit_offset;
+
+ uacpi_status (*read)(
+ uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
+ );
+ uacpi_status (*write)(
+ uacpi_handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
+ );
+
+ void (*unmap)(uacpi_handle, uacpi_size);
+} uacpi_mapped_gas;
+
+uacpi_status uacpi_map_gas_noalloc(
+ const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped
+);
+void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas);
+
+uacpi_size uacpi_round_up_bits_to_bytes(uacpi_size bit_length);
+
+void uacpi_read_buffer_field(
+ const uacpi_buffer_field *field, void *dst
+);
+void uacpi_write_buffer_field(
+ uacpi_buffer_field *field, const void *src, uacpi_size size
+);
+
+uacpi_status uacpi_field_unit_get_read_type(
+ struct uacpi_field_unit *field, uacpi_object_type *out_type
+);
+
+uacpi_status uacpi_field_unit_get_bit_length(
+ struct uacpi_field_unit *field, uacpi_size *out_length
+);
+
+uacpi_status uacpi_read_field_unit(
+ uacpi_field_unit *field, void *dst, uacpi_size size,
+ uacpi_data_view *wtr_response
+);
+uacpi_status uacpi_write_field_unit(
+ uacpi_field_unit *field, const void *src, uacpi_size size,
+ uacpi_data_view *wtr_response
+);
+
+uacpi_status uacpi_system_memory_read(
+ void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
+);
+uacpi_status uacpi_system_memory_write(
+ void *ptr, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
+);
+
+uacpi_status uacpi_system_io_read(
+ uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
+);
+uacpi_status uacpi_system_io_write(
+ uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
+);
+
+uacpi_status uacpi_pci_read(
+ uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 *out
+);
+uacpi_status uacpi_pci_write(
+ uacpi_handle handle, uacpi_size offset, uacpi_u8 width, uacpi_u64 in
+);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/log.h b/sys/include/dev/acpi/uacpi/uacpi/internal/log.h
new file mode 100644
index 0000000..e8b0451
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/log.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <uacpi/kernel_api.h>
+#include <uacpi/internal/context.h>
+#include <uacpi/log.h>
+
+#ifdef UACPI_FORMATTED_LOGGING
+#define uacpi_log uacpi_kernel_log
+#else
+UACPI_PRINTF_DECL(2, 3)
+void uacpi_log(uacpi_log_level, const uacpi_char*, ...);
+#endif
+
+#define uacpi_log_lvl(lvl, ...) \
+ do { if (uacpi_should_log(lvl)) uacpi_log(lvl, __VA_ARGS__); } while (0)
+
+#define uacpi_debug(...) uacpi_log_lvl(UACPI_LOG_DEBUG, __VA_ARGS__)
+#define uacpi_trace(...) uacpi_log_lvl(UACPI_LOG_TRACE, __VA_ARGS__)
+#define uacpi_info(...) uacpi_log_lvl(UACPI_LOG_INFO, __VA_ARGS__)
+#define uacpi_warn(...) uacpi_log_lvl(UACPI_LOG_WARN, __VA_ARGS__)
+#define uacpi_error(...) uacpi_log_lvl(UACPI_LOG_ERROR, __VA_ARGS__)
+
+void uacpi_logger_initialize(void);
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/mutex.h b/sys/include/dev/acpi/uacpi/uacpi/internal/mutex.h
new file mode 100644
index 0000000..4fa2c9b
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/mutex.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#include <uacpi/internal/types.h>
+#include <uacpi/kernel_api.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+uacpi_bool uacpi_this_thread_owns_aml_mutex(uacpi_mutex*);
+
+uacpi_status uacpi_acquire_aml_mutex(uacpi_mutex*, uacpi_u16 timeout);
+uacpi_status uacpi_release_aml_mutex(uacpi_mutex*);
+
+static inline uacpi_status uacpi_acquire_native_mutex(uacpi_handle mtx)
+{
+ if (uacpi_unlikely(mtx == UACPI_NULL))
+ return UACPI_STATUS_INVALID_ARGUMENT;
+
+ return uacpi_kernel_acquire_mutex(mtx, 0xFFFF);
+}
+
+uacpi_status uacpi_acquire_native_mutex_with_timeout(
+ uacpi_handle mtx, uacpi_u16 timeout
+);
+
+static inline uacpi_status uacpi_release_native_mutex(uacpi_handle mtx)
+{
+ if (uacpi_unlikely(mtx == UACPI_NULL))
+ return UACPI_STATUS_INVALID_ARGUMENT;
+
+ uacpi_kernel_release_mutex(mtx);
+ return UACPI_STATUS_OK;
+}
+
+static inline uacpi_status uacpi_acquire_native_mutex_may_be_null(
+ uacpi_handle mtx
+)
+{
+ if (mtx == UACPI_NULL)
+ return UACPI_STATUS_OK;
+
+ return uacpi_kernel_acquire_mutex(mtx, 0xFFFF);
+}
+
+static inline uacpi_status uacpi_release_native_mutex_may_be_null(
+ uacpi_handle mtx
+)
+{
+ if (mtx == UACPI_NULL)
+ return UACPI_STATUS_OK;
+
+ uacpi_kernel_release_mutex(mtx);
+ return UACPI_STATUS_OK;
+}
+
+struct uacpi_recursive_lock {
+ uacpi_handle mutex;
+ uacpi_size depth;
+ uacpi_thread_id owner;
+};
+
+uacpi_status uacpi_recursive_lock_init(struct uacpi_recursive_lock *lock);
+uacpi_status uacpi_recursive_lock_deinit(struct uacpi_recursive_lock *lock);
+
+uacpi_status uacpi_recursive_lock_acquire(struct uacpi_recursive_lock *lock);
+uacpi_status uacpi_recursive_lock_release(struct uacpi_recursive_lock *lock);
+
+struct uacpi_rw_lock {
+ uacpi_handle read_mutex;
+ uacpi_handle write_mutex;
+ uacpi_size num_readers;
+};
+
+uacpi_status uacpi_rw_lock_init(struct uacpi_rw_lock *lock);
+uacpi_status uacpi_rw_lock_deinit(struct uacpi_rw_lock *lock);
+
+uacpi_status uacpi_rw_lock_read(struct uacpi_rw_lock *lock);
+uacpi_status uacpi_rw_unlock_read(struct uacpi_rw_lock *lock);
+
+uacpi_status uacpi_rw_lock_write(struct uacpi_rw_lock *lock);
+uacpi_status uacpi_rw_unlock_write(struct uacpi_rw_lock *lock);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/namespace.h b/sys/include/dev/acpi/uacpi/uacpi/internal/namespace.h
new file mode 100644
index 0000000..369c5a4
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/namespace.h
@@ -0,0 +1,123 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/internal/shareable.h>
+#include <uacpi/status.h>
+#include <uacpi/namespace.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+#define UACPI_NAMESPACE_NODE_FLAG_ALIAS (1 << 0)
+
+/*
+ * This node has been uninstalled and has no object associated with it.
+ *
+ * This is used to handle edge cases where an object needs to reference
+ * a namespace node, where the node might end up going out of scope before
+ * the object lifetime ends.
+ */
+#define UACPI_NAMESPACE_NODE_FLAG_DANGLING (1u << 1)
+
+/*
+ * This node is method-local and must not be exposed via public API as its
+ * lifetime is limited.
+ */
+#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY (1u << 2)
+
+#define UACPI_NAMESPACE_NODE_PREDEFINED (1u << 31)
+
+typedef struct uacpi_namespace_node {
+ struct uacpi_shareable shareable;
+ uacpi_object_name name;
+ uacpi_u32 flags;
+ uacpi_object *object;
+ struct uacpi_namespace_node *parent;
+ struct uacpi_namespace_node *child;
+ struct uacpi_namespace_node *next;
+} uacpi_namespace_node;
+
+uacpi_status uacpi_initialize_namespace(void);
+void uacpi_deinitialize_namespace(void);
+
+uacpi_namespace_node *uacpi_namespace_node_alloc(uacpi_object_name name);
+void uacpi_namespace_node_unref(uacpi_namespace_node *node);
+
+
+uacpi_status uacpi_namespace_node_type_unlocked(
+ const uacpi_namespace_node *node, uacpi_object_type *out_type
+);
+uacpi_status uacpi_namespace_node_is_one_of_unlocked(
+ const uacpi_namespace_node *node, uacpi_object_type_bits type_mask,
+ uacpi_bool *out
+);
+
+uacpi_object *uacpi_namespace_node_get_object(const uacpi_namespace_node *node);
+
+uacpi_object *uacpi_namespace_node_get_object_typed(
+ const uacpi_namespace_node *node, uacpi_object_type_bits type_mask
+);
+
+uacpi_status uacpi_namespace_node_acquire_object(
+ const uacpi_namespace_node *node, uacpi_object **out_obj
+);
+uacpi_status uacpi_namespace_node_acquire_object_typed(
+ const uacpi_namespace_node *node, uacpi_object_type_bits,
+ uacpi_object **out_obj
+);
+
+uacpi_status uacpi_namespace_node_reacquire_object(
+ uacpi_object *obj
+);
+uacpi_status uacpi_namespace_node_release_object(
+ uacpi_object *obj
+);
+
+uacpi_status uacpi_namespace_node_install(
+ uacpi_namespace_node *parent, uacpi_namespace_node *node
+);
+uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node);
+
+uacpi_namespace_node *uacpi_namespace_node_find_sub_node(
+ uacpi_namespace_node *parent,
+ uacpi_object_name name
+);
+
+enum uacpi_may_search_above_parent {
+ UACPI_MAY_SEARCH_ABOVE_PARENT_NO,
+ UACPI_MAY_SEARCH_ABOVE_PARENT_YES,
+};
+
+enum uacpi_permanent_only {
+ UACPI_PERMANENT_ONLY_NO,
+ UACPI_PERMANENT_ONLY_YES,
+};
+
+enum uacpi_should_lock {
+ UACPI_SHOULD_LOCK_NO,
+ UACPI_SHOULD_LOCK_YES,
+};
+
+uacpi_status uacpi_namespace_node_resolve(
+ uacpi_namespace_node *scope, const uacpi_char *path, enum uacpi_should_lock,
+ enum uacpi_may_search_above_parent, enum uacpi_permanent_only,
+ uacpi_namespace_node **out_node
+);
+
+uacpi_status uacpi_namespace_do_for_each_child(
+ uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback,
+ uacpi_iteration_callback ascending_callback,
+ uacpi_object_type_bits, uacpi_u32 max_depth, enum uacpi_should_lock,
+ enum uacpi_permanent_only, void *user
+);
+
+uacpi_bool uacpi_namespace_node_is_dangling(uacpi_namespace_node *node);
+uacpi_bool uacpi_namespace_node_is_temporary(uacpi_namespace_node *node);
+uacpi_bool uacpi_namespace_node_is_predefined(uacpi_namespace_node *node);
+
+uacpi_status uacpi_namespace_read_lock(void);
+uacpi_status uacpi_namespace_read_unlock(void);
+
+uacpi_status uacpi_namespace_write_lock(void);
+uacpi_status uacpi_namespace_write_unlock(void);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/notify.h b/sys/include/dev/acpi/uacpi/uacpi/internal/notify.h
new file mode 100644
index 0000000..c1fa8bb
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/notify.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <uacpi/internal/types.h>
+#include <uacpi/notify.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+uacpi_status uacpi_initialize_notify(void);
+void uacpi_deinitialize_notify(void);
+
+uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/opcodes.h b/sys/include/dev/acpi/uacpi/uacpi/internal/opcodes.h
new file mode 100644
index 0000000..53ef334
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/opcodes.h
@@ -0,0 +1,1390 @@
+#pragma once
+
+#include <uacpi/types.h>
+
+typedef uacpi_u16 uacpi_aml_op;
+
+#define UACPI_EXT_PREFIX 0x5B
+#define UACPI_EXT_OP(op) ((UACPI_EXT_PREFIX << 8) | (op))
+
+#define UACPI_DUAL_NAME_PREFIX 0x2E
+#define UACPI_MULTI_NAME_PREFIX 0x2F
+#define UACPI_NULL_NAME 0x00
+
+/*
+ * Opcodes that tell the parser VM how to take apart every AML instruction.
+ * Every AML opcode has a list of these that is executed by the parser.
+ */
+enum uacpi_parse_op {
+ UACPI_PARSE_OP_END = 0,
+
+ /*
+ * End the execution of the current instruction with a warning if the item
+ * at decode_ops[pc + 1] is NULL.
+ */
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL,
+
+ // Emit a warning as if the current opcode is being skipped
+ UACPI_PARSE_OP_EMIT_SKIP_WARN,
+
+ // SimpleName := NameString | ArgObj | LocalObj
+ UACPI_PARSE_OP_SIMPLE_NAME,
+
+ // SuperName := SimpleName | DebugObj | ReferenceTypeOpcode
+ UACPI_PARSE_OP_SUPERNAME,
+ // The resulting item will be set to null if name couldn't be resolved
+ UACPI_PARSE_OP_SUPERNAME_OR_UNRESOLVED,
+
+ // TermArg := ExpressionOpcode | DataObject | ArgObj | LocalObj
+ UACPI_PARSE_OP_TERM_ARG,
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL,
+
+ /*
+ * Same as TERM_ARG, but named references are passed as-is.
+ * This means methods are not invoked, fields are not read, etc.
+ */
+ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT,
+
+ /*
+ * Same as UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT but allows unresolved
+ * name strings.
+ */
+ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT_OR_UNRESOLVED,
+
+ // Operand := TermArg => Integer
+ UACPI_PARSE_OP_OPERAND,
+
+ // TermArg => String
+ UACPI_PARSE_OP_STRING,
+
+ /*
+ * ComputationalData := ByteConst | WordConst | DWordConst | QWordConst |
+ * String | ConstObj | RevisionOp | DefBuffer
+ */
+ UACPI_PARSE_OP_COMPUTATIONAL_DATA,
+
+ // Target := SuperName | NullName
+ UACPI_PARSE_OP_TARGET,
+
+ // Parses a pkglen
+ UACPI_PARSE_OP_PKGLEN,
+
+ /*
+ * Parses a pkglen and records it, the end of this pkglen is considered
+ * the end of the instruction. The PC is always set to the end of this
+ * package once parser reaches UACPI_PARSE_OP_END.
+ */
+ UACPI_PARSE_OP_TRACKED_PKGLEN,
+
+ /*
+ * Parse a NameString and create the last nameseg.
+ * Note that this errors out if last nameseg already exists.
+ */
+ UACPI_PARSE_OP_CREATE_NAMESTRING,
+
+ /*
+ * same as UACPI_PARSE_OP_CREATE_NAMESTRING, but attempting to create an
+ * already existing object is not fatal if currently loading a table.
+ */
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD,
+
+ /*
+ * Parse a NameString and put the node into the ready parts array.
+ * Note that this errors out if the referenced node doesn't exist.
+ */
+ UACPI_PARSE_OP_EXISTING_NAMESTRING,
+
+ /*
+ * Same as UACPI_PARSE_OP_EXISTING_NAMESTRING except the op doesn't error
+ * out if namestring couldn't be resolved.
+ */
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL,
+
+ /*
+ * Same as UACPI_PARSE_OP_EXISTING_NAMESTRING, but undefined references
+ * are not fatal if currently loading a table.
+ */
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL_IF_LOAD,
+
+ // Invoke a handler at op_handlers[spec->code]
+ UACPI_PARSE_OP_INVOKE_HANDLER,
+
+ // Allocate an object an put it at the front of the item list
+ UACPI_PARSE_OP_OBJECT_ALLOC,
+
+ UACPI_PARSE_OP_EMPTY_OBJECT_ALLOC,
+
+ // Convert last item into a shallow/deep copy of itself
+ UACPI_PARSE_OP_OBJECT_CONVERT_TO_SHALLOW_COPY,
+ UACPI_PARSE_OP_OBJECT_CONVERT_TO_DEEP_COPY,
+
+ /*
+ * Same as UACPI_PARSE_OP_OBJECT_ALLOC except the type of the allocated
+ * object is specified at decode_ops[pc + 1]
+ */
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED,
+
+ // Record current AML program counter as a QWORD immediate
+ UACPI_PARSE_OP_RECORD_AML_PC,
+
+ // Load a QWORD immediate located at decode_ops[pc + 1]
+ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT,
+
+ // Load a decode_ops[pc + 1] byte imm at decode_ops[pc + 2]
+ UACPI_PARSE_OP_LOAD_INLINE_IMM,
+
+ // Load a QWORD zero immediate
+ UACPI_PARSE_OP_LOAD_ZERO_IMM,
+
+ // Load a decode_ops[pc + 1] byte imm from the instructions stream
+ UACPI_PARSE_OP_LOAD_IMM,
+
+ // Same as UACPI_PARSE_OP_LOAD_IMM, expect the resulting value is an object
+ UACPI_PARSE_OP_LOAD_IMM_AS_OBJECT,
+
+ // Create & Load an integer constant representing either true or false
+ UACPI_PARSE_OP_LOAD_FALSE_OBJECT,
+ UACPI_PARSE_OP_LOAD_TRUE_OBJECT,
+
+ // Truncate the last item in the list if needed
+ UACPI_PARSE_OP_TRUNCATE_NUMBER,
+
+ // Ensure the type of item is decode_ops[pc + 1]
+ UACPI_PARSE_OP_TYPECHECK,
+
+ // Install the namespace node specified in items[decode_ops[pc + 1]]
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE,
+
+ // Move item to the previous (preempted) op
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV,
+
+ /*
+ * Same as UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, but the object
+ * is copied instead. (Useful when dealing with multiple targets)
+ * TODO: optimize this so that we can optionally move the object
+ * if target was a null target.
+ */
+ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV,
+
+ // Store the last item to the target at items[decode_ops[pc + 1]]
+ UACPI_PARSE_OP_STORE_TO_TARGET,
+
+ /*
+ * Store the item at items[decode_ops[pc + 2]] to target
+ * at items[decode_ops[pc + 1]]
+ */
+ UACPI_PARSE_OP_STORE_TO_TARGET_INDIRECT,
+
+ /*
+ * Error if reached. Should be used for opcodes that are supposed to be
+ * converted at op parse time, e.g. invoking a method or referring to
+ * a named object.
+ */
+ UACPI_PARSE_OP_UNREACHABLE,
+
+ // Invalid opcode, should never be encountered in the stream
+ UACPI_PARSE_OP_BAD_OPCODE,
+
+ // Decrement the current AML instruction pointer
+ UACPI_PARSE_OP_AML_PC_DECREMENT,
+
+ // Decrement the immediate at decode_ops[pc + 1]
+ UACPI_PARSE_OP_IMM_DECREMENT,
+
+ // Remove the last item off the item stack
+ UACPI_PARSE_OP_ITEM_POP,
+
+ // Dispatch the method call from items[0] and return from current op_exec
+ UACPI_PARSE_OP_DISPATCH_METHOD_CALL,
+
+ /*
+ * Dispatch a table load with scope node at items[0] and method at items[1].
+ * The last item is expected to be an integer object that is set to 0 in
+ * case load fails.
+ */
+ UACPI_PARSE_OP_DISPATCH_TABLE_LOAD,
+
+ /*
+ * Convert the current resolved namestring to either a method call
+ * or a named object reference.
+ */
+ UACPI_PARSE_OP_CONVERT_NAMESTRING,
+
+ /*
+ * Execute the next instruction only if currently tracked package still
+ * has data left, otherwise skip decode_ops[pc + 1] bytes.
+ */
+ UACPI_PARSE_OP_IF_HAS_DATA,
+
+ /*
+ * Execute the next instruction only if the handle at
+ * items[decode_ops[pc + 1]] is null. Otherwise skip
+ * decode_ops[pc + 2] bytes.
+ */
+ UACPI_PARSE_OP_IF_NULL,
+
+ /*
+ * Execute the next instruction only if the handle at
+ * items[-1] is null. Otherwise skip decode_ops[pc + 1] bytes.
+ */
+ UACPI_PARSE_OP_IF_LAST_NULL,
+
+ // The inverse of UACPI_PARSE_OP_IF_NULL
+ UACPI_PARSE_OP_IF_NOT_NULL,
+
+ // The inverse of UACPI_PARSE_OP_IF_LAST_NULL
+ UACPI_PARSE_OP_IF_LAST_NOT_NULL,
+
+ /*
+ * Execute the next instruction only if the last immediate is equal to
+ * decode_ops[pc + 1], otherwise skip decode_ops[pc + 2] bytes.
+ */
+ UACPI_PARSE_OP_IF_LAST_EQUALS,
+
+ /*
+ * Execute the next instruction only if the last object is a false value
+ * (has a value of 0), otherwise skip decode_ops[pc + 1] bytes.
+ */
+ UACPI_PARSE_OP_IF_LAST_FALSE,
+
+ // The inverse of UACPI_PARSE_OP_IF_LAST_FALSE
+ UACPI_PARSE_OP_IF_LAST_TRUE,
+
+ /*
+ * Switch to opcode at decode_ops[pc + 1] only if the next AML instruction
+ * in the stream is equal to it. Note that this looks ahead of the tracked
+ * package if one is active. Switching to the next op also applies the
+ * currently tracked package.
+ */
+ UACPI_PARSE_OP_SWITCH_TO_NEXT_IF_EQUALS,
+
+ /*
+ * Execute the next instruction only if this op was switched to from op at
+ * (decode_ops[pc + 1] | decode_ops[pc + 2] << 8), otherwise skip
+ * decode_ops[pc + 3] bytes.
+ */
+ UACPI_PARSE_OP_IF_SWITCHED_FROM,
+
+ /*
+ * pc = decode_ops[pc + 1]
+ */
+ UACPI_PARSE_OP_JMP,
+ UACPI_PARSE_OP_MAX = UACPI_PARSE_OP_JMP,
+};
+const uacpi_char *uacpi_parse_op_to_string(enum uacpi_parse_op op);
+
+/*
+ * A few notes about op properties:
+ * Technically the spec says that RefOfOp is considered a SuperName, but NT
+ * disagrees about this. For example Store(..., RefOf) fails with
+ * "Invalid SuperName". MethodInvocation could also technically be considered
+ * a SuperName, but NT doesn't allow that either: Store(..., MethodInvocation)
+ * fails with "Invalid Target Method, expected a DataObject" error.
+ */
+
+enum uacpi_op_property {
+ UACPI_OP_PROPERTY_TERM_ARG = 1,
+ UACPI_OP_PROPERTY_SUPERNAME = 2,
+ UACPI_OP_PROPERTY_SIMPLE_NAME = 4,
+ UACPI_OP_PROPERTY_TARGET = 8,
+
+ // The ops to execute are pointed to by indirect_decode_ops
+ UACPI_OP_PROPERTY_OUT_OF_LINE = 16,
+
+ // Error if encountered in the AML byte strem
+ UACPI_OP_PROPERTY_RESERVED = 128,
+};
+
+struct uacpi_op_spec {
+ uacpi_char *name;
+ union {
+ uacpi_u8 decode_ops[16];
+ uacpi_u8 *indirect_decode_ops;
+ };
+ uacpi_u8 properties;
+ uacpi_aml_op code;
+};
+
+const struct uacpi_op_spec *uacpi_get_op_spec(uacpi_aml_op);
+
+#define UACPI_INTERNAL_OP(code) \
+ UACPI_OP(Internal_##code, code, 0, { UACPI_PARSE_OP_UNREACHABLE })
+
+#define UACPI_BAD_OPCODE(code) \
+ UACPI_OP(Reserved_##code, code, 0, { UACPI_PARSE_OP_BAD_OPCODE })
+
+#define UACPI_METHOD_CALL_OPCODE(nargs) \
+ UACPI_OP( \
+ InternalOpMethodCall##nargs##Args, 0xF7 + nargs, \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_RESERVED, \
+ { \
+ UACPI_PARSE_OP_LOAD_INLINE_IMM, 1, nargs, \
+ UACPI_PARSE_OP_IF_NOT_NULL, 1, 6, \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_OBJECT_CONVERT_TO_SHALLOW_COPY, \
+ UACPI_PARSE_OP_IMM_DECREMENT, 1, \
+ UACPI_PARSE_OP_JMP, 3, \
+ UACPI_PARSE_OP_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_DISPATCH_METHOD_CALL, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+ )
+
+/*
+ * -------------------------------------------------------------
+ * RootChar := ‘\’
+ * ParentPrefixChar := ‘^’
+ * ‘\’ := 0x5C
+ * ‘^’ := 0x5E
+ * MultiNamePrefix := 0x2F
+ * DualNamePrefix := 0x2E
+ * ------------------------------------------------------------
+ * ‘A’-‘Z’ := 0x41 - 0x5A
+ * ‘_’ := 0x5F
+ * LeadNameChar := ‘A’-‘Z’ | ‘_’
+ * NameSeg := <leadnamechar namechar namechar namechar>
+ * NameString := <rootchar namepath> | <prefixpath namepath>
+ * PrefixPath := Nothing | <’^’ prefixpath>
+ * DualNamePath := DualNamePrefix NameSeg NameSeg
+ * MultiNamePath := MultiNamePrefix SegCount NameSeg(SegCount)
+ */
+#define UACPI_UNRESOLVED_NAME_STRING_OP(character, code) \
+ UACPI_OP( \
+ UACPI_InternalOpUnresolvedNameString_##character, code, \
+ UACPI_OP_PROPERTY_SIMPLE_NAME | \
+ UACPI_OP_PROPERTY_SUPERNAME | \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_AML_PC_DECREMENT, \
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL, \
+ UACPI_PARSE_OP_CONVERT_NAMESTRING, \
+ } \
+ )
+
+#define UACPI_BUILD_LOCAL_OR_ARG_OP(prefix, base, offset) \
+UACPI_OP( \
+ prefix##offset##Op, base + offset, \
+ UACPI_OP_PROPERTY_SUPERNAME | \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_SIMPLE_NAME, \
+ { \
+ UACPI_PARSE_OP_EMPTY_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+
+#define UACPI_LOCALX_OP(idx) UACPI_BUILD_LOCAL_OR_ARG_OP(Local, 0x60, idx)
+#define UACPI_ARGX_OP(idx) UACPI_BUILD_LOCAL_OR_ARG_OP(Arg, 0x68, idx)
+
+#define UACPI_BUILD_PACKAGE_OP(name, code, jmp_off, ...) \
+UACPI_OP( \
+ name##Op, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ ##__VA_ARGS__, \
+ UACPI_PARSE_OP_IF_HAS_DATA, 4, \
+ UACPI_PARSE_OP_RECORD_AML_PC, \
+ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT_OR_UNRESOLVED, \
+ UACPI_PARSE_OP_JMP, jmp_off, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_PACKAGE, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+)
+
+#define UACPI_BUILD_BINARY_MATH_OP(prefix, code) \
+UACPI_OP( \
+ prefix##Op, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_TRUNCATE_NUMBER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 2, \
+ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV, \
+ } \
+)
+
+#define UACPI_BUILD_UNARY_MATH_OP(type, code) \
+UACPI_OP( \
+ type##Op, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 1, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+)
+
+#define UACPI_DO_BUILD_BUFFER_FIELD_OP(type, code, node_idx, ...) \
+UACPI_OP( \
+ type##FieldOp, code, 0, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_TYPECHECK, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_OPERAND, \
+ ##__VA_ARGS__, \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, node_idx, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_BUFFER_FIELD, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, node_idx, \
+ } \
+)
+
+#define UACPI_BUILD_BUFFER_FIELD_OP(type, code) \
+ UACPI_DO_BUILD_BUFFER_FIELD_OP(Create##type, code, 2)
+
+#define UACPI_INTEGER_LITERAL_OP(type, code, bytes) \
+UACPI_OP( \
+ type##Prefix, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_LOAD_IMM_AS_OBJECT, bytes, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+
+#define UACPI_BUILD_BINARY_LOGIC_OP(type, code) \
+UACPI_OP( \
+ type##Op, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_COMPUTATIONAL_DATA, \
+ UACPI_PARSE_OP_COMPUTATIONAL_DATA, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+)
+
+#define UACPI_BUILD_TO_OP(kind, code, dst_type) \
+UACPI_OP( \
+ To##kind##Op, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_COMPUTATIONAL_DATA, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, dst_type, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 1, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+)
+
+#define UACPI_BUILD_INC_DEC_OP(prefix, code) \
+UACPI_OP( \
+ prefix##Op, code, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_TRUNCATE_NUMBER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 0, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+
+#define UACPI_ENUMERATE_OPCODES \
+UACPI_OP( \
+ ZeroOp, 0x00, \
+ UACPI_OP_PROPERTY_TARGET | \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ OneOp, 0x01, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT, \
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BAD_OPCODE(0x02) \
+UACPI_BAD_OPCODE(0x03) \
+UACPI_BAD_OPCODE(0x04) \
+UACPI_BAD_OPCODE(0x05) \
+UACPI_OP( \
+ AliasOp, 0x06, 0, \
+ { \
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 1, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 1, \
+ } \
+) \
+UACPI_BAD_OPCODE(0x07) \
+UACPI_OP( \
+ NameOp, 0x08, 0, \
+ { \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_OBJECT_CONVERT_TO_DEEP_COPY, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 0, \
+ } \
+) \
+UACPI_BAD_OPCODE(0x09) \
+UACPI_INTEGER_LITERAL_OP(Byte, 0x0A, 1) \
+UACPI_INTEGER_LITERAL_OP(Word, 0x0B, 2) \
+UACPI_INTEGER_LITERAL_OP(DWord, 0x0C, 4) \
+UACPI_OP( \
+ StringPrefix, 0x0D, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_STRING, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_INTEGER_LITERAL_OP(QWord, 0x0E, 8) \
+UACPI_BAD_OPCODE(0x0F) \
+UACPI_OP( \
+ ScopeOp, 0x10, 0, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 1, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ BufferOp, 0x11, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_RECORD_AML_PC, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_PACKAGE_OP( \
+ Package, 0x12, 3, \
+ UACPI_PARSE_OP_LOAD_IMM, 1 \
+) \
+UACPI_BUILD_PACKAGE_OP( \
+ VarPackage, 0x13, 2, \
+ UACPI_PARSE_OP_OPERAND \
+) \
+UACPI_OP( \
+ MethodOp, 0x14, 0, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 1, \
+ UACPI_PARSE_OP_RECORD_AML_PC, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_METHOD, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 1, \
+ } \
+) \
+UACPI_OP( \
+ ExternalOp, 0x15, 0, \
+ { \
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ } \
+) \
+UACPI_BAD_OPCODE(0x16) \
+UACPI_BAD_OPCODE(0x17) \
+UACPI_BAD_OPCODE(0x18) \
+UACPI_BAD_OPCODE(0x19) \
+UACPI_BAD_OPCODE(0x1A) \
+UACPI_BAD_OPCODE(0x1B) \
+UACPI_BAD_OPCODE(0x1C) \
+UACPI_BAD_OPCODE(0x1D) \
+UACPI_BAD_OPCODE(0x1E) \
+UACPI_BAD_OPCODE(0x1F) \
+UACPI_BAD_OPCODE(0x20) \
+UACPI_BAD_OPCODE(0x21) \
+UACPI_BAD_OPCODE(0x22) \
+UACPI_BAD_OPCODE(0x23) \
+UACPI_BAD_OPCODE(0x24) \
+UACPI_BAD_OPCODE(0x25) \
+UACPI_BAD_OPCODE(0x26) \
+UACPI_BAD_OPCODE(0x27) \
+UACPI_BAD_OPCODE(0x28) \
+UACPI_BAD_OPCODE(0x29) \
+UACPI_BAD_OPCODE(0x2A) \
+UACPI_BAD_OPCODE(0x2B) \
+UACPI_BAD_OPCODE(0x2C) \
+UACPI_BAD_OPCODE(0x2D) \
+UACPI_UNRESOLVED_NAME_STRING_OP(DualNamePrefix, 0x2E) \
+UACPI_UNRESOLVED_NAME_STRING_OP(MultiNamePrefix, 0x2F) \
+UACPI_INTERNAL_OP(0x30) \
+UACPI_INTERNAL_OP(0x31) \
+UACPI_INTERNAL_OP(0x32) \
+UACPI_INTERNAL_OP(0x33) \
+UACPI_INTERNAL_OP(0x34) \
+UACPI_INTERNAL_OP(0x35) \
+UACPI_INTERNAL_OP(0x36) \
+UACPI_INTERNAL_OP(0x37) \
+UACPI_INTERNAL_OP(0x38) \
+UACPI_INTERNAL_OP(0x39) \
+UACPI_BAD_OPCODE(0x3A) \
+UACPI_BAD_OPCODE(0x3B) \
+UACPI_BAD_OPCODE(0x3C) \
+UACPI_BAD_OPCODE(0x3D) \
+UACPI_BAD_OPCODE(0x3E) \
+UACPI_BAD_OPCODE(0x3F) \
+UACPI_BAD_OPCODE(0x40) \
+UACPI_UNRESOLVED_NAME_STRING_OP(A, 0x41) \
+UACPI_UNRESOLVED_NAME_STRING_OP(B, 0x42) \
+UACPI_UNRESOLVED_NAME_STRING_OP(C, 0x43) \
+UACPI_UNRESOLVED_NAME_STRING_OP(D, 0x44) \
+UACPI_UNRESOLVED_NAME_STRING_OP(E, 0x45) \
+UACPI_UNRESOLVED_NAME_STRING_OP(F, 0x46) \
+UACPI_UNRESOLVED_NAME_STRING_OP(G, 0x47) \
+UACPI_UNRESOLVED_NAME_STRING_OP(H, 0x48) \
+UACPI_UNRESOLVED_NAME_STRING_OP(I, 0x49) \
+UACPI_UNRESOLVED_NAME_STRING_OP(J, 0x4A) \
+UACPI_UNRESOLVED_NAME_STRING_OP(K, 0x4B) \
+UACPI_UNRESOLVED_NAME_STRING_OP(L, 0x4C) \
+UACPI_UNRESOLVED_NAME_STRING_OP(M, 0x4D) \
+UACPI_UNRESOLVED_NAME_STRING_OP(N, 0x4E) \
+UACPI_UNRESOLVED_NAME_STRING_OP(O, 0x4F) \
+UACPI_UNRESOLVED_NAME_STRING_OP(P, 0x50) \
+UACPI_UNRESOLVED_NAME_STRING_OP(Q, 0x51) \
+UACPI_UNRESOLVED_NAME_STRING_OP(R, 0x52) \
+UACPI_UNRESOLVED_NAME_STRING_OP(S, 0x53) \
+UACPI_UNRESOLVED_NAME_STRING_OP(T, 0x54) \
+UACPI_UNRESOLVED_NAME_STRING_OP(U, 0x55) \
+UACPI_UNRESOLVED_NAME_STRING_OP(V, 0x56) \
+UACPI_UNRESOLVED_NAME_STRING_OP(W, 0x57) \
+UACPI_UNRESOLVED_NAME_STRING_OP(X, 0x58) \
+UACPI_UNRESOLVED_NAME_STRING_OP(Y, 0x59) \
+UACPI_UNRESOLVED_NAME_STRING_OP(Z, 0x5A) \
+UACPI_INTERNAL_OP(0x5B) \
+UACPI_UNRESOLVED_NAME_STRING_OP(RootChar, 0x5C) \
+UACPI_BAD_OPCODE(0x5D) \
+UACPI_UNRESOLVED_NAME_STRING_OP(ParentPrefixChar, 0x5E) \
+UACPI_UNRESOLVED_NAME_STRING_OP(Underscore, 0x5F) \
+UACPI_LOCALX_OP(0) \
+UACPI_LOCALX_OP(1) \
+UACPI_LOCALX_OP(2) \
+UACPI_LOCALX_OP(3) \
+UACPI_LOCALX_OP(4) \
+UACPI_LOCALX_OP(5) \
+UACPI_LOCALX_OP(6) \
+UACPI_LOCALX_OP(7) \
+UACPI_ARGX_OP(0) \
+UACPI_ARGX_OP(1) \
+UACPI_ARGX_OP(2) \
+UACPI_ARGX_OP(3) \
+UACPI_ARGX_OP(4) \
+UACPI_ARGX_OP(5) \
+UACPI_ARGX_OP(6) \
+UACPI_BAD_OPCODE(0x6F) \
+UACPI_OP( \
+ StoreOp, 0x70, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG, \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_ITEM_POP, \
+ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ RefOfOp, 0x71, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_BINARY_MATH_OP(Add, 0x72) \
+UACPI_OP( \
+ ConcatOp, 0x73, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_COMPUTATIONAL_DATA, \
+ UACPI_PARSE_OP_COMPUTATIONAL_DATA, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 2, \
+ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_BINARY_MATH_OP(Subtract, 0x74) \
+UACPI_BUILD_INC_DEC_OP(Increment, 0x75) \
+UACPI_BUILD_INC_DEC_OP(Decrement, 0x76) \
+UACPI_BUILD_BINARY_MATH_OP(Multiply, 0x77) \
+UACPI_OP( \
+ DivideOp, 0x78, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 3, \
+ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV, \
+ UACPI_PARSE_OP_STORE_TO_TARGET_INDIRECT, 2, 4, \
+ } \
+) \
+UACPI_BUILD_BINARY_MATH_OP(ShiftLeft, 0x79) \
+UACPI_BUILD_BINARY_MATH_OP(ShiftRight, 0x7A) \
+UACPI_BUILD_BINARY_MATH_OP(And, 0x7B) \
+UACPI_BUILD_BINARY_MATH_OP(Nand, 0x7C) \
+UACPI_BUILD_BINARY_MATH_OP(Or, 0x7D) \
+UACPI_BUILD_BINARY_MATH_OP(Nor, 0x7E) \
+UACPI_BUILD_BINARY_MATH_OP(Xor, 0x7F) \
+UACPI_BUILD_UNARY_MATH_OP(Not, 0x80) \
+UACPI_BUILD_UNARY_MATH_OP(FindSetLeftBit, 0x81) \
+UACPI_BUILD_UNARY_MATH_OP(FindSetRightBit, 0x82) \
+UACPI_OP( \
+ DerefOfOp, 0x83, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ ConcatResOp, 0x84, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_TYPECHECK, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_TYPECHECK, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 2, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_BINARY_MATH_OP(Mod, 0x85) \
+UACPI_OP( \
+ NotifyOp, 0x86, 0, \
+ { \
+ /* This is technically wrong according to spec but I was */ \
+ /* unable to find any examples of anything else after */ \
+ /* inspecting about 500 AML dumps. Spec says this is a */ \
+ /* SuperName that must evaluate to Device/ThermalZone or */ \
+ /* Processor, just ignore for now. */ \
+ UACPI_PARSE_OP_EXISTING_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ SizeOfOp, 0x87, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ IndexOp, 0x88, \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_SUPERNAME | \
+ UACPI_OP_PROPERTY_SIMPLE_NAME, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_EMPTY_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 2, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ MatchOp, 0x89, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_TYPECHECK, UACPI_OBJECT_PACKAGE, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_BUFFER_FIELD_OP(DWord, 0x8A) \
+UACPI_BUILD_BUFFER_FIELD_OP(Word, 0x8B) \
+UACPI_BUILD_BUFFER_FIELD_OP(Byte, 0x8C) \
+UACPI_BUILD_BUFFER_FIELD_OP(Bit, 0x8D) \
+UACPI_OP( \
+ ObjectTypeOp, 0x8E, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_OR_NAMED_OBJECT, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_BUFFER_FIELD_OP(QWord, 0x8F) \
+UACPI_BUILD_BINARY_LOGIC_OP(Land, 0x90) \
+UACPI_BUILD_BINARY_LOGIC_OP(Lor, 0x91) \
+UACPI_OP( \
+ LnotOp, 0x92, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_BUILD_BINARY_LOGIC_OP(LEqual, 0x93) \
+UACPI_BUILD_BINARY_LOGIC_OP(LGreater, 0x94) \
+UACPI_BUILD_BINARY_LOGIC_OP(LLess, 0x95) \
+UACPI_BUILD_TO_OP(Buffer, 0x96, UACPI_OBJECT_BUFFER) \
+UACPI_BUILD_TO_OP(DecimalString, 0x97, UACPI_OBJECT_STRING) \
+UACPI_BUILD_TO_OP(HexString, 0x98, UACPI_OBJECT_STRING) \
+UACPI_BUILD_TO_OP(Integer, 0x99, UACPI_OBJECT_INTEGER) \
+UACPI_BAD_OPCODE(0x9A) \
+UACPI_BAD_OPCODE(0x9B) \
+UACPI_OP( \
+ ToStringOp, 0x9C, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_TYPECHECK, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_STRING, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 2, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ CopyObjectOp, 0x9D, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG, \
+ UACPI_PARSE_OP_OBJECT_COPY_TO_PREV, \
+ UACPI_PARSE_OP_SIMPLE_NAME, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ MidOp, 0x9E, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 3, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ ContinueOp, 0x9F, 0, \
+ { \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ IfOp, 0xA0, 0, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_IF_LAST_NULL, 3, \
+ UACPI_PARSE_OP_EMIT_SKIP_WARN, \
+ UACPI_PARSE_OP_JMP, 9, \
+ UACPI_PARSE_OP_IF_LAST_FALSE, 4, \
+ UACPI_PARSE_OP_SWITCH_TO_NEXT_IF_EQUALS, 0xA1, 0x00, \
+ UACPI_PARSE_OP_END, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ ElseOp, 0xA1, 0, \
+ { \
+ UACPI_PARSE_OP_IF_SWITCHED_FROM, 0xA0, 0x00, 10, \
+ UACPI_PARSE_OP_IF_LAST_NULL, 3, \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_EMIT_SKIP_WARN, \
+ UACPI_PARSE_OP_END, \
+ UACPI_PARSE_OP_ITEM_POP, \
+ UACPI_PARSE_OP_ITEM_POP, \
+ UACPI_PARSE_OP_PKGLEN, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_END, \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ } \
+) \
+UACPI_OP( \
+ WhileOp, 0xA2, 0, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 1, \
+ UACPI_PARSE_OP_IF_LAST_TRUE, 1, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ NoopOp, 0xA3, 0, \
+ { \
+ UACPI_PARSE_OP_END, \
+ } \
+) \
+UACPI_OP( \
+ ReturnOp, 0xA4, 0, \
+ { \
+ UACPI_PARSE_OP_TERM_ARG_UNWRAP_INTERNAL, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ BreakOp, 0xA5, 0, \
+ { \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_BAD_OPCODE(0xA6) \
+UACPI_BAD_OPCODE(0xA7) \
+UACPI_BAD_OPCODE(0xA8) \
+UACPI_BAD_OPCODE(0xA9) \
+UACPI_BAD_OPCODE(0xAA) \
+UACPI_BAD_OPCODE(0xAB) \
+UACPI_BAD_OPCODE(0xAC) \
+UACPI_BAD_OPCODE(0xAD) \
+UACPI_BAD_OPCODE(0xAE) \
+UACPI_BAD_OPCODE(0xAF) \
+UACPI_BAD_OPCODE(0xB0) \
+UACPI_BAD_OPCODE(0xB1) \
+UACPI_BAD_OPCODE(0xB2) \
+UACPI_BAD_OPCODE(0xB3) \
+UACPI_BAD_OPCODE(0xB4) \
+UACPI_BAD_OPCODE(0xB5) \
+UACPI_BAD_OPCODE(0xB6) \
+UACPI_BAD_OPCODE(0xB7) \
+UACPI_BAD_OPCODE(0xB8) \
+UACPI_BAD_OPCODE(0xB9) \
+UACPI_BAD_OPCODE(0xBA) \
+UACPI_BAD_OPCODE(0xBB) \
+UACPI_BAD_OPCODE(0xBC) \
+UACPI_BAD_OPCODE(0xBD) \
+UACPI_BAD_OPCODE(0xBE) \
+UACPI_BAD_OPCODE(0xBF) \
+UACPI_BAD_OPCODE(0xC0) \
+UACPI_BAD_OPCODE(0xC1) \
+UACPI_BAD_OPCODE(0xC2) \
+UACPI_BAD_OPCODE(0xC3) \
+UACPI_BAD_OPCODE(0xC4) \
+UACPI_BAD_OPCODE(0xC5) \
+UACPI_BAD_OPCODE(0xC6) \
+UACPI_BAD_OPCODE(0xC7) \
+UACPI_BAD_OPCODE(0xC8) \
+UACPI_BAD_OPCODE(0xC9) \
+UACPI_BAD_OPCODE(0xCA) \
+UACPI_BAD_OPCODE(0xCB) \
+UACPI_OP( \
+ BreakPointOp, 0xCC, 0, \
+ { \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_BAD_OPCODE(0xCD) \
+UACPI_BAD_OPCODE(0xCE) \
+UACPI_BAD_OPCODE(0xCF) \
+UACPI_BAD_OPCODE(0xD0) \
+UACPI_BAD_OPCODE(0xD1) \
+UACPI_BAD_OPCODE(0xD2) \
+UACPI_BAD_OPCODE(0xD3) \
+UACPI_BAD_OPCODE(0xD4) \
+UACPI_BAD_OPCODE(0xD5) \
+UACPI_BAD_OPCODE(0xD6) \
+UACPI_BAD_OPCODE(0xD7) \
+UACPI_BAD_OPCODE(0xD8) \
+UACPI_BAD_OPCODE(0xD9) \
+UACPI_BAD_OPCODE(0xDA) \
+UACPI_BAD_OPCODE(0xDB) \
+UACPI_BAD_OPCODE(0xDC) \
+UACPI_BAD_OPCODE(0xDD) \
+UACPI_BAD_OPCODE(0xDE) \
+UACPI_BAD_OPCODE(0xDF) \
+UACPI_BAD_OPCODE(0xE0) \
+UACPI_BAD_OPCODE(0xE1) \
+UACPI_BAD_OPCODE(0xE2) \
+UACPI_BAD_OPCODE(0xE3) \
+UACPI_BAD_OPCODE(0xE4) \
+UACPI_BAD_OPCODE(0xE5) \
+UACPI_BAD_OPCODE(0xE6) \
+UACPI_BAD_OPCODE(0xE7) \
+UACPI_BAD_OPCODE(0xE8) \
+UACPI_BAD_OPCODE(0xE9) \
+UACPI_BAD_OPCODE(0xEA) \
+UACPI_BAD_OPCODE(0xEB) \
+UACPI_BAD_OPCODE(0xEC) \
+UACPI_BAD_OPCODE(0xED) \
+UACPI_BAD_OPCODE(0xEE) \
+UACPI_BAD_OPCODE(0xEF) \
+UACPI_BAD_OPCODE(0xF0) \
+UACPI_BAD_OPCODE(0xF1) \
+UACPI_BAD_OPCODE(0xF2) \
+UACPI_BAD_OPCODE(0xF3) \
+UACPI_OP( \
+ InternalOpReadFieldAsBuffer, 0xF4, \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_RESERVED, \
+ { \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_BUFFER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ InternalOpReadFieldAsInteger, 0xF5, \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_RESERVED, \
+ { \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ InternalOpNamedObject, 0xF6, \
+ UACPI_OP_PROPERTY_SIMPLE_NAME | \
+ UACPI_OP_PROPERTY_SUPERNAME | \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_RESERVED, \
+ { \
+ UACPI_PARSE_OP_EMPTY_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_METHOD_CALL_OPCODE(0) \
+UACPI_METHOD_CALL_OPCODE(1) \
+UACPI_METHOD_CALL_OPCODE(2) \
+UACPI_METHOD_CALL_OPCODE(3) \
+UACPI_METHOD_CALL_OPCODE(4) \
+UACPI_METHOD_CALL_OPCODE(5) \
+UACPI_METHOD_CALL_OPCODE(6) \
+UACPI_METHOD_CALL_OPCODE(7) \
+UACPI_OP( \
+ OnesOp, 0xFF, \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT, \
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+ UACPI_PARSE_OP_TRUNCATE_NUMBER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+)
+
+extern uacpi_u8 uacpi_field_op_decode_ops[];
+extern uacpi_u8 uacpi_index_field_op_decode_ops[];
+extern uacpi_u8 uacpi_bank_field_op_decode_ops[];
+extern uacpi_u8 uacpi_load_op_decode_ops[];
+extern uacpi_u8 uacpi_load_table_op_decode_ops[];
+
+#define UACPI_BUILD_NAMED_SCOPE_OBJECT_OP(name, code, type, ...) \
+UACPI_OP( \
+ name##Op, UACPI_EXT_OP(code), 0, \
+ { \
+ UACPI_PARSE_OP_TRACKED_PKGLEN, \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ ##__VA_ARGS__, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 1, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, type, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 1, \
+ } \
+)
+
+#define UACPI_BUILD_TO_FROM_BCD(type, code) \
+UACPI_OP( \
+ type##BCDOp, UACPI_EXT_OP(code), \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 1, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+)
+
+#define UACPI_ENUMERATE_EXT_OPCODES \
+UACPI_OP( \
+ ReservedExtOp, UACPI_EXT_OP(0x00), 0, \
+ { \
+ UACPI_PARSE_OP_BAD_OPCODE, \
+ } \
+) \
+UACPI_OP( \
+ MutexOp, UACPI_EXT_OP(0x01), 0, \
+ { \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_MUTEX, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 0, \
+ } \
+) \
+UACPI_OP( \
+ EventOp, UACPI_EXT_OP(0x02), 0, \
+ { \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_EVENT, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 0, \
+ } \
+) \
+UACPI_OP( \
+ CondRefOfOp, UACPI_EXT_OP(0x12), \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME_OR_UNRESOLVED, \
+ UACPI_PARSE_OP_TARGET, \
+ UACPI_PARSE_OP_IF_NULL, 0, 3, \
+ UACPI_PARSE_OP_LOAD_FALSE_OBJECT, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ UACPI_PARSE_OP_END, \
+ UACPI_PARSE_OP_OBJECT_ALLOC, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_STORE_TO_TARGET, 1, \
+ UACPI_PARSE_OP_LOAD_TRUE_OBJECT, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_DO_BUILD_BUFFER_FIELD_OP( \
+ Create, UACPI_EXT_OP(0x13), 3, \
+ UACPI_PARSE_OP_OPERAND \
+) \
+UACPI_OUT_OF_LINE_OP( \
+ LoadTableOp, UACPI_EXT_OP(0x1F), \
+ uacpi_load_table_op_decode_ops, \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_OUT_OF_LINE \
+) \
+UACPI_OUT_OF_LINE_OP( \
+ LoadOp, UACPI_EXT_OP(0x20), \
+ uacpi_load_op_decode_ops, \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_OUT_OF_LINE \
+) \
+UACPI_OP( \
+ StallOp, UACPI_EXT_OP(0x21), 0, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ SleepOp, UACPI_EXT_OP(0x22), 0, \
+ { \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ AcquireOp, UACPI_EXT_OP(0x23), \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_LOAD_IMM, 2, \
+ UACPI_PARSE_OP_LOAD_TRUE_OBJECT, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ SignalOp, UACPI_EXT_OP(0x24), 0, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ WaitOp, UACPI_EXT_OP(0x25), \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_LOAD_TRUE_OBJECT, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ ResetOp, UACPI_EXT_OP(0x26), 0, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ ReleaseOp, UACPI_EXT_OP(0x27), 0, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_BUILD_TO_FROM_BCD(From, 0x28) \
+UACPI_BUILD_TO_FROM_BCD(To, 0x29) \
+UACPI_OP( \
+ UnloadOp, UACPI_EXT_OP(0x2A), 0, \
+ { \
+ UACPI_PARSE_OP_SUPERNAME, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ RevisionOp, UACPI_EXT_OP(0x30), \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_LOAD_INLINE_IMM_AS_OBJECT, \
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ DebugOp, UACPI_EXT_OP(0x31), \
+ UACPI_OP_PROPERTY_TERM_ARG | \
+ UACPI_OP_PROPERTY_SUPERNAME | \
+ UACPI_OP_PROPERTY_TARGET, \
+ { \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_DEBUG, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ FatalOp, UACPI_EXT_OP(0x32), 0, \
+ { \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_LOAD_IMM, 4, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ } \
+) \
+UACPI_OP( \
+ TimerOp, UACPI_EXT_OP(0x33), \
+ UACPI_OP_PROPERTY_TERM_ARG, \
+ { \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_INTEGER, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_OBJECT_TRANSFER_TO_PREV, \
+ } \
+) \
+UACPI_OP( \
+ OpRegionOp, UACPI_EXT_OP(0x80), 0, \
+ { \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_OPERAND, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_OPERATION_REGION, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 0, \
+ } \
+) \
+UACPI_OUT_OF_LINE_OP( \
+ FieldOp, UACPI_EXT_OP(0x81), \
+ uacpi_field_op_decode_ops, \
+ UACPI_OP_PROPERTY_OUT_OF_LINE \
+) \
+UACPI_BUILD_NAMED_SCOPE_OBJECT_OP( \
+ Device, 0x82, UACPI_OBJECT_DEVICE \
+) \
+UACPI_BUILD_NAMED_SCOPE_OBJECT_OP( \
+ Processor, 0x83, UACPI_OBJECT_PROCESSOR, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_LOAD_IMM, 4, \
+ UACPI_PARSE_OP_LOAD_IMM, 1 \
+) \
+UACPI_BUILD_NAMED_SCOPE_OBJECT_OP( \
+ PowerRes, 0x84, UACPI_OBJECT_POWER_RESOURCE, \
+ UACPI_PARSE_OP_LOAD_IMM, 1, \
+ UACPI_PARSE_OP_LOAD_IMM, 2 \
+) \
+UACPI_BUILD_NAMED_SCOPE_OBJECT_OP( \
+ ThermalZone, 0x85, UACPI_OBJECT_THERMAL_ZONE \
+) \
+UACPI_OUT_OF_LINE_OP( \
+ IndexFieldOp, UACPI_EXT_OP(0x86), \
+ uacpi_index_field_op_decode_ops, \
+ UACPI_OP_PROPERTY_OUT_OF_LINE \
+) \
+UACPI_OUT_OF_LINE_OP( \
+ BankFieldOp, UACPI_EXT_OP(0x87), \
+ uacpi_bank_field_op_decode_ops, \
+ UACPI_OP_PROPERTY_OUT_OF_LINE \
+) \
+UACPI_OP( \
+ DataRegionOp, UACPI_EXT_OP(0x88), 0, \
+ { \
+ UACPI_PARSE_OP_CREATE_NAMESTRING_OR_NULL_IF_LOAD, \
+ UACPI_PARSE_OP_STRING, \
+ UACPI_PARSE_OP_STRING, \
+ UACPI_PARSE_OP_STRING, \
+ UACPI_PARSE_OP_SKIP_WITH_WARN_IF_NULL, 0, \
+ UACPI_PARSE_OP_OBJECT_ALLOC_TYPED, \
+ UACPI_OBJECT_OPERATION_REGION, \
+ UACPI_PARSE_OP_INVOKE_HANDLER, \
+ UACPI_PARSE_OP_INSTALL_NAMESPACE_NODE, 0, \
+ } \
+)
+
+enum uacpi_aml_op {
+#define UACPI_OP(name, code, ...) UACPI_AML_OP_##name = code,
+#define UACPI_OUT_OF_LINE_OP(name, code, ...) UACPI_AML_OP_##name = code,
+ UACPI_ENUMERATE_OPCODES
+ UACPI_ENUMERATE_EXT_OPCODES
+#undef UACPI_OP
+#undef UACPI_OUT_OF_LINE_OP
+};
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/opregion.h b/sys/include/dev/acpi/uacpi/uacpi/internal/opregion.h
new file mode 100644
index 0000000..a1173f4
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/opregion.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <uacpi/internal/types.h>
+#include <uacpi/opregion.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+uacpi_status uacpi_initialize_opregion(void);
+void uacpi_deinitialize_opregion(void);
+
+void uacpi_trace_region_error(
+ uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret
+);
+
+uacpi_status uacpi_install_address_space_handler_with_flags(
+ uacpi_namespace_node *device_node, enum uacpi_address_space space,
+ uacpi_region_handler handler, uacpi_handle handler_context,
+ uacpi_u16 flags
+);
+
+void uacpi_opregion_uninstall_handler(uacpi_namespace_node *node);
+
+uacpi_bool uacpi_address_space_handler_is_default(
+ uacpi_address_space_handler *handler
+);
+
+uacpi_address_space_handlers *uacpi_node_get_address_space_handlers(
+ uacpi_namespace_node *node
+);
+
+uacpi_status uacpi_initialize_opregion_node(uacpi_namespace_node *node);
+
+uacpi_status uacpi_opregion_attach(uacpi_namespace_node *node);
+
+void uacpi_install_default_address_space_handlers(void);
+
+uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space);
+
+union uacpi_opregion_io_data {
+ uacpi_u64 *integer;
+ uacpi_data_view buffer;
+};
+
+uacpi_status uacpi_dispatch_opregion_io(
+ uacpi_field_unit *field, uacpi_u32 offset,
+ uacpi_region_op op, union uacpi_opregion_io_data data
+);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/osi.h b/sys/include/dev/acpi/uacpi/uacpi/internal/osi.h
new file mode 100644
index 0000000..6d7b0db
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/osi.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <uacpi/osi.h>
+
+uacpi_status uacpi_initialize_interfaces(void);
+void uacpi_deinitialize_interfaces(void);
+
+uacpi_status uacpi_handle_osi(const uacpi_char *string, uacpi_bool *out_value);
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/registers.h b/sys/include/dev/acpi/uacpi/uacpi/internal/registers.h
new file mode 100644
index 0000000..84694ac
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/registers.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/registers.h>
+
+uacpi_status uacpi_initialize_registers(void);
+void uacpi_deinitialize_registers(void);
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/resources.h b/sys/include/dev/acpi/uacpi/uacpi/internal/resources.h
new file mode 100644
index 0000000..4c4a1ff
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/resources.h
@@ -0,0 +1,327 @@
+#pragma once
+
+#include <uacpi/internal/types.h>
+#include <uacpi/resources.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+enum uacpi_aml_resource {
+ UACPI_AML_RESOURCE_TYPE_INVALID = 0,
+
+ // Small resources
+ UACPI_AML_RESOURCE_IRQ,
+ UACPI_AML_RESOURCE_DMA,
+ UACPI_AML_RESOURCE_START_DEPENDENT,
+ UACPI_AML_RESOURCE_END_DEPENDENT,
+ UACPI_AML_RESOURCE_IO,
+ UACPI_AML_RESOURCE_FIXED_IO,
+ UACPI_AML_RESOURCE_FIXED_DMA,
+ UACPI_AML_RESOURCE_VENDOR_TYPE0,
+ UACPI_AML_RESOURCE_END_TAG,
+
+ // Large resources
+ UACPI_AML_RESOURCE_MEMORY24,
+ UACPI_AML_RESOURCE_GENERIC_REGISTER,
+ UACPI_AML_RESOURCE_VENDOR_TYPE1,
+ UACPI_AML_RESOURCE_MEMORY32,
+ UACPI_AML_RESOURCE_FIXED_MEMORY32,
+ UACPI_AML_RESOURCE_ADDRESS32,
+ UACPI_AML_RESOURCE_ADDRESS16,
+ UACPI_AML_RESOURCE_EXTENDED_IRQ,
+ UACPI_AML_RESOURCE_ADDRESS64,
+ UACPI_AML_RESOURCE_ADDRESS64_EXTENDED,
+ UACPI_AML_RESOURCE_GPIO_CONNECTION,
+ UACPI_AML_RESOURCE_PIN_FUNCTION,
+ UACPI_AML_RESOURCE_SERIAL_CONNECTION,
+ UACPI_AML_RESOURCE_PIN_CONFIGURATION,
+ UACPI_AML_RESOURCE_PIN_GROUP,
+ UACPI_AML_RESOURCE_PIN_GROUP_FUNCTION,
+ UACPI_AML_RESOURCE_PIN_GROUP_CONFIGURATION,
+ UACPI_AML_RESOURCE_CLOCK_INPUT,
+ UACPI_AML_RESOURCE_MAX = UACPI_AML_RESOURCE_CLOCK_INPUT,
+};
+
+enum uacpi_aml_resource_size_kind {
+ UACPI_AML_RESOURCE_SIZE_KIND_FIXED,
+ UACPI_AML_RESOURCE_SIZE_KIND_FIXED_OR_ONE_LESS,
+ UACPI_AML_RESOURCE_SIZE_KIND_VARIABLE,
+};
+
+enum uacpi_aml_resource_kind {
+ UACPI_AML_RESOURCE_KIND_SMALL = 0,
+ UACPI_AML_RESOURCE_KIND_LARGE,
+};
+
+enum uacpi_resource_convert_opcode {
+ UACPI_RESOURCE_CONVERT_OPCODE_END = 0,
+
+ /*
+ * AML -> native:
+ * Take the mask at 'aml_offset' and convert to an array of uacpi_u8
+ * at 'native_offset' with the value corresponding to the bit index.
+ * The array size is written to the byte at offset 'arg2'.
+ *
+ * native -> AML:
+ * Walk each element of the array at 'native_offset' and set the
+ * corresponding bit in the mask at 'aml_offset' to 1. The array size is
+ * read from the byte at offset 'arg2'.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_PACKED_ARRAY_8,
+ UACPI_RESOURCE_CONVERT_OPCODE_PACKED_ARRAY_16,
+
+ /*
+ * AML -> native:
+ * Grab the bits at the byte at 'aml_offset' + 'bit_index', and copy its
+ * value into the byte at 'native_offset'.
+ *
+ * native -> AML:
+ * Grab first N bits at 'native_offset' and copy to 'aml_offset' starting
+ * at the 'bit_index'.
+ *
+ * NOTE:
+ * These must be contiguous in this order.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_1,
+ UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_2,
+ UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_3,
+ UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_6 =
+ UACPI_RESOURCE_CONVERT_OPCODE_BIT_FIELD_3 + 3,
+
+ /*
+ * AML -> native:
+ * Copy N bytes at 'aml_offset' to 'native_offset'.
+ *
+ * native -> AML:
+ * Copy N bytes at 'native_offset' to 'aml_offset'.
+ *
+ * 'imm' is added to the accumulator.
+ *
+ * NOTE: These are affected by the current value in the accumulator. If it's
+ * set to 0 at the time of evalution, this is executed once, N times
+ * otherwise. 0xFF is considered a special value, which resets the
+ * accumulator to 0 unconditionally.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_FIELD_8,
+ UACPI_RESOURCE_CONVERT_OPCODE_FIELD_16,
+ UACPI_RESOURCE_CONVERT_OPCODE_FIELD_32,
+ UACPI_RESOURCE_CONVERT_OPCODE_FIELD_64,
+
+ /*
+ * If the length of the current resource is less than 'arg0', then skip
+ * 'imm' instructions.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_SKIP_IF_AML_SIZE_LESS_THAN,
+
+ /*
+ * Skip 'imm' instructions if 'arg0' is not equal to the value in the
+ * accumulator.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_SKIP_IF_NOT_EQUALS,
+
+ /*
+ * AML -> native:
+ * Set the byte at 'native_offset' to 'imm'.
+ *
+ * native -> AML:
+ * Set the byte at 'aml_offset' to 'imm'.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_SET_TO_IMM,
+
+ /*
+ * AML -> native:
+ * Load the AML resoruce length into the accumulator as well as the field at
+ * 'native_offset' of width N.
+ *
+ * native -> AML:
+ * Load the resource length into the accumulator.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_LOAD_AML_SIZE_32,
+
+ /*
+ * AML -> native:
+ * Load the 8 bit field at 'aml_offset' into the accumulator and store at
+ * 'native_offset'.
+ *
+ * native -> AML:
+ * Load the 8 bit field at 'native_offset' into the accumulator and store
+ * at 'aml_offset'.
+ *
+ * The accumulator is multiplied by 'imm' unless it's set to zero.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_LOAD_8_STORE,
+
+ /*
+ * Load the N bit field at 'native_offset' into the accumulator
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_LOAD_8_NATIVE,
+ UACPI_RESOURCE_CONVERT_OPCODE_LOAD_16_NATIVE,
+
+ /*
+ * Load 'imm' into the accumulator.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_LOAD_IMM,
+
+ /*
+ * AML -> native:
+ * Load the resource source at offset = aml size + accumulator into the
+ * uacpi_resource_source struct at 'native_offset'. The string bytes are
+ * written to the offset at resource size + accumulator. The presence is
+ * detected by comparing the length of the resource to the offset,
+ * 'arg2' optionally specifies the offset to the upper bound of the string.
+ *
+ * native -> AML:
+ * Load the resource source from the uacpi_resource_source struct at
+ * 'native_offset' to aml_size + accumulator. aml_size + accumulator is
+ * optionally written to 'aml_offset' if it's specified.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_SOURCE,
+ UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_SOURCE_NO_INDEX,
+ UACPI_RESOURCE_CONVERT_OPCODE_RESOURCE_LABEL,
+
+ /*
+ * AML -> native:
+ * Load the pin table with upper bound specified at 'aml_offset'.
+ * The table length is calculated by subtracting the upper bound from
+ * aml_size and is written into the accumulator.
+ *
+ * native -> AML:
+ * Load the pin table length from 'native_offset' and multiply by 2, store
+ * the result in the accumulator.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_LOAD_PIN_TABLE_LENGTH,
+
+ /*
+ * AML -> native:
+ * Store the accumulator divided by 2 at 'native_offset'.
+ * The table is copied to the offset at resource size from offset at
+ * aml_size with the pointer written to the offset at 'arg2'.
+ *
+ * native -> AML:
+ * Read the pin table from resource size offset, write aml_size to
+ * 'aml_offset'. Copy accumulator bytes to the offset at aml_size.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_PIN_TABLE,
+
+ /*
+ * AML -> native:
+ * Load vendor data with offset stored at 'aml_offset'. The length is
+ * calculated as aml_size - aml_offset and is written to 'native_offset'.
+ * The data is written to offset - aml_size with the pointer written back
+ * to the offset at 'arg2'.
+ *
+ * native -> AML:
+ * Read vendor data from the pointer at offset 'arg2' and size at
+ * 'native_offset', the offset to write to is calculated as the difference
+ * between the data pointer and the native resource end pointer.
+ * offset + aml_size is written to 'aml_offset' and the data is copied
+ * there as well.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_VENDOR_DATA,
+
+ /*
+ * AML -> native:
+ * Read the serial type from the byte at 'aml_offset' and write it to the
+ * type field of the uacpi_resource_serial_bus_common structure. Convert
+ * the serial type to native and set the resource type to it. Copy the
+ * vendor data to the offset at native size, the length is calculated
+ * as type_data_length - extra-type-specific-size, and is written to
+ * vendor_data_length, as well as the accumulator. The data pointer is
+ * written to vendor_data.
+ *
+ * native -> AML:
+ * Set the serial type at 'aml_offset' to the value stored at
+ * 'native_offset'. Load the vendor data to the offset at aml_size,
+ * the length is read from 'vendor_data_length', and the data is copied from
+ * 'vendor_data'.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_SERIAL_TYPE_SPECIFIC,
+
+ /*
+ * Produces an error if encountered in the instruction stream.
+ * Used to trap invalid/unexpected code flow.
+ */
+ UACPI_RESOURCE_CONVERT_OPCODE_UNREACHABLE,
+};
+
+struct uacpi_resource_convert_instruction {
+ uacpi_u8 code;
+
+ union {
+ uacpi_u8 aml_offset;
+ uacpi_u8 arg0;
+ } f1;
+
+ union {
+ uacpi_u8 native_offset;
+ uacpi_u8 arg1;
+ } f2;
+
+ union {
+ uacpi_u8 imm;
+ uacpi_u8 bit_index;
+ uacpi_u8 arg2;
+ } f3;
+};
+
+struct uacpi_resource_spec {
+ uacpi_u8 type : 5;
+ uacpi_u8 native_type : 5;
+ uacpi_u8 resource_kind : 1;
+ uacpi_u8 size_kind : 2;
+
+ /*
+ * Size of the resource as appears in the AML byte stream, for variable
+ * length resources this is the minimum.
+ */
+ uacpi_u16 aml_size;
+
+ /*
+ * Size of the native human-readable uacpi resource, for variable length
+ * resources this is the minimum. The final length is this field plus the
+ * result of extra_size_for_native().
+ */
+ uacpi_u16 native_size;
+
+ /*
+ * Calculate the amount of extra bytes that must be allocated for a specific
+ * native resource given the AML counterpart. This being NULL means no extra
+ * bytes are needed, aka native resources is always the same size.
+ */
+ uacpi_size (*extra_size_for_native)(
+ const struct uacpi_resource_spec*, void*, uacpi_size
+ );
+
+ /*
+ * Calculate the number of bytes needed to represent a native resource as
+ * AML. The 'aml_size' field is used if this is NULL.
+ */
+ uacpi_size (*size_for_aml)(
+ const struct uacpi_resource_spec*, uacpi_resource*
+ );
+
+ const struct uacpi_resource_convert_instruction *to_native;
+ const struct uacpi_resource_convert_instruction *to_aml;
+};
+
+typedef uacpi_iteration_decision (*uacpi_aml_resource_iteration_callback)(
+ void*, uacpi_u8 *data, uacpi_u16 resource_size,
+ const struct uacpi_resource_spec*
+);
+
+uacpi_status uacpi_for_each_aml_resource(
+ uacpi_data_view, uacpi_aml_resource_iteration_callback cb, void *user
+);
+
+uacpi_status uacpi_find_aml_resource_end_tag(
+ uacpi_data_view, uacpi_size *out_offset
+);
+
+uacpi_status uacpi_native_resources_from_aml(
+ uacpi_data_view, uacpi_resources **out_resources
+);
+
+uacpi_status uacpi_native_resources_to_aml(
+ uacpi_resources *resources, uacpi_object **out_template
+);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/shareable.h b/sys/include/dev/acpi/uacpi/uacpi/internal/shareable.h
new file mode 100644
index 0000000..e00d850
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/shareable.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <uacpi/types.h>
+
+struct uacpi_shareable {
+ uacpi_u32 reference_count;
+};
+
+void uacpi_shareable_init(uacpi_handle);
+
+uacpi_bool uacpi_bugged_shareable(uacpi_handle);
+void uacpi_make_shareable_bugged(uacpi_handle);
+
+uacpi_u32 uacpi_shareable_ref(uacpi_handle);
+uacpi_u32 uacpi_shareable_unref(uacpi_handle);
+
+void uacpi_shareable_unref_and_delete_if_last(
+ uacpi_handle, void (*do_free)(uacpi_handle)
+);
+
+uacpi_u32 uacpi_shareable_refcount(uacpi_handle);
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/stdlib.h b/sys/include/dev/acpi/uacpi/uacpi/internal/stdlib.h
new file mode 100644
index 0000000..853c1bc
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/stdlib.h
@@ -0,0 +1,131 @@
+#pragma once
+
+#include <uacpi/internal/types.h>
+#include <uacpi/internal/helpers.h>
+#include <uacpi/platform/libc.h>
+#include <uacpi/platform/config.h>
+#include <uacpi/kernel_api.h>
+
+#define offsetof(st, m) \
+ ((size_t)&(((st *)0)->m))
+
+#ifdef UACPI_USE_BUILTIN_STRING
+
+#ifndef uacpi_memcpy
+void *uacpi_memcpy(void *dest, const void *src, uacpi_size count);
+#endif
+
+#ifndef uacpi_memmove
+void *uacpi_memmove(void *dest, const void *src, uacpi_size count);
+#endif
+
+#ifndef uacpi_memset
+void *uacpi_memset(void *dest, uacpi_i32 ch, uacpi_size count);
+#endif
+
+#ifndef uacpi_memcmp
+uacpi_i32 uacpi_memcmp(const void *lhs, const void *rhs, uacpi_size count);
+#endif
+
+#else
+
+#ifndef uacpi_memcpy
+ #ifdef UACPI_COMPILER_HAS_BUILTIN_MEMCPY
+ #define uacpi_memcpy __builtin_memcpy
+ #else
+ extern void *memcpy(void *dest, const void *src, uacpi_size count);
+ #define uacpi_memcpy memcpy
+ #endif
+#endif
+
+#ifndef uacpi_memmove
+ #ifdef UACPI_COMPILER_HAS_BUILTIN_MEMMOVE
+ #define uacpi_memmove __builtin_memmove
+ #else
+ extern void *memmove(void *dest, const void *src, uacpi_size count);
+ #define uacpi_memmove memmove
+ #endif
+#endif
+
+#ifndef uacpi_memset
+ #ifdef UACPI_COMPILER_HAS_BUILTIN_MEMSET
+ #define uacpi_memset __builtin_memset
+ #else
+ extern void *memset(void *dest, int ch, uacpi_size count);
+ #define uacpi_memset memset
+ #endif
+#endif
+
+#ifndef uacpi_memcmp
+ #ifdef UACPI_COMPILER_HAS_BUILTIN_MEMCMP
+ #define uacpi_memcmp __builtin_memcmp
+ #else
+ extern int memcmp(const void *lhs, const void *rhs, uacpi_size count);
+ #define uacpi_memcmp memcmp
+ #endif
+#endif
+
+#endif
+
+#ifndef uacpi_strlen
+uacpi_size uacpi_strlen(const uacpi_char *str);
+#endif
+
+#ifndef uacpi_strnlen
+uacpi_size uacpi_strnlen(const uacpi_char *str, uacpi_size max);
+#endif
+
+#ifndef uacpi_strcmp
+uacpi_i32 uacpi_strcmp(const uacpi_char *lhs, const uacpi_char *rhs);
+#endif
+
+#ifndef uacpi_snprintf
+UACPI_PRINTF_DECL(3, 4)
+uacpi_i32 uacpi_snprintf(
+ uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt, ...
+);
+#endif
+
+#ifndef uacpi_vsnprintf
+uacpi_i32 uacpi_vsnprintf(
+ uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt,
+ uacpi_va_list vlist
+);
+#endif
+
+#ifdef UACPI_SIZED_FREES
+#define uacpi_free(mem, size) uacpi_kernel_free(mem, size)
+#else
+#define uacpi_free(mem, _) uacpi_kernel_free(mem)
+#endif
+
+#define uacpi_memzero(ptr, size) uacpi_memset(ptr, 0, size)
+
+#define UACPI_COMPARE(x, y, op) ((x) op (y) ? (x) : (y))
+#define UACPI_MIN(x, y) UACPI_COMPARE(x, y, <)
+#define UACPI_MAX(x, y) UACPI_COMPARE(x, y, >)
+
+#define UACPI_ALIGN_UP_MASK(x, mask) (((x) + (mask)) & ~(mask))
+#define UACPI_ALIGN_UP(x, val, type) UACPI_ALIGN_UP_MASK(x, (type)(val) - 1)
+
+#define UACPI_ALIGN_DOWN_MASK(x, mask) ((x) & ~(mask))
+#define UACPI_ALIGN_DOWN(x, val, type) UACPI_ALIGN_DOWN_MASK(x, (type)(val) - 1)
+
+#define UACPI_IS_ALIGNED_MASK(x, mask) (((x) & (mask)) == 0)
+#define UACPI_IS_ALIGNED(x, val, type) UACPI_IS_ALIGNED_MASK(x, (type)(val) - 1)
+
+#define UACPI_IS_POWER_OF_TWO(x, type) UACPI_IS_ALIGNED(x, x, type)
+
+void uacpi_memcpy_zerout(void *dst, const void *src,
+ uacpi_size dst_size, uacpi_size src_size);
+
+// Returns the one-based bit location of LSb or 0
+uacpi_u8 uacpi_bit_scan_forward(uacpi_u64);
+
+// Returns the one-based bit location of MSb or 0
+uacpi_u8 uacpi_bit_scan_backward(uacpi_u64);
+
+#ifndef UACPI_NATIVE_ALLOC_ZEROED
+void *uacpi_builtin_alloc_zeroed(uacpi_size size);
+#define uacpi_kernel_alloc_zeroed uacpi_builtin_alloc_zeroed
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/tables.h b/sys/include/dev/acpi/uacpi/uacpi/internal/tables.h
new file mode 100644
index 0000000..8a5345f
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/tables.h
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <uacpi/internal/context.h>
+#include <uacpi/internal/interpreter.h>
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+#include <uacpi/tables.h>
+
+enum uacpi_table_origin {
+#ifndef UACPI_BAREBONES_MODE
+ UACPI_TABLE_ORIGIN_FIRMWARE_VIRTUAL = 0,
+#endif
+ UACPI_TABLE_ORIGIN_FIRMWARE_PHYSICAL = 1,
+
+ UACPI_TABLE_ORIGIN_HOST_VIRTUAL,
+ UACPI_TABLE_ORIGIN_HOST_PHYSICAL,
+};
+
+struct uacpi_installed_table {
+ uacpi_phys_addr phys_addr;
+ struct acpi_sdt_hdr hdr;
+ void *ptr;
+
+ uacpi_u16 reference_count;
+
+#define UACPI_TABLE_LOADED (1 << 0)
+#define UACPI_TABLE_CSUM_VERIFIED (1 << 1)
+#define UACPI_TABLE_INVALID (1 << 2)
+ uacpi_u8 flags;
+ uacpi_u8 origin;
+};
+
+uacpi_status uacpi_initialize_tables(void);
+void uacpi_deinitialize_tables(void);
+
+uacpi_bool uacpi_signatures_match(const void *const lhs, const void *const rhs);
+uacpi_status uacpi_check_table_signature(void *table, const uacpi_char *expect);
+uacpi_status uacpi_verify_table_checksum(void *table, uacpi_size size);
+
+uacpi_status uacpi_table_install_physical_with_origin(
+ uacpi_phys_addr phys, enum uacpi_table_origin origin, uacpi_table *out_table
+);
+uacpi_status uacpi_table_install_with_origin(
+ void *virt, enum uacpi_table_origin origin, uacpi_table *out_table
+);
+
+#ifndef UACPI_BAREBONES_MODE
+void uacpi_table_mark_as_loaded(uacpi_size idx);
+
+uacpi_status uacpi_table_load_with_cause(
+ uacpi_size idx, enum uacpi_table_load_cause cause
+);
+#endif // !UACPI_BAREBONES_MODE
+
+typedef uacpi_iteration_decision (*uacpi_table_iteration_callback)
+ (void *user, struct uacpi_installed_table *tbl, uacpi_size idx);
+
+uacpi_status uacpi_for_each_table(
+ uacpi_size base_idx, uacpi_table_iteration_callback, void *user
+);
+
+typedef uacpi_bool (*uacpi_table_match_callback)
+ (struct uacpi_installed_table *tbl);
+
+uacpi_status uacpi_table_match(
+ uacpi_size base_idx, uacpi_table_match_callback, uacpi_table *out_table
+);
+
+#define UACPI_PRI_TBL_HDR "'%.4s' (OEM ID '%.6s' OEM Table ID '%.8s')"
+#define UACPI_FMT_TBL_HDR(hdr) (hdr)->signature, (hdr)->oemid, (hdr)->oem_table_id
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/types.h b/sys/include/dev/acpi/uacpi/uacpi/internal/types.h
new file mode 100644
index 0000000..b994a27
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/types.h
@@ -0,0 +1,310 @@
+#pragma once
+
+#include <uacpi/status.h>
+#include <uacpi/types.h>
+#include <uacpi/internal/shareable.h>
+
+#ifndef UACPI_BAREBONES_MODE
+
+// object->flags field if object->type == UACPI_OBJECT_REFERENCE
+enum uacpi_reference_kind {
+ UACPI_REFERENCE_KIND_REFOF = 0,
+ UACPI_REFERENCE_KIND_LOCAL = 1,
+ UACPI_REFERENCE_KIND_ARG = 2,
+ UACPI_REFERENCE_KIND_NAMED = 3,
+ UACPI_REFERENCE_KIND_PKG_INDEX = 4,
+};
+
+// object->flags field if object->type == UACPI_OBJECT_STRING
+enum uacpi_string_kind {
+ UACPI_STRING_KIND_NORMAL = 0,
+ UACPI_STRING_KIND_PATH,
+};
+
+typedef struct uacpi_buffer {
+ struct uacpi_shareable shareable;
+ union {
+ void *data;
+ uacpi_u8 *byte_data;
+ uacpi_char *text;
+ };
+ uacpi_size size;
+} uacpi_buffer;
+
+typedef struct uacpi_package {
+ struct uacpi_shareable shareable;
+ uacpi_object **objects;
+ uacpi_size count;
+} uacpi_package;
+
+typedef struct uacpi_buffer_field {
+ uacpi_buffer *backing;
+ uacpi_size bit_index;
+ uacpi_u32 bit_length;
+ uacpi_bool force_buffer;
+} uacpi_buffer_field;
+
+typedef struct uacpi_buffer_index {
+ uacpi_size idx;
+ uacpi_buffer *buffer;
+} uacpi_buffer_index;
+
+typedef struct uacpi_mutex {
+ struct uacpi_shareable shareable;
+ uacpi_handle handle;
+ uacpi_thread_id owner;
+ uacpi_u16 depth;
+ uacpi_u8 sync_level;
+} uacpi_mutex;
+
+typedef struct uacpi_event {
+ struct uacpi_shareable shareable;
+ uacpi_handle handle;
+} uacpi_event;
+
+typedef struct uacpi_address_space_handler {
+ struct uacpi_shareable shareable;
+ uacpi_region_handler callback;
+ uacpi_handle user_context;
+ struct uacpi_address_space_handler *next;
+ struct uacpi_operation_region *regions;
+ uacpi_u16 space;
+
+#define UACPI_ADDRESS_SPACE_HANDLER_DEFAULT (1 << 0)
+ uacpi_u16 flags;
+} uacpi_address_space_handler;
+
+/*
+ * NOTE: These are common object headers.
+ * Any changes to these structs must be propagated to all objects.
+ * ==============================================================
+ * Common for the following objects:
+ * - UACPI_OBJECT_OPERATION_REGION
+ * - UACPI_OBJECT_PROCESSOR
+ * - UACPI_OBJECT_DEVICE
+ * - UACPI_OBJECT_THERMAL_ZONE
+ */
+typedef struct uacpi_address_space_handlers {
+ struct uacpi_shareable shareable;
+ uacpi_address_space_handler *head;
+} uacpi_address_space_handlers;
+
+typedef struct uacpi_device_notify_handler {
+ uacpi_notify_handler callback;
+ uacpi_handle user_context;
+ struct uacpi_device_notify_handler *next;
+} uacpi_device_notify_handler;
+
+/*
+ * Common for the following objects:
+ * - UACPI_OBJECT_PROCESSOR
+ * - UACPI_OBJECT_DEVICE
+ * - UACPI_OBJECT_THERMAL_ZONE
+ */
+typedef struct uacpi_handlers {
+ struct uacpi_shareable shareable;
+ uacpi_address_space_handler *address_space_head;
+ uacpi_device_notify_handler *notify_head;
+} uacpi_handlers;
+
+// This region has a corresponding _REG method that was succesfully executed
+#define UACPI_OP_REGION_STATE_REG_EXECUTED (1 << 0)
+
+// This region was successfully attached to a handler
+#define UACPI_OP_REGION_STATE_ATTACHED (1 << 1)
+
+typedef struct uacpi_operation_region {
+ struct uacpi_shareable shareable;
+ uacpi_address_space_handler *handler;
+ uacpi_handle user_context;
+ uacpi_u16 space;
+ uacpi_u8 state_flags;
+ uacpi_u64 offset;
+ uacpi_u64 length;
+
+ union {
+ // If space == TABLE_DATA
+ uacpi_u64 table_idx;
+
+ // If space == PCC
+ uacpi_u8 *internal_buffer;
+ };
+
+ // Used to link regions sharing the same handler
+ struct uacpi_operation_region *next;
+} uacpi_operation_region;
+
+typedef struct uacpi_device {
+ struct uacpi_shareable shareable;
+ uacpi_address_space_handler *address_space_handlers;
+ uacpi_device_notify_handler *notify_handlers;
+} uacpi_device;
+
+typedef struct uacpi_processor {
+ struct uacpi_shareable shareable;
+ uacpi_address_space_handler *address_space_handlers;
+ uacpi_device_notify_handler *notify_handlers;
+ uacpi_u8 id;
+ uacpi_u32 block_address;
+ uacpi_u8 block_length;
+} uacpi_processor;
+
+typedef struct uacpi_thermal_zone {
+ struct uacpi_shareable shareable;
+ uacpi_address_space_handler *address_space_handlers;
+ uacpi_device_notify_handler *notify_handlers;
+} uacpi_thermal_zone;
+
+typedef struct uacpi_power_resource {
+ uacpi_u8 system_level;
+ uacpi_u16 resource_order;
+} uacpi_power_resource;
+
+typedef uacpi_status (*uacpi_native_call_handler)(
+ uacpi_handle ctx, uacpi_object *retval
+);
+
+typedef struct uacpi_control_method {
+ struct uacpi_shareable shareable;
+ union {
+ uacpi_u8 *code;
+ uacpi_native_call_handler handler;
+ };
+ uacpi_mutex *mutex;
+ uacpi_u32 size;
+ uacpi_u8 sync_level : 4;
+ uacpi_u8 args : 3;
+ uacpi_u8 is_serialized : 1;
+ uacpi_u8 named_objects_persist: 1;
+ uacpi_u8 native_call : 1;
+ uacpi_u8 owns_code : 1;
+} uacpi_control_method;
+
+typedef enum uacpi_access_type {
+ UACPI_ACCESS_TYPE_ANY = 0,
+ UACPI_ACCESS_TYPE_BYTE = 1,
+ UACPI_ACCESS_TYPE_WORD = 2,
+ UACPI_ACCESS_TYPE_DWORD = 3,
+ UACPI_ACCESS_TYPE_QWORD = 4,
+ UACPI_ACCESS_TYPE_BUFFER = 5,
+} uacpi_access_type;
+
+typedef enum uacpi_lock_rule {
+ UACPI_LOCK_RULE_NO_LOCK = 0,
+ UACPI_LOCK_RULE_LOCK = 1,
+} uacpi_lock_rule;
+
+typedef enum uacpi_update_rule {
+ UACPI_UPDATE_RULE_PRESERVE = 0,
+ UACPI_UPDATE_RULE_WRITE_AS_ONES = 1,
+ UACPI_UPDATE_RULE_WRITE_AS_ZEROES = 2,
+} uacpi_update_rule;
+
+typedef enum uacpi_field_unit_kind {
+ UACPI_FIELD_UNIT_KIND_NORMAL = 0,
+ UACPI_FIELD_UNIT_KIND_INDEX = 1,
+ UACPI_FIELD_UNIT_KIND_BANK = 2,
+} uacpi_field_unit_kind;
+
+typedef struct uacpi_field_unit {
+ struct uacpi_shareable shareable;
+
+ union {
+ // UACPI_FIELD_UNIT_KIND_NORMAL
+ struct {
+ uacpi_namespace_node *region;
+ };
+
+ // UACPI_FIELD_UNIT_KIND_INDEX
+ struct {
+ struct uacpi_field_unit *index;
+ struct uacpi_field_unit *data;
+ };
+
+ // UACPI_FIELD_UNIT_KIND_BANK
+ struct {
+ uacpi_namespace_node *bank_region;
+ struct uacpi_field_unit *bank_selection;
+ uacpi_u64 bank_value;
+ };
+ };
+
+ uacpi_object *connection;
+
+ uacpi_u32 byte_offset;
+ uacpi_u32 bit_length;
+ uacpi_u32 pin_offset;
+ uacpi_u8 bit_offset_within_first_byte;
+ uacpi_u8 access_width_bytes;
+ uacpi_u8 access_length;
+
+ uacpi_u8 attributes : 4;
+ uacpi_u8 update_rule : 2;
+ uacpi_u8 kind : 2;
+ uacpi_u8 lock_rule : 1;
+} uacpi_field_unit;
+
+typedef struct uacpi_object {
+ struct uacpi_shareable shareable;
+ uacpi_u8 type;
+ uacpi_u8 flags;
+
+ union {
+ uacpi_u64 integer;
+ uacpi_package *package;
+ uacpi_buffer_field buffer_field;
+ uacpi_object *inner_object;
+ uacpi_control_method *method;
+ uacpi_buffer *buffer;
+ uacpi_mutex *mutex;
+ uacpi_event *event;
+ uacpi_buffer_index buffer_index;
+ uacpi_operation_region *op_region;
+ uacpi_device *device;
+ uacpi_processor *processor;
+ uacpi_thermal_zone *thermal_zone;
+ uacpi_address_space_handlers *address_space_handlers;
+ uacpi_handlers *handlers;
+ uacpi_power_resource power_resource;
+ uacpi_field_unit *field_unit;
+ };
+} uacpi_object;
+
+uacpi_object *uacpi_create_object(uacpi_object_type type);
+
+enum uacpi_assign_behavior {
+ UACPI_ASSIGN_BEHAVIOR_DEEP_COPY,
+ UACPI_ASSIGN_BEHAVIOR_SHALLOW_COPY,
+};
+
+uacpi_status uacpi_object_assign(uacpi_object *dst, uacpi_object *src,
+ enum uacpi_assign_behavior);
+
+void uacpi_object_attach_child(uacpi_object *parent, uacpi_object *child);
+void uacpi_object_detach_child(uacpi_object *parent);
+
+struct uacpi_object *uacpi_create_internal_reference(
+ enum uacpi_reference_kind kind, uacpi_object *child
+);
+uacpi_object *uacpi_unwrap_internal_reference(uacpi_object *object);
+
+enum uacpi_prealloc_objects {
+ UACPI_PREALLOC_OBJECTS_NO,
+ UACPI_PREALLOC_OBJECTS_YES,
+};
+
+uacpi_bool uacpi_package_fill(
+ uacpi_package *pkg, uacpi_size num_elements,
+ enum uacpi_prealloc_objects prealloc_objects
+);
+
+uacpi_mutex *uacpi_create_mutex(void);
+void uacpi_mutex_unref(uacpi_mutex*);
+
+void uacpi_method_unref(uacpi_control_method*);
+
+void uacpi_address_space_handler_unref(uacpi_address_space_handler *handler);
+
+void uacpi_buffer_to_view(uacpi_buffer*, uacpi_data_view*);
+
+#endif // !UACPI_BAREBONES_MODE
diff --git a/sys/include/dev/acpi/uacpi/uacpi/internal/utilities.h b/sys/include/dev/acpi/uacpi/uacpi/internal/utilities.h
new file mode 100644
index 0000000..606ec92
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/internal/utilities.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/utilities.h>
+#include <uacpi/internal/log.h>
+#include <uacpi/internal/stdlib.h>
+
+static inline uacpi_phys_addr uacpi_truncate_phys_addr_with_warn(uacpi_u64 large_addr)
+{
+ if (sizeof(uacpi_phys_addr) < 8 && large_addr > 0xFFFFFFFF) {
+ uacpi_warn(
+ "truncating a physical address 0x%"UACPI_PRIX64
+ " outside of address space\n", UACPI_FMT64(large_addr)
+ );
+ }
+
+ return (uacpi_phys_addr)large_addr;
+}
+
+#define UACPI_PTR_TO_VIRT_ADDR(ptr) ((uacpi_virt_addr)(ptr))
+#define UACPI_VIRT_ADDR_TO_PTR(vaddr) ((void*)(vaddr))
+
+#define UACPI_PTR_ADD(ptr, value) ((void*)(((uacpi_u8*)(ptr)) + value))
+
+/*
+ * Target buffer must have a length of at least 8 bytes.
+ */
+void uacpi_eisa_id_to_string(uacpi_u32, uacpi_char *out_string);
+
+enum uacpi_base {
+ UACPI_BASE_AUTO,
+ UACPI_BASE_OCT = 8,
+ UACPI_BASE_DEC = 10,
+ UACPI_BASE_HEX = 16,
+};
+uacpi_status uacpi_string_to_integer(
+ const uacpi_char *str, uacpi_size max_chars, enum uacpi_base base,
+ uacpi_u64 *out_value
+);
+
+uacpi_bool uacpi_is_valid_nameseg(uacpi_u8 *nameseg);
+
+void uacpi_free_dynamic_string(const uacpi_char *str);
+
+#define UACPI_NANOSECONDS_PER_SEC (1000ull * 1000ull * 1000ull)
diff --git a/sys/include/dev/acpi/uacpi/uacpi/io.h b/sys/include/dev/acpi/uacpi/uacpi/io.h
new file mode 100644
index 0000000..6535a06
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/io.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/acpi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+uacpi_status uacpi_gas_read(const struct acpi_gas *gas, uacpi_u64 *value);
+uacpi_status uacpi_gas_write(const struct acpi_gas *gas, uacpi_u64 value);
+
+typedef struct uacpi_mapped_gas uacpi_mapped_gas;
+
+/*
+ * Map a GAS for faster access in the future. The handle returned via
+ * 'out_mapped' must be freed & unmapped using uacpi_unmap_gas() when
+ * no longer needed.
+ */
+uacpi_status uacpi_map_gas(const struct acpi_gas *gas, uacpi_mapped_gas **out_mapped);
+void uacpi_unmap_gas(uacpi_mapped_gas*);
+
+/*
+ * Same as uacpi_gas_{read,write} but operates on a pre-mapped handle for faster
+ * access and/or ability to use in critical sections/irq contexts.
+ */
+uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *value);
+uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 value);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/kernel_api.h b/sys/include/dev/acpi/uacpi/uacpi/kernel_api.h
new file mode 100644
index 0000000..2a370de
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/kernel_api.h
@@ -0,0 +1,375 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/platform/arch_helpers.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Returns the PHYSICAL address of the RSDP structure via *out_rsdp_address.
+uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address);
+
+/*
+ * Map a physical memory range starting at 'addr' with length 'len', and return
+ * a virtual address that can be used to access it.
+ *
+ * NOTE: 'addr' may be misaligned, in this case the host is expected to round it
+ * down to the nearest page-aligned boundary and map that, while making
+ * sure that at least 'len' bytes are still mapped starting at 'addr'. The
+ * return value preserves the misaligned offset.
+ *
+ * Example for uacpi_kernel_map(0x1ABC, 0xF00):
+ * 1. Round down the 'addr' we got to the nearest page boundary.
+ * Considering a PAGE_SIZE of 4096 (or 0x1000), 0x1ABC rounded down
+ * is 0x1000, offset within the page is 0x1ABC - 0x1000 => 0xABC
+ * 2. Requested 'len' is 0xF00 bytes, but we just rounded the address
+ * down by 0xABC bytes, so add those on top. 0xF00 + 0xABC => 0x19BC
+ * 3. Round up the final 'len' to the nearest PAGE_SIZE boundary, in
+ * this case 0x19BC is 0x2000 bytes (2 pages if PAGE_SIZE is 4096)
+ * 4. Call the VMM to map the aligned address 0x1000 (from step 1)
+ * with length 0x2000 (from step 3). Let's assume the returned
+ * virtual address for the mapping is 0xF000.
+ * 5. Add the original offset within page 0xABC (from step 1) to the
+ * resulting virtual address 0xF000 + 0xABC => 0xFABC. Return it
+ * to uACPI.
+ */
+void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len);
+
+/*
+ * Unmap a virtual memory range at 'addr' with a length of 'len' bytes.
+ *
+ * NOTE: 'addr' may be misaligned, see the comment above 'uacpi_kernel_map'.
+ * Similar steps to uacpi_kernel_map can be taken to retrieve the
+ * virtual address originally returned by the VMM for this mapping
+ * as well as its true length.
+ */
+void uacpi_kernel_unmap(void *addr, uacpi_size len);
+
+#ifndef UACPI_FORMATTED_LOGGING
+void uacpi_kernel_log(uacpi_log_level, const uacpi_char*);
+#else
+UACPI_PRINTF_DECL(2, 3)
+void uacpi_kernel_log(uacpi_log_level, const uacpi_char*, ...);
+void uacpi_kernel_vlog(uacpi_log_level, const uacpi_char*, uacpi_va_list);
+#endif
+
+/*
+ * Only the above ^^^ API may be used by early table access and
+ * UACPI_BAREBONES_MODE.
+ */
+#ifndef UACPI_BAREBONES_MODE
+
+/*
+ * Convenience initialization/deinitialization hooks that will be called by
+ * uACPI automatically when appropriate if compiled-in.
+ */
+#ifdef UACPI_KERNEL_INITIALIZATION
+/*
+ * This API is invoked for each initialization level so that appropriate parts
+ * of the host kernel and/or glue code can be initialized at different stages.
+ *
+ * uACPI API that triggers calls to uacpi_kernel_initialize and the respective
+ * 'current_init_lvl' passed to the hook at that stage:
+ * 1. uacpi_initialize() -> UACPI_INIT_LEVEL_EARLY
+ * 2. uacpi_namespace_load() -> UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
+ * 3. (start of) uacpi_namespace_initialize() -> UACPI_INIT_LEVEL_NAMESPACE_LOADED
+ * 4. (end of) uacpi_namespace_initialize() -> UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED
+ */
+uacpi_status uacpi_kernel_initialize(uacpi_init_level current_init_lvl);
+void uacpi_kernel_deinitialize(void);
+#endif
+
+/*
+ * Open a PCI device at 'address' for reading & writing.
+ *
+ * Note that this must be able to open any arbitrary PCI device, not just those
+ * detected during kernel PCI enumeration, since the following pattern is
+ * relatively common in AML firmware:
+ * Device (THC0)
+ * {
+ * // Device at 00:10.06
+ * Name (_ADR, 0x00100006) // _ADR: Address
+ *
+ * OperationRegion (THCR, PCI_Config, Zero, 0x0100)
+ * Field (THCR, ByteAcc, NoLock, Preserve)
+ * {
+ * // Vendor ID field in the PCI configuration space
+ * VDID, 32
+ * }
+ *
+ * // Check if the device at 00:10.06 actually exists, that is reading
+ * // from its configuration space returns something other than 0xFFs.
+ * If ((VDID != 0xFFFFFFFF))
+ * {
+ * // Actually create the rest of the device's body if it's present
+ * // in the system, otherwise skip it.
+ * }
+ * }
+ *
+ * The handle returned via 'out_handle' is used to perform IO on the
+ * configuration space of the device.
+ */
+uacpi_status uacpi_kernel_pci_device_open(
+ uacpi_pci_address address, uacpi_handle *out_handle
+);
+void uacpi_kernel_pci_device_close(uacpi_handle);
+
+/*
+ * Read & write the configuration space of a previously open PCI device.
+ */
+uacpi_status uacpi_kernel_pci_read8(
+ uacpi_handle device, uacpi_size offset, uacpi_u8 *value
+);
+uacpi_status uacpi_kernel_pci_read16(
+ uacpi_handle device, uacpi_size offset, uacpi_u16 *value
+);
+uacpi_status uacpi_kernel_pci_read32(
+ uacpi_handle device, uacpi_size offset, uacpi_u32 *value
+);
+
+uacpi_status uacpi_kernel_pci_write8(
+ uacpi_handle device, uacpi_size offset, uacpi_u8 value
+);
+uacpi_status uacpi_kernel_pci_write16(
+ uacpi_handle device, uacpi_size offset, uacpi_u16 value
+);
+uacpi_status uacpi_kernel_pci_write32(
+ uacpi_handle device, uacpi_size offset, uacpi_u32 value
+);
+
+/*
+ * Map a SystemIO address at [base, base + len) and return a kernel-implemented
+ * handle that can be used for reading and writing the IO range.
+ *
+ * NOTE: The x86 architecture uses the in/out family of instructions
+ * to access the SystemIO address space.
+ */
+uacpi_status uacpi_kernel_io_map(
+ uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle
+);
+void uacpi_kernel_io_unmap(uacpi_handle handle);
+
+/*
+ * Read/Write the IO range mapped via uacpi_kernel_io_map
+ * at a 0-based 'offset' within the range.
+ *
+ * NOTE:
+ * The x86 architecture uses the in/out family of instructions
+ * to access the SystemIO address space.
+ *
+ * You are NOT allowed to break e.g. a 4-byte access into four 1-byte accesses.
+ * Hardware ALWAYS expects accesses to be of the exact width.
+ */
+uacpi_status uacpi_kernel_io_read8(
+ uacpi_handle, uacpi_size offset, uacpi_u8 *out_value
+);
+uacpi_status uacpi_kernel_io_read16(
+ uacpi_handle, uacpi_size offset, uacpi_u16 *out_value
+);
+uacpi_status uacpi_kernel_io_read32(
+ uacpi_handle, uacpi_size offset, uacpi_u32 *out_value
+);
+
+uacpi_status uacpi_kernel_io_write8(
+ uacpi_handle, uacpi_size offset, uacpi_u8 in_value
+);
+uacpi_status uacpi_kernel_io_write16(
+ uacpi_handle, uacpi_size offset, uacpi_u16 in_value
+);
+uacpi_status uacpi_kernel_io_write32(
+ uacpi_handle, uacpi_size offset, uacpi_u32 in_value
+);
+
+/*
+ * Allocate a block of memory of 'size' bytes.
+ * The contents of the allocated memory are unspecified.
+ */
+void *uacpi_kernel_alloc(uacpi_size size);
+
+#ifdef UACPI_NATIVE_ALLOC_ZEROED
+/*
+ * Allocate a block of memory of 'size' bytes.
+ * The returned memory block is expected to be zero-filled.
+ */
+void *uacpi_kernel_alloc_zeroed(uacpi_size size);
+#endif
+
+/*
+ * Free a previously allocated memory block.
+ *
+ * 'mem' might be a NULL pointer. In this case, the call is assumed to be a
+ * no-op.
+ *
+ * An optionally enabled 'size_hint' parameter contains the size of the original
+ * allocation. Note that in some scenarios this incurs additional cost to
+ * calculate the object size.
+ */
+#ifndef UACPI_SIZED_FREES
+void uacpi_kernel_free(void *mem);
+#else
+void uacpi_kernel_free(void *mem, uacpi_size size_hint);
+#endif
+
+/*
+ * Returns the number of nanosecond ticks elapsed since boot,
+ * strictly monotonic.
+ */
+uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void);
+
+/*
+ * Spin for N microseconds.
+ */
+void uacpi_kernel_stall(uacpi_u8 usec);
+
+/*
+ * Sleep for N milliseconds.
+ */
+void uacpi_kernel_sleep(uacpi_u64 msec);
+
+/*
+ * Create/free an opaque non-recursive kernel mutex object.
+ */
+uacpi_handle uacpi_kernel_create_mutex(void);
+void uacpi_kernel_free_mutex(uacpi_handle);
+
+/*
+ * Create/free an opaque kernel (semaphore-like) event object.
+ */
+uacpi_handle uacpi_kernel_create_event(void);
+void uacpi_kernel_free_event(uacpi_handle);
+
+/*
+ * Returns a unique identifier of the currently executing thread.
+ *
+ * The returned thread id cannot be UACPI_THREAD_ID_NONE.
+ */
+uacpi_thread_id uacpi_kernel_get_thread_id(void);
+
+/*
+ * Try to acquire the mutex with a millisecond timeout.
+ *
+ * The timeout value has the following meanings:
+ * 0x0000 - Attempt to acquire the mutex once, in a non-blocking manner
+ * 0x0001...0xFFFE - Attempt to acquire the mutex for at least 'timeout'
+ * milliseconds
+ * 0xFFFF - Infinite wait, block until the mutex is acquired
+ *
+ * The following are possible return values:
+ * 1. UACPI_STATUS_OK - successful acquire operation
+ * 2. UACPI_STATUS_TIMEOUT - timeout reached while attempting to acquire (or the
+ * single attempt to acquire was not successful for
+ * calls with timeout=0)
+ * 3. Any other value - signifies a host internal error and is treated as such
+ */
+uacpi_status uacpi_kernel_acquire_mutex(uacpi_handle, uacpi_u16);
+void uacpi_kernel_release_mutex(uacpi_handle);
+
+/*
+ * Try to wait for an event (counter > 0) with a millisecond timeout.
+ * A timeout value of 0xFFFF implies infinite wait.
+ *
+ * The internal counter is decremented by 1 if wait was successful.
+ *
+ * A successful wait is indicated by returning UACPI_TRUE.
+ */
+uacpi_bool uacpi_kernel_wait_for_event(uacpi_handle, uacpi_u16);
+
+/*
+ * Signal the event object by incrementing its internal counter by 1.
+ *
+ * This function may be used in interrupt contexts.
+ */
+void uacpi_kernel_signal_event(uacpi_handle);
+
+/*
+ * Reset the event counter to 0.
+ */
+void uacpi_kernel_reset_event(uacpi_handle);
+
+/*
+ * Handle a firmware request.
+ *
+ * Currently either a Breakpoint or Fatal operators.
+ */
+uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request*);
+
+/*
+ * Install an interrupt handler at 'irq', 'ctx' is passed to the provided
+ * handler for every invocation.
+ *
+ * 'out_irq_handle' is set to a kernel-implemented value that can be used to
+ * refer to this handler from other API.
+ */
+uacpi_status uacpi_kernel_install_interrupt_handler(
+ uacpi_u32 irq, uacpi_interrupt_handler, uacpi_handle ctx,
+ uacpi_handle *out_irq_handle
+);
+
+/*
+ * Uninstall an interrupt handler. 'irq_handle' is the value returned via
+ * 'out_irq_handle' during installation.
+ */
+uacpi_status uacpi_kernel_uninstall_interrupt_handler(
+ uacpi_interrupt_handler, uacpi_handle irq_handle
+);
+
+/*
+ * Create/free a kernel spinlock object.
+ *
+ * Unlike other types of locks, spinlocks may be used in interrupt contexts.
+ */
+uacpi_handle uacpi_kernel_create_spinlock(void);
+void uacpi_kernel_free_spinlock(uacpi_handle);
+
+/*
+ * Lock/unlock helpers for spinlocks.
+ *
+ * These are expected to disable interrupts, returning the previous state of cpu
+ * flags, that can be used to possibly re-enable interrupts if they were enabled
+ * before.
+ *
+ * Note that lock is infalliable.
+ */
+uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle);
+void uacpi_kernel_unlock_spinlock(uacpi_handle, uacpi_cpu_flags);
+
+typedef enum uacpi_work_type {
+ /*
+ * Schedule a GPE handler method for execution.
+ * This should be scheduled to run on CPU0 to avoid potential SMI-related
+ * firmware bugs.
+ */
+ UACPI_WORK_GPE_EXECUTION,
+
+ /*
+ * Schedule a Notify(device) firmware request for execution.
+ * This can run on any CPU.
+ */
+ UACPI_WORK_NOTIFICATION,
+} uacpi_work_type;
+
+typedef void (*uacpi_work_handler)(uacpi_handle);
+
+/*
+ * Schedules deferred work for execution.
+ * Might be invoked from an interrupt context.
+ */
+uacpi_status uacpi_kernel_schedule_work(
+ uacpi_work_type, uacpi_work_handler, uacpi_handle ctx
+);
+
+/*
+ * Waits for two types of work to finish:
+ * 1. All in-flight interrupts installed via uacpi_kernel_install_interrupt_handler
+ * 2. All work scheduled via uacpi_kernel_schedule_work
+ *
+ * Note that the waits must be done in this order specifically.
+ */
+uacpi_status uacpi_kernel_wait_for_work_completion(void);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/log.h b/sys/include/dev/acpi/uacpi/uacpi/log.h
new file mode 100644
index 0000000..4fb5457
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/log.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum uacpi_log_level {
+ /*
+ * Super verbose logging, every op & uop being processed is logged.
+ * Mostly useful for tracking down hangs/lockups.
+ */
+ UACPI_LOG_DEBUG = 5,
+
+ /*
+ * A little verbose, every operation region access is traced with a bit of
+ * extra information on top.
+ */
+ UACPI_LOG_TRACE = 4,
+
+ /*
+ * Only logs the bare minimum information about state changes and/or
+ * initialization progress.
+ */
+ UACPI_LOG_INFO = 3,
+
+ /*
+ * Logs recoverable errors and/or non-important aborts.
+ */
+ UACPI_LOG_WARN = 2,
+
+ /*
+ * Logs only critical errors that might affect the ability to initialize or
+ * prevent stable runtime.
+ */
+ UACPI_LOG_ERROR = 1,
+} uacpi_log_level;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/namespace.h b/sys/include/dev/acpi/uacpi/uacpi/namespace.h
new file mode 100644
index 0000000..5ef23af
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/namespace.h
@@ -0,0 +1,186 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef struct uacpi_namespace_node uacpi_namespace_node;
+
+uacpi_namespace_node *uacpi_namespace_root(void);
+
+typedef enum uacpi_predefined_namespace {
+ UACPI_PREDEFINED_NAMESPACE_ROOT = 0,
+ UACPI_PREDEFINED_NAMESPACE_GPE,
+ UACPI_PREDEFINED_NAMESPACE_PR,
+ UACPI_PREDEFINED_NAMESPACE_SB,
+ UACPI_PREDEFINED_NAMESPACE_SI,
+ UACPI_PREDEFINED_NAMESPACE_TZ,
+ UACPI_PREDEFINED_NAMESPACE_GL,
+ UACPI_PREDEFINED_NAMESPACE_OS,
+ UACPI_PREDEFINED_NAMESPACE_OSI,
+ UACPI_PREDEFINED_NAMESPACE_REV,
+ UACPI_PREDEFINED_NAMESPACE_MAX = UACPI_PREDEFINED_NAMESPACE_REV,
+} uacpi_predefined_namespace;
+uacpi_namespace_node *uacpi_namespace_get_predefined(
+ uacpi_predefined_namespace
+);
+
+/*
+ * Returns UACPI_TRUE if the provided 'node' is an alias.
+ */
+uacpi_bool uacpi_namespace_node_is_alias(uacpi_namespace_node *node);
+
+uacpi_object_name uacpi_namespace_node_name(const uacpi_namespace_node *node);
+
+/*
+ * Returns the type of object stored at the namespace node.
+ *
+ * NOTE: due to the existance of the CopyObject operator in AML, the
+ * return value of this function is subject to TOCTOU bugs.
+ */
+uacpi_status uacpi_namespace_node_type(
+ const uacpi_namespace_node *node, uacpi_object_type *out_type
+);
+
+/*
+ * Returns UACPI_TRUE via 'out' if the type of the object stored at the
+ * namespace node matches the provided value, UACPI_FALSE otherwise.
+ *
+ * NOTE: due to the existance of the CopyObject operator in AML, the
+ * return value of this function is subject to TOCTOU bugs.
+ */
+uacpi_status uacpi_namespace_node_is(
+ const uacpi_namespace_node *node, uacpi_object_type type, uacpi_bool *out
+);
+
+/*
+ * Returns UACPI_TRUE via 'out' if the type of the object stored at the
+ * namespace node matches any of the type bits in the provided value,
+ * UACPI_FALSE otherwise.
+ *
+ * NOTE: due to the existance of the CopyObject operator in AML, the
+ * return value of this function is subject to TOCTOU bugs.
+ */
+uacpi_status uacpi_namespace_node_is_one_of(
+ const uacpi_namespace_node *node, uacpi_object_type_bits type_mask,
+ uacpi_bool *out
+);
+
+uacpi_size uacpi_namespace_node_depth(const uacpi_namespace_node *node);
+
+uacpi_namespace_node *uacpi_namespace_node_parent(
+ uacpi_namespace_node *node
+);
+
+uacpi_status uacpi_namespace_node_find(
+ uacpi_namespace_node *parent,
+ const uacpi_char *path,
+ uacpi_namespace_node **out_node
+);
+
+/*
+ * Same as uacpi_namespace_node_find, except the search recurses upwards when
+ * the namepath consists of only a single nameseg. Usually, this behavior is
+ * only desired if resolving a namepath specified in an aml-provided object,
+ * such as a package element.
+ */
+uacpi_status uacpi_namespace_node_resolve_from_aml_namepath(
+ uacpi_namespace_node *scope,
+ const uacpi_char *path,
+ uacpi_namespace_node **out_node
+);
+
+typedef uacpi_iteration_decision (*uacpi_iteration_callback) (
+ void *user, uacpi_namespace_node *node, uacpi_u32 node_depth
+);
+
+#define UACPI_MAX_DEPTH_ANY 0xFFFFFFFF
+
+/*
+ * Depth-first iterate the namespace starting at the first child of 'parent'.
+ */
+uacpi_status uacpi_namespace_for_each_child_simple(
+ uacpi_namespace_node *parent, uacpi_iteration_callback callback, void *user
+);
+
+/*
+ * Depth-first iterate the namespace starting at the first child of 'parent'.
+ *
+ * 'descending_callback' is invoked the first time a node is visited when
+ * walking down. 'ascending_callback' is invoked the second time a node is
+ * visited after we reach the leaf node without children and start walking up.
+ * Either of the callbacks may be NULL, but not both at the same time.
+ *
+ * Only nodes matching 'type_mask' are passed to the callbacks.
+ *
+ * 'max_depth' is used to limit the maximum reachable depth from 'parent',
+ * where 1 is only direct children of 'parent', 2 is children of first-level
+ * children etc. Use UACPI_MAX_DEPTH_ANY or -1 to specify infinite depth.
+ */
+uacpi_status uacpi_namespace_for_each_child(
+ uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback,
+ uacpi_iteration_callback ascending_callback,
+ uacpi_object_type_bits type_mask, uacpi_u32 max_depth, void *user
+);
+
+/*
+ * Retrieve the next peer namespace node of '*iter', or, if '*iter' is
+ * UACPI_NULL, retrieve the first child of 'parent' instead. The resulting
+ * namespace node is stored at '*iter'.
+ *
+ * This API can be used to implement an "iterator" version of the
+ * for_each_child helpers.
+ *
+ * Example usage:
+ * void recurse(uacpi_namespace_node *parent) {
+ * uacpi_namespace_node *iter = UACPI_NULL;
+ *
+ * while (uacpi_namespace_node_next(parent, &iter) == UACPI_STATUS_OK) {
+ * // Do something with iter...
+ * descending_callback(iter);
+ *
+ * // Recurse down to walk over the children of iter
+ * recurse(iter);
+ * }
+ * }
+ *
+ * Prefer the for_each_child family of helpers if possible instead of this API
+ * as they avoid recursion and/or the need to use dynamic data structures
+ * entirely.
+ */
+uacpi_status uacpi_namespace_node_next(
+ uacpi_namespace_node *parent, uacpi_namespace_node **iter
+);
+
+/*
+ * Retrieve the next peer namespace node of '*iter', or, if '*iter' is
+ * UACPI_NULL, retrieve the first child of 'parent' instead. The resulting
+ * namespace node is stored at '*iter'. Only nodes which type matches one
+ * of the types set in 'type_mask' are returned.
+ *
+ * See comment above 'uacpi_namespace_node_next' for usage examples.
+ *
+ * Prefer the for_each_child family of helpers if possible instead of this API
+ * as they avoid recursion and/or the need to use dynamic data structures
+ * entirely.
+ */
+uacpi_status uacpi_namespace_node_next_typed(
+ uacpi_namespace_node *parent, uacpi_namespace_node **iter,
+ uacpi_object_type_bits type_mask
+);
+
+const uacpi_char *uacpi_namespace_node_generate_absolute_path(
+ const uacpi_namespace_node *node
+);
+void uacpi_free_absolute_path(const uacpi_char *path);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/notify.h b/sys/include/dev/acpi/uacpi/uacpi/notify.h
new file mode 100644
index 0000000..3b66757
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/notify.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <uacpi/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+/*
+ * Install a Notify() handler to a device node.
+ * A handler installed to the root node will receive all notifications, even if
+ * a device already has a dedicated Notify handler.
+ * 'handler_context' is passed to the handler on every invocation.
+ */
+uacpi_status uacpi_install_notify_handler(
+ uacpi_namespace_node *node, uacpi_notify_handler handler,
+ uacpi_handle handler_context
+);
+
+uacpi_status uacpi_uninstall_notify_handler(
+ uacpi_namespace_node *node, uacpi_notify_handler handler
+);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/opregion.h b/sys/include/dev/acpi/uacpi/uacpi/opregion.h
new file mode 100644
index 0000000..1eee4f0
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/opregion.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+/*
+ * Install an address space handler to a device node.
+ * The handler is recursively connected to all of the operation regions of
+ * type 'space' underneath 'device_node'. Note that this recursion stops as
+ * soon as another device node that already has an address space handler of
+ * this type installed is encountered.
+ */
+uacpi_status uacpi_install_address_space_handler(
+ uacpi_namespace_node *device_node, enum uacpi_address_space space,
+ uacpi_region_handler handler, uacpi_handle handler_context
+);
+
+/*
+ * Uninstall the handler of type 'space' from a given device node.
+ */
+uacpi_status uacpi_uninstall_address_space_handler(
+ uacpi_namespace_node *device_node,
+ enum uacpi_address_space space
+);
+
+/*
+ * Execute _REG(space, ACPI_REG_CONNECT) for all of the opregions with this
+ * address space underneath this device. This should only be called manually
+ * if you want to register an early handler that must be available before the
+ * call to uacpi_namespace_initialize().
+ */
+uacpi_status uacpi_reg_all_opregions(
+ uacpi_namespace_node *device_node,
+ enum uacpi_address_space space
+);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/osi.h b/sys/include/dev/acpi/uacpi/uacpi/osi.h
new file mode 100644
index 0000000..5330138
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/osi.h
@@ -0,0 +1,125 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef enum uacpi_vendor_interface {
+ UACPI_VENDOR_INTERFACE_NONE = 0,
+ UACPI_VENDOR_INTERFACE_WINDOWS_2000,
+ UACPI_VENDOR_INTERFACE_WINDOWS_XP,
+ UACPI_VENDOR_INTERFACE_WINDOWS_XP_SP1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_SERVER_2003,
+ UACPI_VENDOR_INTERFACE_WINDOWS_XP_SP2,
+ UACPI_VENDOR_INTERFACE_WINDOWS_SERVER_2003_SP1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_VISTA,
+ UACPI_VENDOR_INTERFACE_WINDOWS_SERVER_2008,
+ UACPI_VENDOR_INTERFACE_WINDOWS_VISTA_SP1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_VISTA_SP2,
+ UACPI_VENDOR_INTERFACE_WINDOWS_7,
+ UACPI_VENDOR_INTERFACE_WINDOWS_8,
+ UACPI_VENDOR_INTERFACE_WINDOWS_8_1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_RS1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_RS2,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_RS3,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_RS4,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_RS5,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_19H1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_10_20H1,
+ UACPI_VENDOR_INTERFACE_WINDOWS_11,
+ UACPI_VENDOR_INTERFACE_WINDOWS_11_22H2,
+} uacpi_vendor_interface;
+
+/*
+ * Returns the "latest" AML-queried _OSI vendor interface.
+ *
+ * E.g. for the following AML code:
+ * _OSI("Windows 2021")
+ * _OSI("Windows 2000")
+ *
+ * This function will return UACPI_VENDOR_INTERFACE_WINDOWS_11, since this is
+ * the latest version of the interface the code queried, even though the
+ * "Windows 2000" query came after "Windows 2021".
+ */
+uacpi_vendor_interface uacpi_latest_queried_vendor_interface(void);
+
+typedef enum uacpi_interface_kind {
+ UACPI_INTERFACE_KIND_VENDOR = (1 << 0),
+ UACPI_INTERFACE_KIND_FEATURE = (1 << 1),
+ UACPI_INTERFACE_KIND_ALL = UACPI_INTERFACE_KIND_VENDOR |
+ UACPI_INTERFACE_KIND_FEATURE,
+} uacpi_interface_kind;
+
+/*
+ * Install or uninstall an interface.
+ *
+ * The interface kind is used for matching during interface enumeration in
+ * uacpi_bulk_configure_interfaces().
+ *
+ * After installing an interface, all _OSI queries report it as supported.
+ */
+uacpi_status uacpi_install_interface(
+ const uacpi_char *name, uacpi_interface_kind
+);
+uacpi_status uacpi_uninstall_interface(const uacpi_char *name);
+
+typedef enum uacpi_host_interface {
+ UACPI_HOST_INTERFACE_MODULE_DEVICE = 1,
+ UACPI_HOST_INTERFACE_PROCESSOR_DEVICE,
+ UACPI_HOST_INTERFACE_3_0_THERMAL_MODEL,
+ UACPI_HOST_INTERFACE_3_0_SCP_EXTENSIONS,
+ UACPI_HOST_INTERFACE_PROCESSOR_AGGREGATOR_DEVICE,
+} uacpi_host_interface;
+
+/*
+ * Same as install/uninstall interface, but comes with an enum of known
+ * interfaces defined by the ACPI specification. These are disabled by default
+ * as they depend on the host kernel support.
+ */
+uacpi_status uacpi_enable_host_interface(uacpi_host_interface);
+uacpi_status uacpi_disable_host_interface(uacpi_host_interface);
+
+typedef uacpi_bool (*uacpi_interface_handler)
+ (const uacpi_char *name, uacpi_bool supported);
+
+/*
+ * Set a custom interface query (_OSI) handler.
+ *
+ * This callback will be invoked for each _OSI query with the value
+ * passed in the _OSI, as well as whether the interface was detected as
+ * supported. The callback is able to override the return value dynamically
+ * or leave it untouched if desired (e.g. if it simply wants to log something or
+ * do internal bookkeeping of some kind).
+ */
+uacpi_status uacpi_set_interface_query_handler(uacpi_interface_handler);
+
+typedef enum uacpi_interface_action {
+ UACPI_INTERFACE_ACTION_DISABLE = 0,
+ UACPI_INTERFACE_ACTION_ENABLE,
+} uacpi_interface_action;
+
+/*
+ * Bulk interface configuration, used to disable or enable all interfaces that
+ * match 'kind'.
+ *
+ * This is generally only needed to work around buggy hardware, for example if
+ * requested from the kernel command line.
+ *
+ * By default, all vendor strings (like "Windows 2000") are enabled, and all
+ * host features (like "3.0 Thermal Model") are disabled.
+ */
+uacpi_status uacpi_bulk_configure_interfaces(
+ uacpi_interface_action action, uacpi_interface_kind kind
+);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/platform/arch_helpers.h b/sys/include/dev/acpi/uacpi/uacpi/platform/arch_helpers.h
new file mode 100644
index 0000000..2e566c4
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/platform/arch_helpers.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#ifdef UACPI_OVERRIDE_ARCH_HELPERS
+#include "uacpi_arch_helpers.h"
+#else
+
+#include <uacpi/platform/atomic.h>
+
+#ifndef UACPI_ARCH_FLUSH_CPU_CACHE
+#define UACPI_ARCH_FLUSH_CPU_CACHE() do {} while (0)
+#endif
+
+typedef unsigned long uacpi_cpu_flags;
+
+typedef void *uacpi_thread_id;
+
+/*
+ * Replace as needed depending on your platform's way to represent thread ids.
+ * uACPI offers a few more helpers like uacpi_atomic_{load,store}{8,16,32,64,ptr}
+ * (or you could provide your own helpers)
+ */
+#ifndef UACPI_ATOMIC_LOAD_THREAD_ID
+#define UACPI_ATOMIC_LOAD_THREAD_ID(ptr) ((uacpi_thread_id)uacpi_atomic_load_ptr(ptr))
+#endif
+
+#ifndef UACPI_ATOMIC_STORE_THREAD_ID
+#define UACPI_ATOMIC_STORE_THREAD_ID(ptr, value) uacpi_atomic_store_ptr(ptr, value)
+#endif
+
+/*
+ * A sentinel value that the kernel promises to NEVER return from
+ * uacpi_kernel_get_current_thread_id or this will break
+ */
+#ifndef UACPI_THREAD_ID_NONE
+#define UACPI_THREAD_ID_NONE ((uacpi_thread_id)-1)
+#endif
+
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/platform/atomic.h b/sys/include/dev/acpi/uacpi/uacpi/platform/atomic.h
new file mode 100644
index 0000000..1d1b570
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/platform/atomic.h
@@ -0,0 +1,347 @@
+#pragma once
+
+/*
+ * Most of this header is a giant workaround for MSVC to make atomics into a
+ * somewhat unified interface with how GCC and Clang handle them.
+ *
+ * We don't use the absolutely disgusting C11 stdatomic.h header because it is
+ * unable to operate on non _Atomic types, which enforce implicit sequential
+ * consistency and alter the behavior of the standard C binary/unary operators.
+ *
+ * The strictness of the atomic helpers defined here is assumed to be at least
+ * acquire for loads and release for stores. Cmpxchg uses the standard acq/rel
+ * for success, acq for failure, and is assumed to be strong.
+ */
+
+#ifdef UACPI_OVERRIDE_ATOMIC
+#include "uacpi_atomic.h"
+#else
+
+#include <uacpi/platform/compiler.h>
+
+#if defined(_MSC_VER) && !defined(__clang__)
+
+#include <intrin.h>
+
+// mimic __atomic_compare_exchange_n that doesn't exist on MSVC
+#define UACPI_MAKE_MSVC_CMPXCHG(width, type, suffix) \
+ static inline int uacpi_do_atomic_cmpxchg##width( \
+ type volatile *ptr, type volatile *expected, type desired \
+ ) \
+ { \
+ type current; \
+ \
+ current = _InterlockedCompareExchange##suffix(ptr, *expected, desired); \
+ if (current != *expected) { \
+ *expected = current; \
+ return 0; \
+ } \
+ return 1; \
+ }
+
+#define UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, width, type) \
+ uacpi_do_atomic_cmpxchg##width( \
+ (type volatile*)ptr, (type volatile*)expected, desired \
+ )
+
+#define UACPI_MSVC_ATOMIC_STORE(ptr, value, type, width) \
+ _InterlockedExchange##width((type volatile*)(ptr), (type)(value))
+
+#define UACPI_MSVC_ATOMIC_LOAD(ptr, type, width) \
+ _InterlockedOr##width((type volatile*)(ptr), 0)
+
+#define UACPI_MSVC_ATOMIC_INC(ptr, type, width) \
+ _InterlockedIncrement##width((type volatile*)(ptr))
+
+#define UACPI_MSVC_ATOMIC_DEC(ptr, type, width) \
+ _InterlockedDecrement##width((type volatile*)(ptr))
+
+UACPI_MAKE_MSVC_CMPXCHG(64, __int64, 64)
+UACPI_MAKE_MSVC_CMPXCHG(32, long,)
+UACPI_MAKE_MSVC_CMPXCHG(16, short, 16)
+
+#define uacpi_atomic_cmpxchg16(ptr, expected, desired) \
+ UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, 16, short)
+
+#define uacpi_atomic_cmpxchg32(ptr, expected, desired) \
+ UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, 32, long)
+
+#define uacpi_atomic_cmpxchg64(ptr, expected, desired) \
+ UACPI_MSVC_CMPXCHG_INVOKE(ptr, expected, desired, 64, __int64)
+
+#define uacpi_atomic_load8(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, char, 8)
+#define uacpi_atomic_load16(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, short, 16)
+#define uacpi_atomic_load32(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, long,)
+#define uacpi_atomic_load64(ptr) UACPI_MSVC_ATOMIC_LOAD(ptr, __int64, 64)
+
+#define uacpi_atomic_store8(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, char, 8)
+#define uacpi_atomic_store16(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, short, 16)
+#define uacpi_atomic_store32(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, long,)
+#define uacpi_atomic_store64(ptr, value) UACPI_MSVC_ATOMIC_STORE(ptr, value, __int64, 64)
+
+#define uacpi_atomic_inc16(ptr) UACPI_MSVC_ATOMIC_INC(ptr, short, 16)
+#define uacpi_atomic_inc32(ptr) UACPI_MSVC_ATOMIC_INC(ptr, long,)
+#define uacpi_atomic_inc64(ptr) UACPI_MSVC_ATOMIC_INC(ptr, __int64, 64)
+
+#define uacpi_atomic_dec16(ptr) UACPI_MSVC_ATOMIC_DEC(ptr, short, 16)
+#define uacpi_atomic_dec32(ptr) UACPI_MSVC_ATOMIC_DEC(ptr, long,)
+#define uacpi_atomic_dec64(ptr) UACPI_MSVC_ATOMIC_DEC(ptr, __int64, 64)
+#elif defined(__WATCOMC__)
+
+#include <stdint.h>
+
+static int uacpi_do_atomic_cmpxchg16(volatile uint16_t *ptr, volatile uint16_t *expected, uint16_t desired);
+#pragma aux uacpi_do_atomic_cmpxchg16 = \
+ ".486" \
+ "mov ax, [esi]" \
+ "lock cmpxchg [edi], bx" \
+ "mov [esi], ax" \
+ "setz al" \
+ "movzx eax, al" \
+ parm [ edi ] [ esi ] [ ebx ] \
+ value [ eax ]
+
+static int uacpi_do_atomic_cmpxchg32(volatile uint32_t *ptr, volatile uint32_t *expected, uint32_t desired);
+#pragma aux uacpi_do_atomic_cmpxchg32 = \
+ ".486" \
+ "mov eax, [esi]" \
+ "lock cmpxchg [edi], ebx" \
+ "mov [esi], eax" \
+ "setz al" \
+ "movzx eax, al" \
+ parm [ edi ] [ esi ] [ ebx ] \
+ value [ eax ]
+
+static int uacpi_do_atomic_cmpxchg64_asm(volatile uint64_t *ptr, volatile uint64_t *expected, uint32_t low, uint32_t high);
+#pragma aux uacpi_do_atomic_cmpxchg64_asm = \
+ ".586" \
+ "mov eax, [esi]" \
+ "mov edx, [esi + 4]" \
+ "lock cmpxchg8b [edi]" \
+ "mov [esi], eax" \
+ "mov [esi + 4], edx" \
+ "setz al" \
+ "movzx eax, al" \
+ modify [ edx ] \
+ parm [ edi ] [ esi ] [ ebx ] [ ecx ] \
+ value [ eax ]
+
+static inline int uacpi_do_atomic_cmpxchg64(volatile uint64_t *ptr, volatile uint64_t *expected, uint64_t desired) {
+ return uacpi_do_atomic_cmpxchg64_asm(ptr, expected, desired, desired >> 32);
+}
+
+#define uacpi_atomic_cmpxchg16(ptr, expected, desired) \
+ uacpi_do_atomic_cmpxchg16((volatile uint16_t*)ptr, (volatile uint16_t*)expected, (uint16_t)desired)
+#define uacpi_atomic_cmpxchg32(ptr, expected, desired) \
+ uacpi_do_atomic_cmpxchg32((volatile uint32_t*)ptr, (volatile uint32_t*)expected, (uint32_t)desired)
+#define uacpi_atomic_cmpxchg64(ptr, expected, desired) \
+ uacpi_do_atomic_cmpxchg64((volatile uint64_t*)ptr, (volatile uint64_t*)expected, (uint64_t)desired)
+
+static uint8_t uacpi_do_atomic_load8(volatile uint8_t *ptr);
+#pragma aux uacpi_do_atomic_load8 = \
+ "mov al, [esi]" \
+ parm [ esi ] \
+ value [ al ]
+
+static uint16_t uacpi_do_atomic_load16(volatile uint16_t *ptr);
+#pragma aux uacpi_do_atomic_load16 = \
+ "mov ax, [esi]" \
+ parm [ esi ] \
+ value [ ax ]
+
+static uint32_t uacpi_do_atomic_load32(volatile uint32_t *ptr);
+#pragma aux uacpi_do_atomic_load32 = \
+ "mov eax, [esi]" \
+ parm [ esi ] \
+ value [ eax ]
+
+static void uacpi_do_atomic_load64_asm(volatile uint64_t *ptr, uint64_t *out);
+#pragma aux uacpi_do_atomic_load64_asm = \
+ ".586" \
+ "xor eax, eax" \
+ "xor ebx, ebx" \
+ "xor ecx, ecx" \
+ "xor edx, edx" \
+ "lock cmpxchg8b [esi]" \
+ "mov [edi], eax" \
+ "mov [edi + 4], edx" \
+ modify [ eax ebx ecx edx ] \
+ parm [ esi ] [ edi ]
+
+static inline uint64_t uacpi_do_atomic_load64(volatile uint64_t *ptr) {
+ uint64_t value;
+ uacpi_do_atomic_load64_asm(ptr, &value);
+ return value;
+}
+
+#define uacpi_atomic_load8(ptr) uacpi_do_atomic_load8((volatile uint8_t*)ptr)
+#define uacpi_atomic_load16(ptr) uacpi_do_atomic_load16((volatile uint16_t*)ptr)
+#define uacpi_atomic_load32(ptr) uacpi_do_atomic_load32((volatile uint32_t*)ptr)
+#define uacpi_atomic_load64(ptr) uacpi_do_atomic_load64((volatile uint64_t*)ptr)
+
+static void uacpi_do_atomic_store8(volatile uint8_t *ptr, uint8_t value);
+#pragma aux uacpi_do_atomic_store8 = \
+ "mov [edi], al" \
+ parm [ edi ] [ eax ]
+
+static void uacpi_do_atomic_store16(volatile uint16_t *ptr, uint16_t value);
+#pragma aux uacpi_do_atomic_store16 = \
+ "mov [edi], ax" \
+ parm [ edi ] [ eax ]
+
+static void uacpi_do_atomic_store32(volatile uint32_t *ptr, uint32_t value);
+#pragma aux uacpi_do_atomic_store32 = \
+ "mov [edi], eax" \
+ parm [ edi ] [ eax ]
+
+static void uacpi_do_atomic_store64_asm(volatile uint64_t *ptr, uint32_t low, uint32_t high);
+#pragma aux uacpi_do_atomic_store64_asm = \
+ ".586" \
+ "xor eax, eax" \
+ "xor edx, edx" \
+ "retry: lock cmpxchg8b [edi]" \
+ "jnz retry" \
+ modify [ eax edx ] \
+ parm [ edi ] [ ebx ] [ ecx ]
+
+static inline void uacpi_do_atomic_store64(volatile uint64_t *ptr, uint64_t value) {
+ uacpi_do_atomic_store64_asm(ptr, value, value >> 32);
+}
+
+#define uacpi_atomic_store8(ptr, value) uacpi_do_atomic_store8((volatile uint8_t*)ptr, (uint8_t)value)
+#define uacpi_atomic_store16(ptr, value) uacpi_do_atomic_store16((volatile uint16_t*)ptr, (uint16_t)value)
+#define uacpi_atomic_store32(ptr, value) uacpi_do_atomic_store32((volatile uint32_t*)ptr, (uint32_t)value)
+#define uacpi_atomic_store64(ptr, value) uacpi_do_atomic_store64((volatile uint64_t*)ptr, (uint64_t)value)
+
+static uint16_t uacpi_do_atomic_inc16(volatile uint16_t *ptr);
+#pragma aux uacpi_do_atomic_inc16 = \
+ ".486" \
+ "mov ax, 1" \
+ "lock xadd [edi], ax" \
+ "add ax, 1" \
+ parm [ edi ] \
+ value [ ax ]
+
+static uint32_t uacpi_do_atomic_inc32(volatile uint32_t *ptr);
+#pragma aux uacpi_do_atomic_inc32 = \
+ ".486" \
+ "mov eax, 1" \
+ "lock xadd [edi], eax" \
+ "add eax, 1" \
+ parm [ edi ] \
+ value [ eax ]
+
+static void uacpi_do_atomic_inc64_asm(volatile uint64_t *ptr, uint64_t *out);
+#pragma aux uacpi_do_atomic_inc64_asm = \
+ ".586" \
+ "xor eax, eax" \
+ "xor edx, edx" \
+ "mov ebx, 1" \
+ "mov ecx, 1" \
+ "retry: lock cmpxchg8b [esi]" \
+ "mov ebx, eax" \
+ "mov ecx, edx" \
+ "add ebx, 1" \
+ "adc ecx, 0" \
+ "jnz retry" \
+ "mov [edi], ebx" \
+ "mov [edi + 4], ecx" \
+ modify [ eax ebx ecx edx ] \
+ parm [ esi ] [ edi ]
+
+static inline uint64_t uacpi_do_atomic_inc64(volatile uint64_t *ptr) {
+ uint64_t value;
+ uacpi_do_atomic_inc64_asm(ptr, &value);
+ return value;
+}
+
+#define uacpi_atomic_inc16(ptr) uacpi_do_atomic_inc16((volatile uint16_t*)ptr)
+#define uacpi_atomic_inc32(ptr) uacpi_do_atomic_inc32((volatile uint32_t*)ptr)
+#define uacpi_atomic_inc64(ptr) uacpi_do_atomic_inc64((volatile uint64_t*)ptr)
+
+static uint16_t uacpi_do_atomic_dec16(volatile uint16_t *ptr);
+#pragma aux uacpi_do_atomic_dec16 = \
+ ".486" \
+ "mov ax, -1" \
+ "lock xadd [edi], ax" \
+ "add ax, -1" \
+ parm [ edi ] \
+ value [ ax ]
+
+static uint32_t uacpi_do_atomic_dec32(volatile uint32_t *ptr);
+#pragma aux uacpi_do_atomic_dec32 = \
+ ".486" \
+ "mov eax, -1" \
+ "lock xadd [edi], eax" \
+ "add eax, -1" \
+ parm [ edi ] \
+ value [ eax ]
+
+static void uacpi_do_atomic_dec64_asm(volatile uint64_t *ptr, uint64_t *out);
+#pragma aux uacpi_do_atomic_dec64_asm = \
+ ".586" \
+ "xor eax, eax" \
+ "xor edx, edx" \
+ "mov ebx, -1" \
+ "mov ecx, -1" \
+ "retry: lock cmpxchg8b [esi]" \
+ "mov ebx, eax" \
+ "mov ecx, edx" \
+ "sub ebx, 1" \
+ "sbb ecx, 0" \
+ "jnz retry" \
+ "mov [edi], ebx" \
+ "mov [edi + 4], ecx" \
+ modify [ eax ebx ecx edx ] \
+ parm [ esi ] [ edi ]
+
+static inline uint64_t uacpi_do_atomic_dec64(volatile uint64_t *ptr) {
+ uint64_t value;
+ uacpi_do_atomic_dec64_asm(ptr, &value);
+ return value;
+}
+
+#define uacpi_atomic_dec16(ptr) uacpi_do_atomic_dec16((volatile uint16_t*)ptr)
+#define uacpi_atomic_dec32(ptr) uacpi_do_atomic_dec32((volatile uint32_t*)ptr)
+#define uacpi_atomic_dec64(ptr) uacpi_do_atomic_dec64((volatile uint64_t*)ptr)
+#else
+
+#define UACPI_DO_CMPXCHG(ptr, expected, desired) \
+ __atomic_compare_exchange_n(ptr, expected, desired, 0, \
+ __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)
+
+#define uacpi_atomic_cmpxchg16(ptr, expected, desired) \
+ UACPI_DO_CMPXCHG(ptr, expected, desired)
+#define uacpi_atomic_cmpxchg32(ptr, expected, desired) \
+ UACPI_DO_CMPXCHG(ptr, expected, desired)
+#define uacpi_atomic_cmpxchg64(ptr, expected, desired) \
+ UACPI_DO_CMPXCHG(ptr, expected, desired)
+
+#define uacpi_atomic_load8(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
+#define uacpi_atomic_load16(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
+#define uacpi_atomic_load32(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
+#define uacpi_atomic_load64(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE)
+
+#define uacpi_atomic_store8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
+#define uacpi_atomic_store16(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
+#define uacpi_atomic_store32(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
+#define uacpi_atomic_store64(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_RELEASE)
+
+#define uacpi_atomic_inc16(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_ACQ_REL)
+#define uacpi_atomic_inc32(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_ACQ_REL)
+#define uacpi_atomic_inc64(ptr) __atomic_add_fetch(ptr, 1, __ATOMIC_ACQ_REL)
+
+#define uacpi_atomic_dec16(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_ACQ_REL)
+#define uacpi_atomic_dec32(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_ACQ_REL)
+#define uacpi_atomic_dec64(ptr) __atomic_sub_fetch(ptr, 1, __ATOMIC_ACQ_REL)
+#endif
+
+#if UACPI_POINTER_SIZE == 4
+#define uacpi_atomic_load_ptr(ptr_to_ptr) uacpi_atomic_load32(ptr_to_ptr)
+#define uacpi_atomic_store_ptr(ptr_to_ptr, value) uacpi_atomic_store32(ptr_to_ptr, value)
+#else
+#define uacpi_atomic_load_ptr(ptr_to_ptr) uacpi_atomic_load64(ptr_to_ptr)
+#define uacpi_atomic_store_ptr(ptr_to_ptr, value) uacpi_atomic_store64(ptr_to_ptr, value)
+#endif
+
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/platform/compiler.h b/sys/include/dev/acpi/uacpi/uacpi/platform/compiler.h
new file mode 100644
index 0000000..78aab08
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/platform/compiler.h
@@ -0,0 +1,123 @@
+#pragma once
+
+/*
+ * Compiler-specific attributes/macros go here. This is the default placeholder
+ * that should work for MSVC/GCC/clang.
+ */
+
+#ifdef UACPI_OVERRIDE_COMPILER
+#include "uacpi_compiler.h"
+#else
+
+#define UACPI_ALIGN(x) __declspec(align(x))
+
+#if defined(__WATCOMC__)
+#define UACPI_STATIC_ASSERT(expr, msg)
+#elif defined(__cplusplus)
+#define UACPI_STATIC_ASSERT static_assert
+#else
+#define UACPI_STATIC_ASSERT _Static_assert
+#endif
+
+#ifdef _MSC_VER
+ #include <intrin.h>
+
+ #define UACPI_ALWAYS_INLINE __forceinline
+
+ #define UACPI_PACKED(decl) \
+ __pragma(pack(push, 1)) \
+ decl; \
+ __pragma(pack(pop))
+#elif defined(__WATCOMC__)
+ #define UACPI_ALWAYS_INLINE inline
+ #define UACPI_PACKED(decl) _Packed decl;
+#else
+ #define UACPI_ALWAYS_INLINE inline __attribute__((always_inline))
+ #define UACPI_PACKED(decl) decl __attribute__((packed));
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+ #define uacpi_unlikely(expr) __builtin_expect(!!(expr), 0)
+ #define uacpi_likely(expr) __builtin_expect(!!(expr), 1)
+
+ #if __has_attribute(__fallthrough__)
+ #define UACPI_FALLTHROUGH __attribute__((__fallthrough__))
+ #endif
+
+ #define UACPI_MAYBE_UNUSED __attribute__ ((unused))
+
+ #define UACPI_NO_UNUSED_PARAMETER_WARNINGS_BEGIN \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
+
+ #define UACPI_NO_UNUSED_PARAMETER_WARNINGS_END \
+ _Pragma("GCC diagnostic pop")
+
+ #ifdef __clang__
+ #define UACPI_PRINTF_DECL(fmt_idx, args_idx) \
+ __attribute__((format(printf, fmt_idx, args_idx)))
+ #else
+ #define UACPI_PRINTF_DECL(fmt_idx, args_idx) \
+ __attribute__((format(gnu_printf, fmt_idx, args_idx)))
+ #endif
+
+ #define UACPI_COMPILER_HAS_BUILTIN_MEMCPY
+ #define UACPI_COMPILER_HAS_BUILTIN_MEMMOVE
+ #define UACPI_COMPILER_HAS_BUILTIN_MEMSET
+ #define UACPI_COMPILER_HAS_BUILTIN_MEMCMP
+#elif defined(__WATCOMC__)
+ #define uacpi_unlikely(expr) expr
+ #define uacpi_likely(expr) expr
+
+ /*
+ * The OpenWatcom documentation suggests this should be done using
+ * _Pragma("off (unreferenced)") and _Pragma("pop (unreferenced)"),
+ * but these pragmas appear to be no-ops. Use inline as the next best thing.
+ * Note that OpenWatcom accepts redundant modifiers without a warning,
+ * so UACPI_MAYBE_UNUSED inline still works.
+ */
+ #define UACPI_MAYBE_UNUSED inline
+
+ #define UACPI_NO_UNUSED_PARAMETER_WARNINGS_BEGIN
+ #define UACPI_NO_UNUSED_PARAMETER_WARNINGS_END
+
+ #define UACPI_PRINTF_DECL(fmt_idx, args_idx)
+#else
+ #define uacpi_unlikely(expr) expr
+ #define uacpi_likely(expr) expr
+
+ #define UACPI_MAYBE_UNUSED
+
+ #define UACPI_NO_UNUSED_PARAMETER_WARNINGS_BEGIN
+ #define UACPI_NO_UNUSED_PARAMETER_WARNINGS_END
+
+ #define UACPI_PRINTF_DECL(fmt_idx, args_idx)
+#endif
+
+#ifndef UACPI_FALLTHROUGH
+ #define UACPI_FALLTHROUGH do {} while (0)
+#endif
+
+#ifndef UACPI_POINTER_SIZE
+ #ifdef _WIN32
+ #ifdef _WIN64
+ #define UACPI_POINTER_SIZE 8
+ #else
+ #define UACPI_POINTER_SIZE 4
+ #endif
+ #elif defined(__GNUC__)
+ #define UACPI_POINTER_SIZE __SIZEOF_POINTER__
+ #elif defined(__WATCOMC__)
+ #ifdef __386__
+ #define UACPI_POINTER_SIZE 4
+ #elif defined(__I86__)
+ #error uACPI does not support 16-bit mode compilation
+ #else
+ #error Unknown target architecture
+ #endif
+ #else
+ #error Failed to detect pointer size
+ #endif
+#endif
+
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/platform/config.h b/sys/include/dev/acpi/uacpi/uacpi/platform/config.h
new file mode 100644
index 0000000..dff043f
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/platform/config.h
@@ -0,0 +1,162 @@
+#pragma once
+
+#ifdef UACPI_OVERRIDE_CONFIG
+#include "uacpi_config.h"
+#else
+
+#include <uacpi/helpers.h>
+#include <uacpi/log.h>
+
+/*
+ * =======================
+ * Context-related options
+ * =======================
+ */
+#ifndef UACPI_DEFAULT_LOG_LEVEL
+ #define UACPI_DEFAULT_LOG_LEVEL UACPI_LOG_INFO
+#endif
+
+UACPI_BUILD_BUG_ON_WITH_MSG(
+ UACPI_DEFAULT_LOG_LEVEL < UACPI_LOG_ERROR ||
+ UACPI_DEFAULT_LOG_LEVEL > UACPI_LOG_DEBUG,
+ "configured default log level is invalid"
+);
+
+#ifndef UACPI_DEFAULT_LOOP_TIMEOUT_SECONDS
+ #define UACPI_DEFAULT_LOOP_TIMEOUT_SECONDS 30
+#endif
+
+UACPI_BUILD_BUG_ON_WITH_MSG(
+ UACPI_DEFAULT_LOOP_TIMEOUT_SECONDS < 1,
+ "configured default loop timeout is invalid (expecting at least 1 second)"
+);
+
+#ifndef UACPI_DEFAULT_MAX_CALL_STACK_DEPTH
+ #define UACPI_DEFAULT_MAX_CALL_STACK_DEPTH 256
+#endif
+
+UACPI_BUILD_BUG_ON_WITH_MSG(
+ UACPI_DEFAULT_MAX_CALL_STACK_DEPTH < 4,
+ "configured default max call stack depth is invalid "
+ "(expecting at least 4 frames)"
+);
+
+/*
+ * ===================
+ * Kernel-api options
+ * ===================
+ */
+
+/*
+ * Convenience initialization/deinitialization hooks that will be called by
+ * uACPI automatically when appropriate if compiled-in.
+ */
+// #define UACPI_KERNEL_INITIALIZATION
+
+/*
+ * Makes kernel api logging callbacks work with unformatted printf-style
+ * strings and va_args instead of a pre-formatted string. Can be useful if
+ * your native logging is implemented in terms of this format as well.
+ */
+// #define UACPI_FORMATTED_LOGGING
+
+/*
+ * Makes uacpi_kernel_free take in an additional 'size_hint' parameter, which
+ * contains the size of the original allocation. Note that this comes with a
+ * performance penalty in some cases.
+ */
+// #define UACPI_SIZED_FREES
+
+
+/*
+ * Makes uacpi_kernel_alloc_zeroed mandatory to implement by the host, uACPI
+ * will not provide a default implementation if this is enabled.
+ */
+// #define UACPI_NATIVE_ALLOC_ZEROED
+
+/*
+ * =========================
+ * Platform-specific options
+ * =========================
+ */
+
+/*
+ * Makes uACPI use the internal versions of mem{cpy,move,set,cmp} instead of
+ * relying on the host to provide them. Note that compilers like clang and GCC
+ * rely on these being available by default, even in freestanding mode, so
+ * compiling uACPI may theoretically generate implicit dependencies on them
+ * even if this option is defined.
+ */
+// #define UACPI_USE_BUILTIN_STRING
+
+/*
+ * Turns uacpi_phys_addr and uacpi_io_addr into a 32-bit type, and adds extra
+ * code for address truncation. Needed for e.g. i686 platforms without PAE
+ * support.
+ */
+// #define UACPI_PHYS_ADDR_IS_32BITS
+
+/*
+ * Switches uACPI into reduced-hardware-only mode. Strips all full-hardware
+ * ACPI support code at compile-time, including the event subsystem, the global
+ * lock, and other full-hardware features.
+ */
+// #define UACPI_REDUCED_HARDWARE
+
+/*
+ * Switches uACPI into tables-subsystem-only mode and strips all other code.
+ * This means only the table API will be usable, no other subsystems are
+ * compiled in. In this mode, uACPI only depends on the following kernel APIs:
+ * - uacpi_kernel_get_rsdp
+ * - uacpi_kernel_{map,unmap}
+ * - uacpi_kernel_log
+ *
+ * Use uacpi_setup_early_table_access to initialize, uacpi_state_reset to
+ * deinitialize.
+ *
+ * This mode is primarily designed for these three use-cases:
+ * - Bootloader/pre-kernel environments that need to parse ACPI tables, but
+ * don't actually need a fully-featured AML interpreter, and everything else
+ * that a full APCI implementation entails.
+ * - A micro-kernel that has the full AML interpreter running in userspace, but
+ * still needs to parse ACPI tables to bootstrap allocators, timers, SMP etc.
+ * - A WIP kernel that needs to parse ACPI tables for bootrapping SMP/timers,
+ * ECAM, etc., but doesn't yet have enough subsystems implemented in order
+ * to run a fully-featured AML interpreter.
+ */
+// #define UACPI_BAREBONES_MODE
+
+/*
+ * =============
+ * Misc. options
+ * =============
+ */
+
+/*
+ * If UACPI_FORMATTED_LOGGING is not enabled, this is the maximum length of the
+ * pre-formatted message that is passed to the logging callback.
+ */
+#ifndef UACPI_PLAIN_LOG_BUFFER_SIZE
+ #define UACPI_PLAIN_LOG_BUFFER_SIZE 128
+#endif
+
+UACPI_BUILD_BUG_ON_WITH_MSG(
+ UACPI_PLAIN_LOG_BUFFER_SIZE < 16,
+ "configured log buffer size is too small (expecting at least 16 bytes)"
+);
+
+/*
+ * The size of the table descriptor inline storage. All table descriptors past
+ * this length will be stored in a dynamically allocated heap array. The size
+ * of one table descriptor is approximately 56 bytes.
+ */
+#ifndef UACPI_STATIC_TABLE_ARRAY_LEN
+ #define UACPI_STATIC_TABLE_ARRAY_LEN 16
+#endif
+
+UACPI_BUILD_BUG_ON_WITH_MSG(
+ UACPI_STATIC_TABLE_ARRAY_LEN < 1,
+ "configured static table array length is too small (expecting at least 1)"
+);
+
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/platform/libc.h b/sys/include/dev/acpi/uacpi/uacpi/platform/libc.h
new file mode 100644
index 0000000..44c9013
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/platform/libc.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#ifdef UACPI_OVERRIDE_LIBC
+#include "uacpi_libc.h"
+#else
+/*
+ * The following libc functions are used internally by uACPI and have a default
+ * (sub-optimal) implementation:
+ * - strcmp
+ * - strnlen
+ * - strlen
+ * - snprintf
+ * - vsnprintf
+ *
+ * The following use a builtin implementation only if UACPI_USE_BUILTIN_STRING
+ * is defined (more information can be found in the config.h header):
+ * - memcpy
+ * - memmove
+ * - memset
+ * - memcmp
+ *
+ * In case your platform happens to implement optimized verisons of the helpers
+ * above, you are able to make uACPI use those instead by overriding them like so:
+ *
+ * #define uacpi_memcpy my_fast_memcpy
+ * #define uacpi_snprintf my_fast_snprintf
+ */
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/platform/types.h b/sys/include/dev/acpi/uacpi/uacpi/platform/types.h
new file mode 100644
index 0000000..f4a7cf9
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/platform/types.h
@@ -0,0 +1,64 @@
+#pragma once
+
+/*
+ * Platform-specific types go here. This is the default placeholder using
+ * types from the standard headers.
+ */
+
+#ifdef UACPI_OVERRIDE_TYPES
+#include "uacpi_types.h"
+#else
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#include <uacpi/helpers.h>
+
+typedef uint8_t uacpi_u8;
+typedef uint16_t uacpi_u16;
+typedef uint32_t uacpi_u32;
+typedef uint64_t uacpi_u64;
+
+typedef int8_t uacpi_i8;
+typedef int16_t uacpi_i16;
+typedef int32_t uacpi_i32;
+typedef int64_t uacpi_i64;
+
+#define UACPI_TRUE true
+#define UACPI_FALSE false
+typedef bool uacpi_bool;
+
+#define UACPI_NULL NULL
+
+typedef uintptr_t uacpi_uintptr;
+typedef uacpi_uintptr uacpi_virt_addr;
+typedef size_t uacpi_size;
+
+typedef va_list uacpi_va_list;
+#define uacpi_va_start va_start
+#define uacpi_va_end va_end
+#define uacpi_va_arg va_arg
+
+typedef char uacpi_char;
+
+#define uacpi_offsetof offsetof
+
+/*
+ * We use unsignd long long for 64-bit number formatting because 64-bit types
+ * don't have a standard way to format them. The inttypes.h header is not
+ * freestanding therefore it's not practical to force the user to define the
+ * corresponding PRI macros. Moreover, unsignd long long is required to be
+ * at least 64-bits as per C99.
+ */
+UACPI_BUILD_BUG_ON_WITH_MSG(
+ sizeof(unsigned long long) < 8,
+ "unsigned long long must be at least 64 bits large as per C99"
+);
+#define UACPI_PRIu64 "llu"
+#define UACPI_PRIx64 "llx"
+#define UACPI_PRIX64 "llX"
+#define UACPI_FMT64(val) ((unsigned long long)(val))
+
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/registers.h b/sys/include/dev/acpi/uacpi/uacpi/registers.h
new file mode 100644
index 0000000..cdffb97
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/registers.h
@@ -0,0 +1,105 @@
+#include <uacpi/types.h>
+
+/*
+ * BEFORE YOU USE THIS API:
+ * uACPI manages FADT registers on its own entirely, you should only use this
+ * API directly if there's absolutely no other way for your use case, e.g.
+ * implementing a CPU idle state driver that does C state switching or similar.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef enum uacpi_register {
+ UACPI_REGISTER_PM1_STS = 0,
+ UACPI_REGISTER_PM1_EN,
+ UACPI_REGISTER_PM1_CNT,
+ UACPI_REGISTER_PM_TMR,
+ UACPI_REGISTER_PM2_CNT,
+ UACPI_REGISTER_SLP_CNT,
+ UACPI_REGISTER_SLP_STS,
+ UACPI_REGISTER_RESET,
+ UACPI_REGISTER_SMI_CMD,
+ UACPI_REGISTER_MAX = UACPI_REGISTER_SMI_CMD,
+} uacpi_register;
+
+/*
+ * Read a register from FADT
+ *
+ * NOTE: write-only bits (if any) are cleared automatically
+ */
+uacpi_status uacpi_read_register(uacpi_register, uacpi_u64*);
+
+/*
+ * Write a register from FADT
+ *
+ * NOTE:
+ * - Preserved bits (if any) are preserved automatically
+ * - If a register is made up of two (e.g. PM1a and PM1b) parts, the input
+ * is written to both at the same time
+ */
+uacpi_status uacpi_write_register(uacpi_register, uacpi_u64);
+
+/*
+ * Write a register from FADT
+ *
+ * NOTE:
+ * - Preserved bits (if any) are preserved automatically
+ * - For registers that are made up of two (e.g. PM1a and PM1b) parts, the
+ * provided values are written to their respective physical register
+ */
+uacpi_status uacpi_write_registers(uacpi_register, uacpi_u64, uacpi_u64);
+
+typedef enum uacpi_register_field {
+ UACPI_REGISTER_FIELD_TMR_STS = 0,
+ UACPI_REGISTER_FIELD_BM_STS,
+ UACPI_REGISTER_FIELD_GBL_STS,
+ UACPI_REGISTER_FIELD_PWRBTN_STS,
+ UACPI_REGISTER_FIELD_SLPBTN_STS,
+ UACPI_REGISTER_FIELD_RTC_STS,
+ UACPI_REGISTER_FIELD_PCIEX_WAKE_STS,
+ UACPI_REGISTER_FIELD_HWR_WAK_STS,
+ UACPI_REGISTER_FIELD_WAK_STS,
+ UACPI_REGISTER_FIELD_TMR_EN,
+ UACPI_REGISTER_FIELD_GBL_EN,
+ UACPI_REGISTER_FIELD_PWRBTN_EN,
+ UACPI_REGISTER_FIELD_SLPBTN_EN,
+ UACPI_REGISTER_FIELD_RTC_EN,
+ UACPI_REGISTER_FIELD_PCIEXP_WAKE_DIS,
+ UACPI_REGISTER_FIELD_SCI_EN,
+ UACPI_REGISTER_FIELD_BM_RLD,
+ UACPI_REGISTER_FIELD_GBL_RLS,
+ UACPI_REGISTER_FIELD_SLP_TYP,
+ UACPI_REGISTER_FIELD_HWR_SLP_TYP,
+ UACPI_REGISTER_FIELD_SLP_EN,
+ UACPI_REGISTER_FIELD_HWR_SLP_EN,
+ UACPI_REGISTER_FIELD_ARB_DIS,
+ UACPI_REGISTER_FIELD_MAX = UACPI_REGISTER_FIELD_ARB_DIS,
+} uacpi_register_field;
+
+/*
+ * Read a field from a FADT register
+ *
+ * NOTE: The value is automatically masked and shifted down as appropriate,
+ * the client code doesn't have to do any bit manipulation. E.g. for
+ * a field at 0b???XX??? the returned value will contain just the 0bXX
+ */
+uacpi_status uacpi_read_register_field(uacpi_register_field, uacpi_u64*);
+
+/*
+ * Write to a field of a FADT register
+ *
+ * NOTE: The value is automatically masked and shifted up as appropriate,
+ * the client code doesn't have to do any bit manipulation. E.g. for
+ * a field at 0b???XX??? the passed value should be just 0bXX
+ */
+uacpi_status uacpi_write_register_field(uacpi_register_field, uacpi_u64);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/resources.h b/sys/include/dev/acpi/uacpi/uacpi/resources.h
new file mode 100644
index 0000000..f929f1d
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/resources.h
@@ -0,0 +1,740 @@
+#pragma once
+
+#include <uacpi/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef enum uacpi_resource_type {
+ UACPI_RESOURCE_TYPE_IRQ,
+ UACPI_RESOURCE_TYPE_EXTENDED_IRQ,
+
+ UACPI_RESOURCE_TYPE_DMA,
+ UACPI_RESOURCE_TYPE_FIXED_DMA,
+
+ UACPI_RESOURCE_TYPE_IO,
+ UACPI_RESOURCE_TYPE_FIXED_IO,
+
+ UACPI_RESOURCE_TYPE_ADDRESS16,
+ UACPI_RESOURCE_TYPE_ADDRESS32,
+ UACPI_RESOURCE_TYPE_ADDRESS64,
+ UACPI_RESOURCE_TYPE_ADDRESS64_EXTENDED,
+
+ UACPI_RESOURCE_TYPE_MEMORY24,
+ UACPI_RESOURCE_TYPE_MEMORY32,
+ UACPI_RESOURCE_TYPE_FIXED_MEMORY32,
+
+ UACPI_RESOURCE_TYPE_START_DEPENDENT,
+ UACPI_RESOURCE_TYPE_END_DEPENDENT,
+
+ // Up to 7 bytes
+ UACPI_RESOURCE_TYPE_VENDOR_SMALL,
+
+ // Up to 2^16 - 1 bytes
+ UACPI_RESOURCE_TYPE_VENDOR_LARGE,
+
+ UACPI_RESOURCE_TYPE_GENERIC_REGISTER,
+ UACPI_RESOURCE_TYPE_GPIO_CONNECTION,
+
+ // These must always be contiguous in this order
+ UACPI_RESOURCE_TYPE_SERIAL_I2C_CONNECTION,
+ UACPI_RESOURCE_TYPE_SERIAL_SPI_CONNECTION,
+ UACPI_RESOURCE_TYPE_SERIAL_UART_CONNECTION,
+ UACPI_RESOURCE_TYPE_SERIAL_CSI2_CONNECTION,
+
+ UACPI_RESOURCE_TYPE_PIN_FUNCTION,
+ UACPI_RESOURCE_TYPE_PIN_CONFIGURATION,
+ UACPI_RESOURCE_TYPE_PIN_GROUP,
+ UACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION,
+ UACPI_RESOURCE_TYPE_PIN_GROUP_CONFIGURATION,
+
+ UACPI_RESOURCE_TYPE_CLOCK_INPUT,
+
+ UACPI_RESOURCE_TYPE_END_TAG,
+ UACPI_RESOURCE_TYPE_MAX = UACPI_RESOURCE_TYPE_END_TAG,
+} uacpi_resource_type;
+
+typedef struct uacpi_resource_source {
+ uacpi_u8 index;
+ uacpi_bool index_present;
+ uacpi_u16 length;
+ uacpi_char *string;
+} uacpi_resource_source;
+
+/*
+ * This applies to IRQ & StartDependent resources only. The DONT_CARE value is
+ * used for deserialization into the AML format to signify that the serializer
+ * is allowed to optimize the length down if possible. Note that this is
+ * generally not allowed unless the resource is generated by the caller:
+ *
+ * -- ACPI 6.5 ------------------------------------------------------------
+ * The resource descriptors in the byte stream argument must be specified
+ * exactly as listed in the _CRS byte stream - meaning that the identical
+ * resource descriptors must appear in the identical order, resulting in a
+ * buffer of exactly the same length. Optimizations such as changing an
+ * IRQ descriptor to an IRQNoFlags descriptor (or vice-versa) must not be
+ * performed. Similarly, changing StartDependentFn to StartDependentFnNoPri
+ * is not allowed.
+ * ------------------------------------------------------------------------
+ */
+enum uacpi_resource_length_kind {
+ UACPI_RESOURCE_LENGTH_KIND_DONT_CARE = 0,
+ UACPI_RESOURCE_LENGTH_KIND_ONE_LESS,
+ UACPI_RESOURCE_LENGTH_KIND_FULL,
+};
+
+// triggering fields
+#define UACPI_TRIGGERING_EDGE 1
+#define UACPI_TRIGGERING_LEVEL 0
+
+// polarity
+#define UACPI_POLARITY_ACTIVE_HIGH 0
+#define UACPI_POLARITY_ACTIVE_LOW 1
+#define UACPI_POLARITY_ACTIVE_BOTH 2
+
+// sharing
+#define UACPI_EXCLUSIVE 0
+#define UACPI_SHARED 1
+
+// wake_capability
+#define UACPI_WAKE_CAPABLE 1
+#define UACPI_NOT_WAKE_CAPABLE 0
+
+typedef struct uacpi_resource_irq {
+ uacpi_u8 length_kind;
+ uacpi_u8 triggering;
+ uacpi_u8 polarity;
+ uacpi_u8 sharing;
+ uacpi_u8 wake_capability;
+ uacpi_u8 num_irqs;
+ uacpi_u8 irqs[];
+} uacpi_resource_irq;
+
+typedef struct uacpi_resource_extended_irq {
+ uacpi_u8 direction;
+ uacpi_u8 triggering;
+ uacpi_u8 polarity;
+ uacpi_u8 sharing;
+ uacpi_u8 wake_capability;
+ uacpi_u8 num_irqs;
+ uacpi_resource_source source;
+ uacpi_u32 irqs[];
+} uacpi_resource_extended_irq;
+
+// transfer_type
+#define UACPI_TRANSFER_TYPE_8_BIT 0b00
+#define UACPI_TRANSFER_TYPE_8_AND_16_BIT 0b01
+#define UACPI_TRANSFER_TYPE_16_BIT 0b10
+
+// bus_master_status
+#define UACPI_BUS_MASTER 0b1
+
+// channel_speed
+#define UACPI_DMA_COMPATIBILITY 0b00
+#define UACPI_DMA_TYPE_A 0b01
+#define UACPI_DMA_TYPE_B 0b10
+#define UACPI_DMA_TYPE_F 0b11
+
+// transfer_width
+#define UACPI_TRANSFER_WIDTH_8 0x00
+#define UACPI_TRANSFER_WIDTH_16 0x01
+#define UACPI_TRANSFER_WIDTH_32 0x02
+#define UACPI_TRANSFER_WIDTH_64 0x03
+#define UACPI_TRANSFER_WIDTH_128 0x04
+#define UACPI_TRANSFER_WIDTH_256 0x05
+
+typedef struct uacpi_resource_dma {
+ uacpi_u8 transfer_type;
+ uacpi_u8 bus_master_status;
+ uacpi_u8 channel_speed;
+ uacpi_u8 num_channels;
+ uacpi_u8 channels[];
+} uacpi_resource_dma;
+
+typedef struct uacpi_resource_fixed_dma {
+ uacpi_u16 request_line;
+ uacpi_u16 channel;
+ uacpi_u8 transfer_width;
+} uacpi_resource_fixed_dma;
+
+// decode_type
+#define UACPI_DECODE_16 0b1
+#define UACPI_DECODE_10 0b0
+
+typedef struct uacpi_resource_io {
+ uacpi_u8 decode_type;
+ uacpi_u16 minimum;
+ uacpi_u16 maximum;
+ uacpi_u8 alignment;
+ uacpi_u8 length;
+} uacpi_resource_io;
+
+typedef struct uacpi_resource_fixed_io {
+ uacpi_u16 address;
+ uacpi_u8 length;
+} uacpi_resource_fixed_io;
+
+// write_status
+#define UACPI_NON_WRITABLE 0
+#define UACPI_WRITABLE 1
+
+// caching
+#define UACPI_NON_CACHEABLE 0
+#define UACPI_CACHEABLE 1
+#define UACPI_CACHEABLE_WRITE_COMBINING 2
+#define UACPI_PREFETCHABLE 3
+
+// range_type
+#define UACPI_RANGE_TYPE_MEMORY 0
+#define UACPI_RANGE_TYPE_RESERVED 1
+#define UACPI_RANGE_TYPE_ACPI 2
+#define UACPI_RANGE_TYPE_NVS 3
+
+// address_common->type
+#define UACPI_RANGE_MEMORY 0
+#define UACPI_RANGE_IO 1
+#define UACPI_RANGE_BUS 2
+
+// translation
+#define UACPI_IO_MEM_TRANSLATION 1
+#define UACPI_IO_MEM_STATIC 0
+
+// translation_type
+#define UACPI_TRANSLATION_DENSE 0
+#define UACPI_TRANSLATION_SPARSE 1
+
+// direction
+#define UACPI_PRODUCER 0
+#define UACPI_CONSUMER 1
+
+// decode_type
+#define UACPI_POSITIVE_DECODE 0
+#define UACPI_SUBTRACTIVE_DECODE 1
+
+/*
+ * DO NOT USE! SLATED FOR REMOVAL AT 3.0
+ * See the version without the typo above (UACPI_POSITIVE_DECODE)
+ */
+#define UACPI_POISITIVE_DECODE 0
+
+// fixed_min_address & fixed_max_address
+#define UACPI_ADDRESS_NOT_FIXED 0
+#define UACPI_ADDRESS_FIXED 1
+
+typedef struct uacpi_memory_attribute {
+ uacpi_u8 write_status;
+ uacpi_u8 caching;
+ uacpi_u8 range_type;
+ uacpi_u8 translation;
+} uacpi_memory_attribute;
+
+typedef struct uacpi_io_attribute {
+ uacpi_u8 range_type;
+ uacpi_u8 translation;
+ uacpi_u8 translation_type;
+} uacpi_io_attribute;
+
+typedef union uacpi_address_attribute {
+ uacpi_memory_attribute memory;
+ uacpi_io_attribute io;
+ uacpi_u8 type_specific;
+} uacpi_address_attribute;
+
+typedef struct uacpi_resource_address_common {
+ uacpi_address_attribute attribute;
+ uacpi_u8 type;
+ uacpi_u8 direction;
+ uacpi_u8 decode_type;
+ uacpi_u8 fixed_min_address;
+ uacpi_u8 fixed_max_address;
+} uacpi_resource_address_common;
+
+typedef struct uacpi_resource_address16 {
+ uacpi_resource_address_common common;
+ uacpi_u16 granularity;
+ uacpi_u16 minimum;
+ uacpi_u16 maximum;
+ uacpi_u16 translation_offset;
+ uacpi_u16 address_length;
+ uacpi_resource_source source;
+} uacpi_resource_address16;
+
+typedef struct uacpi_resource_address32 {
+ uacpi_resource_address_common common;
+ uacpi_u32 granularity;
+ uacpi_u32 minimum;
+ uacpi_u32 maximum;
+ uacpi_u32 translation_offset;
+ uacpi_u32 address_length;
+ uacpi_resource_source source;
+} uacpi_resource_address32;
+
+typedef struct uacpi_resource_address64 {
+ uacpi_resource_address_common common;
+ uacpi_u64 granularity;
+ uacpi_u64 minimum;
+ uacpi_u64 maximum;
+ uacpi_u64 translation_offset;
+ uacpi_u64 address_length;
+ uacpi_resource_source source;
+} uacpi_resource_address64;
+
+typedef struct uacpi_resource_address64_extended {
+ uacpi_resource_address_common common;
+ uacpi_u8 revision_id;
+ uacpi_u64 granularity;
+ uacpi_u64 minimum;
+ uacpi_u64 maximum;
+ uacpi_u64 translation_offset;
+ uacpi_u64 address_length;
+ uacpi_u64 attributes;
+} uacpi_resource_address64_extended;
+
+typedef struct uacpi_resource_memory24 {
+ uacpi_u8 write_status;
+ uacpi_u16 minimum;
+ uacpi_u16 maximum;
+ uacpi_u16 alignment;
+ uacpi_u16 length;
+} uacpi_resource_memory24;
+
+typedef struct uacpi_resource_memory32 {
+ uacpi_u8 write_status;
+ uacpi_u32 minimum;
+ uacpi_u32 maximum;
+ uacpi_u32 alignment;
+ uacpi_u32 length;
+} uacpi_resource_memory32;
+
+typedef struct uacpi_resource_fixed_memory32 {
+ uacpi_u8 write_status;
+ uacpi_u32 address;
+ uacpi_u32 length;
+} uacpi_resource_fixed_memory32;
+
+// compatibility & performance
+#define UACPI_GOOD 0
+#define UACPI_ACCEPTABLE 1
+#define UACPI_SUB_OPTIMAL 2
+
+typedef struct uacpi_resource_start_dependent {
+ uacpi_u8 length_kind;
+ uacpi_u8 compatibility;
+ uacpi_u8 performance;
+} uacpi_resource_start_dependent;
+
+typedef struct uacpi_resource_vendor_defined {
+ uacpi_u8 length;
+ uacpi_u8 data[];
+} uacpi_resource_vendor;
+
+typedef struct uacpi_resource_vendor_typed {
+ uacpi_u16 length;
+ uacpi_u8 sub_type;
+ uacpi_u8 uuid[16];
+ uacpi_u8 data[];
+} uacpi_resource_vendor_typed;
+
+typedef struct uacpi_resource_generic_register {
+ uacpi_u8 address_space_id;
+ uacpi_u8 bit_width;
+ uacpi_u8 bit_offset;
+ uacpi_u8 access_size;
+ uacpi_u64 address;
+} uacpi_resource_generic_register;
+
+// type
+#define UACPI_GPIO_CONNECTION_INTERRUPT 0x00
+#define UACPI_GPIO_CONNECTION_IO 0x01
+
+typedef struct uacpi_interrupt_connection_flags {
+ uacpi_u8 triggering;
+ uacpi_u8 polarity;
+ uacpi_u8 sharing;
+ uacpi_u8 wake_capability;
+} uacpi_interrupt_connection_flags;
+
+// restriction
+#define UACPI_IO_RESTRICTION_NONE 0x0
+#define UACPI_IO_RESTRICTION_INPUT 0x1
+#define UACPI_IO_RESTRICTION_OUTPUT 0x2
+#define UACPI_IO_RESTRICTION_NONE_PRESERVE 0x3
+
+typedef struct uacpi_io_connection_flags {
+ uacpi_u8 restriction;
+ uacpi_u8 sharing;
+} uacpi_io_connection_flags;
+
+// pull_configuration
+#define UACPI_PIN_CONFIG_DEFAULT 0x00
+#define UACPI_PIN_CONFIG_PULL_UP 0x01
+#define UACPI_PIN_CONFIG_PULL_DOWN 0x02
+#define UACPI_PIN_CONFIG_NO_PULL 0x03
+
+typedef struct uacpi_resource_gpio_connection {
+ uacpi_u8 revision_id;
+ uacpi_u8 type;
+ uacpi_u8 direction;
+
+ union {
+ uacpi_interrupt_connection_flags intr;
+ uacpi_io_connection_flags io;
+ uacpi_u16 type_specific;
+ };
+
+ uacpi_u8 pull_configuration;
+ uacpi_u16 drive_strength;
+ uacpi_u16 debounce_timeout;
+ uacpi_u16 vendor_data_length;
+ uacpi_u16 pin_table_length;
+ uacpi_resource_source source;
+ uacpi_u16 *pin_table;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_gpio_connection;
+
+// mode
+#define UACPI_MODE_CONTROLLER_INITIATED 0x0
+#define UACPI_MODE_DEVICE_INITIATED 0x1
+
+typedef struct uacpi_resource_serial_bus_common {
+ uacpi_u8 revision_id;
+ uacpi_u8 type;
+ uacpi_u8 mode;
+ uacpi_u8 direction;
+ uacpi_u8 sharing;
+ uacpi_u8 type_revision_id;
+ uacpi_u16 type_data_length;
+ uacpi_u16 vendor_data_length;
+ uacpi_resource_source source;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_serial_bus_common;
+
+// addressing_mode
+#define UACPI_I2C_7BIT 0x0
+#define UACPI_I2C_10BIT 0x1
+
+typedef struct uacpi_resource_i2c_connection {
+ uacpi_resource_serial_bus_common common;
+ uacpi_u8 addressing_mode;
+ uacpi_u16 slave_address;
+ uacpi_u32 connection_speed;
+} uacpi_resource_i2c_connection;
+
+// wire_mode
+#define UACPI_SPI_4_WIRES 0
+#define UACPI_SPI_3_WIRES 1
+
+// device_polarity
+#define UACPI_SPI_ACTIVE_LOW 0
+#define UACPI_SPI_ACTIVE_HIGH 1
+
+// phase
+#define UACPI_SPI_PHASE_FIRST 0
+#define UACPI_SPI_PHASE_SECOND 1
+
+// polarity
+#define UACPI_SPI_START_LOW 0
+#define UACPI_SPI_START_HIGH 1
+
+typedef struct uacpi_resource_spi_connection {
+ uacpi_resource_serial_bus_common common;
+ uacpi_u8 wire_mode;
+ uacpi_u8 device_polarity;
+ uacpi_u8 data_bit_length;
+ uacpi_u8 phase;
+ uacpi_u8 polarity;
+ uacpi_u16 device_selection;
+ uacpi_u32 connection_speed;
+} uacpi_resource_spi_connection;
+
+// stop_bits
+#define UACPI_UART_STOP_BITS_NONE 0b00
+#define UACPI_UART_STOP_BITS_1 0b01
+#define UACPI_UART_STOP_BITS_1_5 0b10
+#define UACPI_UART_STOP_BITS_2 0b11
+
+// data_bits
+#define UACPI_UART_DATA_5BITS 0b000
+#define UACPI_UART_DATA_6BITS 0b001
+#define UACPI_UART_DATA_7BITS 0b010
+#define UACPI_UART_DATA_8BITS 0b011
+#define UACPI_UART_DATA_9BITS 0b100
+
+// endianness
+#define UACPI_UART_LITTLE_ENDIAN 0
+#define UACPI_UART_BIG_ENDIAN 1
+
+// parity
+#define UACPI_UART_PARITY_NONE 0x00
+#define UACPI_UART_PARITY_EVEN 0x01
+#define UACPI_UART_PARITY_ODD 0x02
+#define UACPI_UART_PARITY_MARK 0x03
+#define UACPI_UART_PARITY_SPACE 0x04
+
+// lines_enabled
+#define UACPI_UART_DATA_CARRIER_DETECT (1 << 2)
+#define UACPI_UART_RING_INDICATOR (1 << 3)
+#define UACPI_UART_DATA_SET_READY (1 << 4)
+#define UACPI_UART_DATA_TERMINAL_READY (1 << 5)
+#define UACPI_UART_CLEAR_TO_SEND (1 << 6)
+#define UACPI_UART_REQUEST_TO_SEND (1 << 7)
+
+// flow_control
+#define UACPI_UART_FLOW_CONTROL_NONE 0b00
+#define UACPI_UART_FLOW_CONTROL_HW 0b01
+#define UACPI_UART_FLOW_CONTROL_XON_XOFF 0b10
+
+typedef struct uacpi_resource_uart_connection {
+ uacpi_resource_serial_bus_common common;
+ uacpi_u8 stop_bits;
+ uacpi_u8 data_bits;
+ uacpi_u8 endianness;
+ uacpi_u8 parity;
+ uacpi_u8 lines_enabled;
+ uacpi_u8 flow_control;
+ uacpi_u32 baud_rate;
+ uacpi_u16 rx_fifo;
+ uacpi_u16 tx_fifo;
+} uacpi_resource_uart_connection;
+
+// phy_type
+#define UACPI_CSI2_PHY_C 0b00
+#define UACPI_CSI2_PHY_D 0b01
+
+typedef struct uacpi_resource_csi2_connection {
+ uacpi_resource_serial_bus_common common;
+ uacpi_u8 phy_type;
+ uacpi_u8 local_port;
+} uacpi_resource_csi2_connection;
+
+typedef struct uacpi_resource_pin_function {
+ uacpi_u8 revision_id;
+ uacpi_u8 sharing;
+ uacpi_u8 pull_configuration;
+ uacpi_u16 function_number;
+ uacpi_u16 pin_table_length;
+ uacpi_u16 vendor_data_length;
+ uacpi_resource_source source;
+ uacpi_u16 *pin_table;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_pin_function;
+
+// type
+#define UACPI_PIN_CONFIG_DEFAULT 0x00
+#define UACPI_PIN_CONFIG_BIAS_PULL_UP 0x01
+#define UACPI_PIN_CONFIG_BIAS_PULL_DOWN 0x02
+#define UACPI_PIN_CONFIG_BIAS_DEFAULT 0x03
+#define UACPI_PIN_CONFIG_BIAS_DISABLE 0x04
+#define UACPI_PIN_CONFIG_BIAS_HIGH_IMPEDANCE 0x05
+#define UACPI_PIN_CONFIG_BIAS_BUS_HOLD 0x06
+#define UACPI_PIN_CONFIG_DRIVE_OPEN_DRAIN 0x07
+#define UACPI_PIN_CONFIG_DRIVE_OPEN_SOURCE 0x08
+#define UACPI_PIN_CONFIG_DRIVE_PUSH_PULL 0x09
+#define UACPI_PIN_CONFIG_DRIVE_STRENGTH 0x0A
+#define UACPI_PIN_CONFIG_SLEW_RATE 0x0B
+#define UACPI_PIN_CONFIG_INPUT_DEBOUNCE 0x0C
+#define UACPI_PIN_CONFIG_INPUT_SCHMITT_TRIGGER 0x0D
+
+typedef struct uacpi_resource_pin_configuration {
+ uacpi_u8 revision_id;
+ uacpi_u8 sharing;
+ uacpi_u8 direction;
+ uacpi_u8 type;
+ uacpi_u32 value;
+ uacpi_u16 pin_table_length;
+ uacpi_u16 vendor_data_length;
+ uacpi_resource_source source;
+ uacpi_u16 *pin_table;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_pin_configuration;
+
+typedef struct uacpi_resource_label {
+ uacpi_u16 length;
+ const uacpi_char *string;
+} uacpi_resource_label;
+
+typedef struct uacpi_resource_pin_group {
+ uacpi_u8 revision_id;
+ uacpi_u8 direction;
+ uacpi_u16 pin_table_length;
+ uacpi_u16 vendor_data_length;
+ uacpi_resource_label label;
+ uacpi_u16 *pin_table;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_pin_group;
+
+typedef struct uacpi_resource_pin_group_function {
+ uacpi_u8 revision_id;
+ uacpi_u8 sharing;
+ uacpi_u8 direction;
+ uacpi_u16 function;
+ uacpi_u16 vendor_data_length;
+ uacpi_resource_source source;
+ uacpi_resource_label label;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_pin_group_function;
+
+typedef struct uacpi_resource_pin_group_configuration {
+ uacpi_u8 revision_id;
+ uacpi_u8 sharing;
+ uacpi_u8 direction;
+ uacpi_u8 type;
+ uacpi_u32 value;
+ uacpi_u16 vendor_data_length;
+ uacpi_resource_source source;
+ uacpi_resource_label label;
+ uacpi_u8 *vendor_data;
+} uacpi_resource_pin_group_configuration;
+
+// scale
+#define UACPI_SCALE_HZ 0b00
+#define UACPI_SCALE_KHZ 0b01
+#define UACPI_SCALE_MHZ 0b10
+
+// frequency
+#define UACPI_FREQUENCY_FIXED 0x0
+#define UACPI_FREQUENCY_VARIABLE 0x1
+
+typedef struct uacpi_resource_clock_input {
+ uacpi_u8 revision_id;
+ uacpi_u8 frequency;
+ uacpi_u8 scale;
+ uacpi_u16 divisor;
+ uacpi_u32 numerator;
+ uacpi_resource_source source;
+} uacpi_resource_clock_input;
+
+typedef struct uacpi_resource {
+ uacpi_u32 type;
+ uacpi_u32 length;
+
+ union {
+ uacpi_resource_irq irq;
+ uacpi_resource_extended_irq extended_irq;
+ uacpi_resource_dma dma;
+ uacpi_resource_fixed_dma fixed_dma;
+ uacpi_resource_io io;
+ uacpi_resource_fixed_io fixed_io;
+ uacpi_resource_address16 address16;
+ uacpi_resource_address32 address32;
+ uacpi_resource_address64 address64;
+ uacpi_resource_address64_extended address64_extended;
+ uacpi_resource_memory24 memory24;
+ uacpi_resource_memory32 memory32;
+ uacpi_resource_fixed_memory32 fixed_memory32;
+ uacpi_resource_start_dependent start_dependent;
+ uacpi_resource_vendor vendor;
+ uacpi_resource_vendor_typed vendor_typed;
+ uacpi_resource_generic_register generic_register;
+ uacpi_resource_gpio_connection gpio_connection;
+ uacpi_resource_serial_bus_common serial_bus_common;
+ uacpi_resource_i2c_connection i2c_connection;
+ uacpi_resource_spi_connection spi_connection;
+ uacpi_resource_uart_connection uart_connection;
+ uacpi_resource_csi2_connection csi2_connection;
+ uacpi_resource_pin_function pin_function;
+ uacpi_resource_pin_configuration pin_configuration;
+ uacpi_resource_pin_group pin_group;
+ uacpi_resource_pin_group_function pin_group_function;
+ uacpi_resource_pin_group_configuration pin_group_configuration;
+ uacpi_resource_clock_input clock_input;
+ };
+} uacpi_resource;
+
+#define UACPI_NEXT_RESOURCE(cur) \
+ ((uacpi_resource*)((uacpi_u8*)(cur) + (cur)->length))
+
+typedef struct uacpi_resources {
+ uacpi_size length;
+ uacpi_resource *entries;
+} uacpi_resources;
+void uacpi_free_resources(uacpi_resources*);
+
+typedef uacpi_iteration_decision (*uacpi_resource_iteration_callback)
+ (void *user, uacpi_resource *resource);
+
+/*
+ * Evaluate the _CRS method for a 'device' and get the returned resource list
+ * via 'out_resources'.
+ *
+ * NOTE: the returned buffer must be released via a uacpi_free_resources()
+ */
+uacpi_status uacpi_get_current_resources(
+ uacpi_namespace_node *device, uacpi_resources **out_resources
+);
+
+/*
+ * Evaluate the _PRS method for a 'device' and get the returned resource list
+ * via 'out_resources'.
+ *
+ * NOTE: the returned buffer must be released via uacpi_free_resources()
+ */
+uacpi_status uacpi_get_possible_resources(
+ uacpi_namespace_node *device, uacpi_resources **out_resources
+);
+
+/*
+ * Evaluate an arbitrary method that is expected to return an AML resource
+ * buffer for a 'device' and get the returned resource list via 'out_resources'.
+ *
+ * NOTE: the returned buffer must be released via uacpi_free_resources()
+ */
+uacpi_status uacpi_get_device_resources(
+ uacpi_namespace_node *device, const uacpi_char *method,
+ uacpi_resources **out_resources
+);
+
+/*
+ * Set the configuration to be used by the 'device' by calling its _SRS method.
+ *
+ * Note that this expects 'resources' in the normal 'uacpi_resources' format,
+ * and not the raw AML resources bytestream, the conversion to the latter is
+ * done automatically by this API. If you want to _SRS a raw AML resources
+ * bytestream, use 'uacpi_execute' or similar API directly.
+ */
+uacpi_status uacpi_set_resources(
+ uacpi_namespace_node *device, uacpi_resources *resources
+);
+
+/*
+ * A convenience helper for iterating over the resource list returned by any
+ * of the uacpi_get_*_resources functions.
+ */
+uacpi_status uacpi_for_each_resource(
+ uacpi_resources *resources, uacpi_resource_iteration_callback cb, void *user
+);
+
+/*
+ * A shorthand for uacpi_get_device_resources() + uacpi_for_each_resource().
+ *
+ * Use if you don't actually want to save the 'resources' list, but simply want
+ * to iterate it once to extract the resources you care about and then free it
+ * right away.
+ */
+uacpi_status uacpi_for_each_device_resource(
+ uacpi_namespace_node *device, const uacpi_char *method,
+ uacpi_resource_iteration_callback cb, void *user
+);
+
+/*
+ * Convert a single AML-encoded resource to native format.
+ *
+ * This should be used for converting Connection() fields (passed during IO on
+ * GeneralPurposeIO or GenericSerialBus operation regions) or other similar
+ * buffers with only one resource to native format.
+ *
+ * NOTE: the returned buffer must be released via uacpi_free_resource()
+ */
+uacpi_status uacpi_get_resource_from_buffer(
+ uacpi_data_view aml_buffer, uacpi_resource **out_resource
+);
+void uacpi_free_resource(uacpi_resource*);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/sleep.h b/sys/include/dev/acpi/uacpi/uacpi/sleep.h
new file mode 100644
index 0000000..3fd9bf3
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/sleep.h
@@ -0,0 +1,67 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+#include <uacpi/uacpi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+/*
+ * Set the firmware waking vector in FACS.
+ *
+ * 'addr32' is the real mode entry-point address
+ * 'addr64' is the protected mode entry-point address
+ */
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+uacpi_status uacpi_set_waking_vector(
+ uacpi_phys_addr addr32, uacpi_phys_addr addr64
+))
+
+typedef enum uacpi_sleep_state {
+ UACPI_SLEEP_STATE_S0 = 0,
+ UACPI_SLEEP_STATE_S1,
+ UACPI_SLEEP_STATE_S2,
+ UACPI_SLEEP_STATE_S3,
+ UACPI_SLEEP_STATE_S4,
+ UACPI_SLEEP_STATE_S5,
+ UACPI_SLEEP_STATE_MAX = UACPI_SLEEP_STATE_S5,
+} uacpi_sleep_state;
+
+/*
+ * Prepare for a given sleep state.
+ * Must be caled with interrupts ENABLED.
+ */
+uacpi_status uacpi_prepare_for_sleep_state(uacpi_sleep_state);
+
+/*
+ * Enter the given sleep state after preparation.
+ * Must be called with interrupts DISABLED.
+ */
+uacpi_status uacpi_enter_sleep_state(uacpi_sleep_state);
+
+/*
+ * Prepare to leave the given sleep state.
+ * Must be called with interrupts DISABLED.
+ */
+uacpi_status uacpi_prepare_for_wake_from_sleep_state(uacpi_sleep_state);
+
+/*
+ * Wake from the given sleep state.
+ * Must be called with interrupts ENABLED.
+ */
+uacpi_status uacpi_wake_from_sleep_state(uacpi_sleep_state);
+
+/*
+ * Attempt reset via the FADT reset register.
+ */
+uacpi_status uacpi_reboot(void);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/status.h b/sys/include/dev/acpi/uacpi/uacpi/status.h
new file mode 100644
index 0000000..5c09508
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/status.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <uacpi/internal/compiler.h>
+#include <uacpi/platform/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum uacpi_status {
+ UACPI_STATUS_OK = 0,
+ UACPI_STATUS_MAPPING_FAILED = 1,
+ UACPI_STATUS_OUT_OF_MEMORY = 2,
+ UACPI_STATUS_BAD_CHECKSUM = 3,
+ UACPI_STATUS_INVALID_SIGNATURE = 4,
+ UACPI_STATUS_INVALID_TABLE_LENGTH = 5,
+ UACPI_STATUS_NOT_FOUND = 6,
+ UACPI_STATUS_INVALID_ARGUMENT = 7,
+ UACPI_STATUS_UNIMPLEMENTED = 8,
+ UACPI_STATUS_ALREADY_EXISTS = 9,
+ UACPI_STATUS_INTERNAL_ERROR = 10,
+ UACPI_STATUS_TYPE_MISMATCH = 11,
+ UACPI_STATUS_INIT_LEVEL_MISMATCH = 12,
+ UACPI_STATUS_NAMESPACE_NODE_DANGLING = 13,
+ UACPI_STATUS_NO_HANDLER = 14,
+ UACPI_STATUS_NO_RESOURCE_END_TAG = 15,
+ UACPI_STATUS_COMPILED_OUT = 16,
+ UACPI_STATUS_HARDWARE_TIMEOUT = 17,
+ UACPI_STATUS_TIMEOUT = 18,
+ UACPI_STATUS_OVERRIDDEN = 19,
+ UACPI_STATUS_DENIED = 20,
+
+ // All errors that have bytecode-related origin should go here
+ UACPI_STATUS_AML_UNDEFINED_REFERENCE = 0x0EFF0000,
+ UACPI_STATUS_AML_INVALID_NAMESTRING = 0x0EFF0001,
+ UACPI_STATUS_AML_OBJECT_ALREADY_EXISTS = 0x0EFF0002,
+ UACPI_STATUS_AML_INVALID_OPCODE = 0x0EFF0003,
+ UACPI_STATUS_AML_INCOMPATIBLE_OBJECT_TYPE = 0x0EFF0004,
+ UACPI_STATUS_AML_BAD_ENCODING = 0x0EFF0005,
+ UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX = 0x0EFF0006,
+ UACPI_STATUS_AML_SYNC_LEVEL_TOO_HIGH = 0x0EFF0007,
+ UACPI_STATUS_AML_INVALID_RESOURCE = 0x0EFF0008,
+ UACPI_STATUS_AML_LOOP_TIMEOUT = 0x0EFF0009,
+ UACPI_STATUS_AML_CALL_STACK_DEPTH_LIMIT = 0x0EFF000A,
+} uacpi_status;
+
+const uacpi_char *uacpi_status_to_string(uacpi_status);
+
+#define uacpi_unlikely_error(expr) uacpi_unlikely((expr) != UACPI_STATUS_OK)
+#define uacpi_likely_error(expr) uacpi_likely((expr) != UACPI_STATUS_OK)
+
+#define uacpi_unlikely_success(expr) uacpi_unlikely((expr) == UACPI_STATUS_OK)
+#define uacpi_likely_success(expr) uacpi_likely((expr) == UACPI_STATUS_OK)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/tables.h b/sys/include/dev/acpi/uacpi/uacpi/tables.h
new file mode 100644
index 0000000..5fbecee
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/tables.h
@@ -0,0 +1,141 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Forward-declared to avoid including the entire acpi.h here
+struct acpi_fadt;
+
+typedef struct uacpi_table_identifiers {
+ uacpi_object_name signature;
+
+ // if oemid[0] == 0 this field is ignored
+ char oemid[6];
+
+ // if oem_table_id[0] == 0 this field is ignored
+ char oem_table_id[8];
+} uacpi_table_identifiers;
+
+typedef struct uacpi_table {
+ union {
+ uacpi_virt_addr virt_addr;
+ void *ptr;
+ struct acpi_sdt_hdr *hdr;
+ };
+
+ // Index number used to identify this table internally
+ uacpi_size index;
+} uacpi_table;
+
+/*
+ * Install a table from either a virtual or a physical address.
+ * The table is simply stored in the internal table array, and not loaded by
+ * the interpreter (see uacpi_table_load).
+ *
+ * The table is optionally returned via 'out_table'.
+ *
+ * Manual calls to uacpi_table_install are not subject to filtering via the
+ * table installation callback (if any).
+ */
+uacpi_status uacpi_table_install(
+ void*, uacpi_table *out_table
+);
+uacpi_status uacpi_table_install_physical(
+ uacpi_phys_addr, uacpi_table *out_table
+);
+
+#ifndef UACPI_BAREBONES_MODE
+/*
+ * Load a previously installed table by feeding it to the interpreter.
+ */
+uacpi_status uacpi_table_load(uacpi_size index);
+#endif // !UACPI_BAREBONES_MODE
+
+/*
+ * Helpers for finding tables.
+ *
+ * for find_by_signature:
+ * 'signature' is an array of 4 characters, a null terminator is not
+ * necessary and can be omitted (especially useful for non-C language
+ * bindings)
+ *
+ * 'out_table' is a pointer to a caller allocated uacpi_table structure that
+ * receives the table pointer & its internal index in case the call was
+ * successful.
+ *
+ * NOTE:
+ * The returned table's reference count is incremented by 1, which keeps its
+ * mapping alive forever unless uacpi_table_unref() is called for this table
+ * later on. Calling uacpi_table_find_next_with_same_signature() on a table also
+ * drops its reference count by 1, so if you want to keep it mapped you must
+ * manually call uacpi_table_ref() beforehand.
+ */
+uacpi_status uacpi_table_find_by_signature(
+ const uacpi_char *signature, uacpi_table *out_table
+);
+uacpi_status uacpi_table_find_next_with_same_signature(
+ uacpi_table *in_out_table
+);
+uacpi_status uacpi_table_find(
+ const uacpi_table_identifiers *id, uacpi_table *out_table
+);
+
+/*
+ * Increment/decrement a table's reference count.
+ * The table is unmapped when the reference count drops to 0.
+ */
+uacpi_status uacpi_table_ref(uacpi_table*);
+uacpi_status uacpi_table_unref(uacpi_table*);
+
+/*
+ * Returns the pointer to a sanitized internal version of FADT.
+ *
+ * The revision is guaranteed to be correct. All of the registers are converted
+ * to GAS format. Fields that might contain garbage are cleared.
+ */
+uacpi_status uacpi_table_fadt(struct acpi_fadt**);
+
+typedef enum uacpi_table_installation_disposition {
+ // Allow the table to be installed as-is
+ UACPI_TABLE_INSTALLATION_DISPOSITON_ALLOW = 0,
+
+ /*
+ * Deny the table from being installed completely. This is useful for
+ * debugging various problems, e.g. AML loading bad SSDTs that cause the
+ * system to hang or enter an undesired state.
+ */
+ UACPI_TABLE_INSTALLATION_DISPOSITON_DENY,
+
+ /*
+ * Override the table being installed with the table at the virtual address
+ * returned in 'out_override_address'.
+ */
+ UACPI_TABLE_INSTALLATION_DISPOSITON_VIRTUAL_OVERRIDE,
+
+ /*
+ * Override the table being installed with the table at the physical address
+ * returned in 'out_override_address'.
+ */
+ UACPI_TABLE_INSTALLATION_DISPOSITON_PHYSICAL_OVERRIDE,
+} uacpi_table_installation_disposition;
+
+typedef uacpi_table_installation_disposition (*uacpi_table_installation_handler)
+ (struct acpi_sdt_hdr *hdr, uacpi_u64 *out_override_address);
+
+/*
+ * Set a handler that is invoked for each table before it gets installed.
+ *
+ * Depending on the return value, the table is either allowed to be installed
+ * as-is, denied, or overriden with a new one.
+ */
+uacpi_status uacpi_set_table_installation_handler(
+ uacpi_table_installation_handler handler
+);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/types.h b/sys/include/dev/acpi/uacpi/uacpi/types.h
new file mode 100644
index 0000000..240cfdc
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/types.h
@@ -0,0 +1,547 @@
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#pragma GCC diagnostic ignored "-Wformat"
+
+#include <uacpi/status.h>
+#include <uacpi/platform/types.h>
+#include <uacpi/platform/compiler.h>
+#include <uacpi/platform/arch_helpers.h>
+#include <uacpi/platform/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if UACPI_POINTER_SIZE == 4 && defined(UACPI_PHYS_ADDR_IS_32BITS)
+typedef uacpi_u32 uacpi_phys_addr;
+typedef uacpi_u32 uacpi_io_addr;
+#else
+typedef uacpi_u64 uacpi_phys_addr;
+typedef uacpi_u64 uacpi_io_addr;
+#endif
+
+typedef void *uacpi_handle;
+
+typedef union uacpi_object_name {
+ uacpi_char text[4];
+ uacpi_u32 id;
+} uacpi_object_name;
+
+typedef enum uacpi_iteration_decision {
+ UACPI_ITERATION_DECISION_CONTINUE = 0,
+ UACPI_ITERATION_DECISION_BREAK,
+
+ // Only applicable for uacpi_namespace_for_each_child
+ UACPI_ITERATION_DECISION_NEXT_PEER,
+} uacpi_iteration_decision;
+
+typedef enum uacpi_address_space {
+ UACPI_ADDRESS_SPACE_SYSTEM_MEMORY = 0,
+ UACPI_ADDRESS_SPACE_SYSTEM_IO = 1,
+ UACPI_ADDRESS_SPACE_PCI_CONFIG = 2,
+ UACPI_ADDRESS_SPACE_EMBEDDED_CONTROLLER = 3,
+ UACPI_ADDRESS_SPACE_SMBUS = 4,
+ UACPI_ADDRESS_SPACE_SYSTEM_CMOS = 5,
+ UACPI_ADDRESS_SPACE_PCI_BAR_TARGET = 6,
+ UACPI_ADDRESS_SPACE_IPMI = 7,
+ UACPI_ADDRESS_SPACE_GENERAL_PURPOSE_IO = 8,
+ UACPI_ADDRESS_SPACE_GENERIC_SERIAL_BUS = 9,
+ UACPI_ADDRESS_SPACE_PCC = 0x0A,
+ UACPI_ADDRESS_SPACE_PRM = 0x0B,
+ UACPI_ADDRESS_SPACE_FFIXEDHW = 0x7F,
+
+ // Internal type
+ UACPI_ADDRESS_SPACE_TABLE_DATA = 0xDA1A,
+} uacpi_address_space;
+const uacpi_char *uacpi_address_space_to_string(uacpi_address_space space);
+
+#ifndef UACPI_BAREBONES_MODE
+
+typedef enum uacpi_init_level {
+ // Reboot state, nothing is available
+ UACPI_INIT_LEVEL_EARLY = 0,
+
+ /*
+ * State after a successfull call to uacpi_initialize. Table API and
+ * other helpers that don't depend on the ACPI namespace may be used.
+ */
+ UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED = 1,
+
+ /*
+ * State after a successfull call to uacpi_namespace_load. Most API may be
+ * used, namespace can be iterated, etc.
+ */
+ UACPI_INIT_LEVEL_NAMESPACE_LOADED = 2,
+
+ /*
+ * The final initialization stage, this is entered after the call to
+ * uacpi_namespace_initialize. All API is available to use.
+ */
+ UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED = 3,
+} uacpi_init_level;
+
+typedef struct uacpi_pci_address {
+ uacpi_u16 segment;
+ uacpi_u8 bus;
+ uacpi_u8 device;
+ uacpi_u8 function;
+} uacpi_pci_address;
+
+typedef struct uacpi_data_view {
+ union {
+ uacpi_u8 *bytes;
+ const uacpi_u8 *const_bytes;
+
+ uacpi_char *text;
+ const uacpi_char *const_text;
+
+ void *data;
+ const void *const_data;
+ };
+ uacpi_size length;
+} uacpi_data_view;
+
+typedef struct uacpi_namespace_node uacpi_namespace_node;
+
+typedef enum uacpi_object_type {
+ UACPI_OBJECT_UNINITIALIZED = 0,
+ UACPI_OBJECT_INTEGER = 1,
+ UACPI_OBJECT_STRING = 2,
+ UACPI_OBJECT_BUFFER = 3,
+ UACPI_OBJECT_PACKAGE = 4,
+ UACPI_OBJECT_FIELD_UNIT = 5,
+ UACPI_OBJECT_DEVICE = 6,
+ UACPI_OBJECT_EVENT = 7,
+ UACPI_OBJECT_METHOD = 8,
+ UACPI_OBJECT_MUTEX = 9,
+ UACPI_OBJECT_OPERATION_REGION = 10,
+ UACPI_OBJECT_POWER_RESOURCE = 11,
+ UACPI_OBJECT_PROCESSOR = 12,
+ UACPI_OBJECT_THERMAL_ZONE = 13,
+ UACPI_OBJECT_BUFFER_FIELD = 14,
+ UACPI_OBJECT_DEBUG = 16,
+
+ UACPI_OBJECT_REFERENCE = 20,
+ UACPI_OBJECT_BUFFER_INDEX = 21,
+ UACPI_OBJECT_MAX_TYPE_VALUE = UACPI_OBJECT_BUFFER_INDEX
+} uacpi_object_type;
+
+// Type bits for API requiring a bit mask, e.g. uacpi_eval_typed
+typedef enum uacpi_object_type_bits {
+ UACPI_OBJECT_INTEGER_BIT = (1 << UACPI_OBJECT_INTEGER),
+ UACPI_OBJECT_STRING_BIT = (1 << UACPI_OBJECT_STRING),
+ UACPI_OBJECT_BUFFER_BIT = (1 << UACPI_OBJECT_BUFFER),
+ UACPI_OBJECT_PACKAGE_BIT = (1 << UACPI_OBJECT_PACKAGE),
+ UACPI_OBJECT_FIELD_UNIT_BIT = (1 << UACPI_OBJECT_FIELD_UNIT),
+ UACPI_OBJECT_DEVICE_BIT = (1 << UACPI_OBJECT_DEVICE),
+ UACPI_OBJECT_EVENT_BIT = (1 << UACPI_OBJECT_EVENT),
+ UACPI_OBJECT_METHOD_BIT = (1 << UACPI_OBJECT_METHOD),
+ UACPI_OBJECT_MUTEX_BIT = (1 << UACPI_OBJECT_MUTEX),
+ UACPI_OBJECT_OPERATION_REGION_BIT = (1 << UACPI_OBJECT_OPERATION_REGION),
+ UACPI_OBJECT_POWER_RESOURCE_BIT = (1 << UACPI_OBJECT_POWER_RESOURCE),
+ UACPI_OBJECT_PROCESSOR_BIT = (1 << UACPI_OBJECT_PROCESSOR),
+ UACPI_OBJECT_THERMAL_ZONE_BIT = (1 << UACPI_OBJECT_THERMAL_ZONE),
+ UACPI_OBJECT_BUFFER_FIELD_BIT = (1 << UACPI_OBJECT_BUFFER_FIELD),
+ UACPI_OBJECT_DEBUG_BIT = (1 << UACPI_OBJECT_DEBUG),
+ UACPI_OBJECT_REFERENCE_BIT = (1 << UACPI_OBJECT_REFERENCE),
+ UACPI_OBJECT_BUFFER_INDEX_BIT = (1 << UACPI_OBJECT_BUFFER_INDEX),
+ UACPI_OBJECT_ANY_BIT = 0xFFFFFFFF,
+} uacpi_object_type_bits;
+
+typedef struct uacpi_object uacpi_object;
+
+void uacpi_object_ref(uacpi_object *obj);
+void uacpi_object_unref(uacpi_object *obj);
+
+uacpi_object_type uacpi_object_get_type(uacpi_object*);
+uacpi_object_type_bits uacpi_object_get_type_bit(uacpi_object*);
+
+/*
+ * Returns UACPI_TRUE if the provided object's type matches this type.
+ */
+uacpi_bool uacpi_object_is(uacpi_object*, uacpi_object_type);
+
+/*
+ * Returns UACPI_TRUE if the provided object's type is one of the values
+ * specified in the 'type_mask' of UACPI_OBJECT_*_BIT.
+ */
+uacpi_bool uacpi_object_is_one_of(
+ uacpi_object*, uacpi_object_type_bits type_mask
+);
+
+const uacpi_char *uacpi_object_type_to_string(uacpi_object_type);
+
+/*
+ * Create an uninitialized object. The object can be further overwritten via
+ * uacpi_object_assign_* to anything.
+ */
+uacpi_object *uacpi_object_create_uninitialized(void);
+
+/*
+ * Create an integer object with the value provided.
+ */
+uacpi_object *uacpi_object_create_integer(uacpi_u64);
+
+typedef enum uacpi_overflow_behavior {
+ UACPI_OVERFLOW_ALLOW = 0,
+ UACPI_OVERFLOW_TRUNCATE,
+ UACPI_OVERFLOW_DISALLOW,
+} uacpi_overflow_behavior;
+
+/*
+ * Same as uacpi_object_create_integer, but introduces additional ways to
+ * control what happens if the provided integer is larger than 32-bits, and the
+ * AML code expects 32-bit integers.
+ *
+ * - UACPI_OVERFLOW_ALLOW -> do nothing, same as the vanilla helper
+ * - UACPI_OVERFLOW_TRUNCATE -> truncate the integer to 32-bits if it happens to
+ * be larger than allowed by the DSDT
+ * - UACPI_OVERFLOW_DISALLOW -> fail object creation with
+ * UACPI_STATUS_INVALID_ARGUMENT if the provided
+ * value happens to be too large
+ */
+uacpi_status uacpi_object_create_integer_safe(
+ uacpi_u64, uacpi_overflow_behavior, uacpi_object **out_obj
+);
+
+uacpi_status uacpi_object_assign_integer(uacpi_object*, uacpi_u64 value);
+uacpi_status uacpi_object_get_integer(uacpi_object*, uacpi_u64 *out);
+
+/*
+ * Create a string/buffer object. Takes in a constant view of the data.
+ *
+ * NOTE: The data is copied to a separately allocated buffer and is not taken
+ * ownership of.
+ */
+uacpi_object *uacpi_object_create_string(uacpi_data_view);
+uacpi_object *uacpi_object_create_cstring(const uacpi_char*);
+uacpi_object *uacpi_object_create_buffer(uacpi_data_view);
+
+/*
+ * Returns a writable view of the data stored in the string or buffer type
+ * object.
+ */
+uacpi_status uacpi_object_get_string_or_buffer(
+ uacpi_object*, uacpi_data_view *out
+);
+uacpi_status uacpi_object_get_string(uacpi_object*, uacpi_data_view *out);
+uacpi_status uacpi_object_get_buffer(uacpi_object*, uacpi_data_view *out);
+
+/*
+ * Returns UACPI_TRUE if the provided string object is actually an AML namepath.
+ *
+ * This can only be the case for package elements. If a package element is
+ * specified as a path to an object in AML, it's not resolved by the interpreter
+ * right away as it might not have been defined at that point yet, and is
+ * instead stored as a special string object to be resolved by client code
+ * when needed.
+ *
+ * Example usage:
+ * uacpi_namespace_node *target_node = UACPI_NULL;
+ *
+ * uacpi_object *obj = UACPI_NULL;
+ * uacpi_eval(scope, path, UACPI_NULL, &obj);
+ *
+ * uacpi_object_array arr;
+ * uacpi_object_get_package(obj, &arr);
+ *
+ * if (uacpi_object_is_aml_namepath(arr.objects[0])) {
+ * uacpi_object_resolve_as_aml_namepath(
+ * arr.objects[0], scope, &target_node
+ * );
+ * }
+ */
+uacpi_bool uacpi_object_is_aml_namepath(uacpi_object*);
+
+/*
+ * Resolve an AML namepath contained in a string object.
+ *
+ * This is only applicable to objects that are package elements. See an
+ * explanation of how this works in the comment above the declaration of
+ * uacpi_object_is_aml_namepath.
+ *
+ * This is a shorthand for:
+ * uacpi_data_view view;
+ * uacpi_object_get_string(object, &view);
+ *
+ * target_node = uacpi_namespace_node_resolve_from_aml_namepath(
+ * scope, view.text
+ * );
+ */
+uacpi_status uacpi_object_resolve_as_aml_namepath(
+ uacpi_object*, uacpi_namespace_node *scope, uacpi_namespace_node **out_node
+);
+
+/*
+ * Make the provided object a string/buffer.
+ * Takes in a constant view of the data to be stored in the object.
+ *
+ * NOTE: The data is copied to a separately allocated buffer and is not taken
+ * ownership of.
+ */
+uacpi_status uacpi_object_assign_string(uacpi_object*, uacpi_data_view in);
+uacpi_status uacpi_object_assign_buffer(uacpi_object*, uacpi_data_view in);
+
+typedef struct uacpi_object_array {
+ uacpi_object **objects;
+ uacpi_size count;
+} uacpi_object_array;
+
+/*
+ * Create a package object and store all of the objects in the array inside.
+ * The array is allowed to be empty.
+ *
+ * NOTE: the reference count of each object is incremented before being stored
+ * in the object. Client code must remove all of the locally created
+ * references at its own discretion.
+ */
+uacpi_object *uacpi_object_create_package(uacpi_object_array in);
+
+/*
+ * Returns the list of objects stored in a package object.
+ *
+ * NOTE: the reference count of the objects stored inside is not incremented,
+ * which means destorying/overwriting the object also potentially destroys
+ * all of the objects stored inside unless the reference count is
+ * incremented by the client via uacpi_object_ref.
+ */
+uacpi_status uacpi_object_get_package(uacpi_object*, uacpi_object_array *out);
+
+/*
+ * Make the provided object a package and store all of the objects in the array
+ * inside. The array is allowed to be empty.
+ *
+ * NOTE: the reference count of each object is incremented before being stored
+ * in the object. Client code must remove all of the locally created
+ * references at its own discretion.
+ */
+uacpi_status uacpi_object_assign_package(uacpi_object*, uacpi_object_array in);
+
+/*
+ * Create a reference object and make it point to 'child'.
+ *
+ * NOTE: child's reference count is incremented by one. Client code must remove
+ * all of the locally created references at its own discretion.
+ */
+uacpi_object *uacpi_object_create_reference(uacpi_object *child);
+
+/*
+ * Make the provided object a reference and make it point to 'child'.
+ *
+ * NOTE: child's reference count is incremented by one. Client code must remove
+ * all of the locally created references at its own discretion.
+ */
+uacpi_status uacpi_object_assign_reference(uacpi_object*, uacpi_object *child);
+
+/*
+ * Retrieve the object pointed to by a reference object.
+ *
+ * NOTE: the reference count of the returned object is incremented by one and
+ * must be uacpi_object_unref'ed by the client when no longer needed.
+ */
+uacpi_status uacpi_object_get_dereferenced(uacpi_object*, uacpi_object **out);
+
+typedef struct uacpi_processor_info {
+ uacpi_u8 id;
+ uacpi_u32 block_address;
+ uacpi_u8 block_length;
+} uacpi_processor_info;
+
+/*
+ * Returns the information about the provided processor object.
+ */
+uacpi_status uacpi_object_get_processor_info(
+ uacpi_object*, uacpi_processor_info *out
+);
+
+typedef struct uacpi_power_resource_info {
+ uacpi_u8 system_level;
+ uacpi_u16 resource_order;
+} uacpi_power_resource_info;
+
+/*
+ * Returns the information about the provided power resource object.
+ */
+uacpi_status uacpi_object_get_power_resource_info(
+ uacpi_object*, uacpi_power_resource_info *out
+);
+
+typedef enum uacpi_region_op {
+ // data => uacpi_region_attach_data
+ UACPI_REGION_OP_ATTACH = 0,
+ // data => uacpi_region_detach_data
+ UACPI_REGION_OP_DETACH,
+
+ // data => uacpi_region_rw_data
+ UACPI_REGION_OP_READ,
+ UACPI_REGION_OP_WRITE,
+
+ // data => uacpi_region_pcc_send_data
+ UACPI_REGION_OP_PCC_SEND,
+
+ // data => uacpi_region_gpio_rw_data
+ UACPI_REGION_OP_GPIO_READ,
+ UACPI_REGION_OP_GPIO_WRITE,
+
+ // data => uacpi_region_ipmi_rw_data
+ UACPI_REGION_OP_IPMI_COMMAND,
+
+ // data => uacpi_region_ffixedhw_rw_data
+ UACPI_REGION_OP_FFIXEDHW_COMMAND,
+
+ // data => uacpi_region_prm_rw_data
+ UACPI_REGION_OP_PRM_COMMAND,
+
+ // data => uacpi_region_serial_rw_data
+ UACPI_REGION_OP_SERIAL_READ,
+ UACPI_REGION_OP_SERIAL_WRITE,
+} uacpi_region_op;
+
+typedef struct uacpi_generic_region_info {
+ uacpi_u64 base;
+ uacpi_u64 length;
+} uacpi_generic_region_info;
+
+typedef struct uacpi_pcc_region_info {
+ uacpi_data_view buffer;
+ uacpi_u8 subspace_id;
+} uacpi_pcc_region_info;
+
+typedef struct uacpi_gpio_region_info
+{
+ uacpi_u64 num_pins;
+} uacpi_gpio_region_info;
+
+typedef struct uacpi_region_attach_data {
+ void *handler_context;
+ uacpi_namespace_node *region_node;
+ union {
+ uacpi_generic_region_info generic_info;
+ uacpi_pcc_region_info pcc_info;
+ uacpi_gpio_region_info gpio_info;
+ };
+ void *out_region_context;
+} uacpi_region_attach_data;
+
+typedef struct uacpi_region_rw_data {
+ void *handler_context;
+ void *region_context;
+ union {
+ uacpi_phys_addr address;
+ uacpi_u64 offset;
+ };
+ uacpi_u64 value;
+ uacpi_u8 byte_width;
+} uacpi_region_rw_data;
+
+typedef struct uacpi_region_pcc_send_data {
+ void *handler_context;
+ void *region_context;
+ uacpi_data_view buffer;
+} uacpi_region_pcc_send_data;
+
+typedef struct uacpi_region_gpio_rw_data
+{
+ void *handler_context;
+ void *region_context;
+ uacpi_data_view connection;
+ uacpi_u32 pin_offset;
+ uacpi_u32 num_pins;
+ uacpi_u64 value;
+} uacpi_region_gpio_rw_data;
+
+typedef struct uacpi_region_ipmi_rw_data
+{
+ void *handler_context;
+ void *region_context;
+ uacpi_data_view in_out_message;
+ uacpi_u64 command;
+} uacpi_region_ipmi_rw_data;
+
+typedef uacpi_region_ipmi_rw_data uacpi_region_ffixedhw_rw_data;
+
+typedef struct uacpi_region_prm_rw_data
+{
+ void *handler_context;
+ void *region_context;
+ uacpi_data_view in_out_message;
+} uacpi_region_prm_rw_data;
+
+typedef enum uacpi_access_attribute {
+ UACPI_ACCESS_ATTRIBUTE_QUICK = 0x02,
+ UACPI_ACCESS_ATTRIBUTE_SEND_RECEIVE = 0x04,
+ UACPI_ACCESS_ATTRIBUTE_BYTE = 0x06,
+ UACPI_ACCESS_ATTRIBUTE_WORD = 0x08,
+ UACPI_ACCESS_ATTRIBUTE_BLOCK = 0x0A,
+ UACPI_ACCESS_ATTRIBUTE_BYTES = 0x0B,
+ UACPI_ACCESS_ATTRIBUTE_PROCESS_CALL = 0x0C,
+ UACPI_ACCESS_ATTRIBUTE_BLOCK_PROCESS_CALL = 0x0D,
+ UACPI_ACCESS_ATTRIBUTE_RAW_BYTES = 0x0E,
+ UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES = 0x0F,
+} uacpi_access_attribute;
+
+typedef struct uacpi_region_serial_rw_data {
+ void *handler_context;
+ void *region_context;
+ uacpi_u64 command;
+ uacpi_data_view connection;
+ uacpi_data_view in_out_buffer;
+ uacpi_access_attribute access_attribute;
+
+ /*
+ * Applicable if access_attribute is one of:
+ * - UACPI_ACCESS_ATTRIBUTE_BYTES
+ * - UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
+ * - UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
+ */
+ uacpi_u8 access_length;
+} uacpi_region_serial_rw_data;
+
+typedef struct uacpi_region_detach_data {
+ void *handler_context;
+ void *region_context;
+ uacpi_namespace_node *region_node;
+} uacpi_region_detach_data;
+
+typedef uacpi_status (*uacpi_region_handler)
+ (uacpi_region_op op, uacpi_handle op_data);
+
+typedef uacpi_status (*uacpi_notify_handler)
+ (uacpi_handle context, uacpi_namespace_node *node, uacpi_u64 value);
+
+typedef enum uacpi_firmware_request_type {
+ UACPI_FIRMWARE_REQUEST_TYPE_BREAKPOINT,
+ UACPI_FIRMWARE_REQUEST_TYPE_FATAL,
+} uacpi_firmware_request_type;
+
+typedef struct uacpi_firmware_request {
+ uacpi_u8 type;
+
+ union {
+ // UACPI_FIRMWARE_REQUEST_BREAKPOINT
+ struct {
+ // The context of the method currently being executed
+ uacpi_handle ctx;
+ } breakpoint;
+
+ // UACPI_FIRMWARE_REQUEST_FATAL
+ struct {
+ uacpi_u8 type;
+ uacpi_u32 code;
+ uacpi_u64 arg;
+ } fatal;
+ };
+} uacpi_firmware_request;
+
+#define UACPI_INTERRUPT_NOT_HANDLED 0
+#define UACPI_INTERRUPT_HANDLED 1
+typedef uacpi_u32 uacpi_interrupt_ret;
+
+typedef uacpi_interrupt_ret (*uacpi_interrupt_handler)(uacpi_handle);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/uacpi.h b/sys/include/dev/acpi/uacpi/uacpi/uacpi.h
new file mode 100644
index 0000000..a37836c
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/uacpi.h
@@ -0,0 +1,269 @@
+#pragma once
+
+#include <uacpi/types.h>
+#include <uacpi/status.h>
+#include <uacpi/kernel_api.h>
+#include <uacpi/namespace.h>
+
+#define UACPI_MAJOR 2
+#define UACPI_MINOR 1
+#define UACPI_PATCH 1
+
+#ifdef UACPI_REDUCED_HARDWARE
+#define UACPI_MAKE_STUB_FOR_REDUCED_HARDWARE(fn, ret) \
+ UACPI_NO_UNUSED_PARAMETER_WARNINGS_BEGIN \
+ static inline fn { return ret; } \
+ UACPI_NO_UNUSED_PARAMETER_WARNINGS_END
+
+#define UACPI_STUB_IF_REDUCED_HARDWARE(fn) \
+ UACPI_MAKE_STUB_FOR_REDUCED_HARDWARE(fn,)
+#define UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(fn) \
+ UACPI_MAKE_STUB_FOR_REDUCED_HARDWARE(fn, UACPI_STATUS_COMPILED_OUT)
+#define UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(fn) \
+ UACPI_MAKE_STUB_FOR_REDUCED_HARDWARE(fn, UACPI_STATUS_OK)
+#else
+
+#define UACPI_STUB_IF_REDUCED_HARDWARE(fn) fn;
+#define UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(fn) fn;
+#define UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(fn) fn;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Set up early access to the table subsystem. What this means is:
+ * - uacpi_table_find() and similar API becomes usable before the call to
+ * uacpi_initialize().
+ * - No kernel API besides logging and map/unmap will be invoked at this stage,
+ * allowing for heap and scheduling to still be fully offline.
+ * - The provided 'temporary_buffer' will be used as a temporary storage for the
+ * internal metadata about the tables (list, reference count, addresses,
+ * sizes, etc).
+ * - The 'temporary_buffer' is replaced with a normal heap buffer allocated via
+ * uacpi_kernel_alloc() after the call to uacpi_initialize() and can therefore
+ * be reclaimed by the kernel.
+ *
+ * The approximate overhead per table is 56 bytes, so a buffer of 4096 bytes
+ * yields about 73 tables in terms of capacity. uACPI also has an internal
+ * static buffer for tables, "UACPI_STATIC_TABLE_ARRAY_LEN", which is configured
+ * as 16 descriptors in length by default.
+ *
+ * This function is used to initialize the barebones mode, see
+ * UACPI_BAREBONES_MODE in config.h for more information.
+ */
+uacpi_status uacpi_setup_early_table_access(
+ void *temporary_buffer, uacpi_size buffer_size
+);
+
+/*
+ * Bad table checksum should be considered a fatal error
+ * (table load is fully aborted in this case)
+ */
+#define UACPI_FLAG_BAD_CSUM_FATAL (1ull << 0)
+
+/*
+ * Unexpected table signature should be considered a fatal error
+ * (table load is fully aborted in this case)
+ */
+#define UACPI_FLAG_BAD_TBL_SIGNATURE_FATAL (1ull << 1)
+
+/*
+ * Force uACPI to use RSDT even for later revisions
+ */
+#define UACPI_FLAG_BAD_XSDT (1ull << 2)
+
+/*
+ * If this is set, ACPI mode is not entered during the call to
+ * uacpi_initialize. The caller is expected to enter it later at their own
+ * discretion by using uacpi_enter_acpi_mode().
+ */
+#define UACPI_FLAG_NO_ACPI_MODE (1ull << 3)
+
+/*
+ * Don't create the \_OSI method when building the namespace.
+ * Only enable this if you're certain that having this method breaks your AML
+ * blob, a more atomic/granular interface management is available via osi.h
+ */
+#define UACPI_FLAG_NO_OSI (1ull << 4)
+
+/*
+ * Validate table checksums at installation time instead of first use.
+ * Note that this makes uACPI map the entire table at once, which not all
+ * hosts are able to handle at early init.
+ */
+#define UACPI_FLAG_PROACTIVE_TBL_CSUM (1ull << 5)
+
+#ifndef UACPI_BAREBONES_MODE
+
+/*
+ * Initializes the uACPI subsystem, iterates & records all relevant RSDT/XSDT
+ * tables. Enters ACPI mode.
+ *
+ * 'flags' is any combination of UACPI_FLAG_* above
+ */
+uacpi_status uacpi_initialize(uacpi_u64 flags);
+
+/*
+ * Parses & executes all of the DSDT/SSDT tables.
+ * Initializes the event subsystem.
+ */
+uacpi_status uacpi_namespace_load(void);
+
+/*
+ * Initializes all the necessary objects in the namespaces by calling
+ * _STA/_INI etc.
+ */
+uacpi_status uacpi_namespace_initialize(void);
+
+// Returns the current subsystem initialization level
+uacpi_init_level uacpi_get_current_init_level(void);
+
+/*
+ * Evaluate an object within the namespace and get back its value.
+ * Either root or path must be valid.
+ * A value of NULL for 'parent' implies uacpi_namespace_root() relative
+ * lookups, unless 'path' is already absolute.
+ */
+uacpi_status uacpi_eval(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_object **ret
+);
+uacpi_status uacpi_eval_simple(
+ uacpi_namespace_node *parent, const uacpi_char *path, uacpi_object **ret
+);
+
+/*
+ * Same as uacpi_eval() but without a return value.
+ */
+uacpi_status uacpi_execute(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args
+);
+uacpi_status uacpi_execute_simple(
+ uacpi_namespace_node *parent, const uacpi_char *path
+);
+
+/*
+ * Same as uacpi_eval, but the return value type is validated against
+ * the 'ret_mask'. UACPI_STATUS_TYPE_MISMATCH is returned on error.
+ */
+uacpi_status uacpi_eval_typed(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_object_type_bits ret_mask,
+ uacpi_object **ret
+);
+uacpi_status uacpi_eval_simple_typed(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ uacpi_object_type_bits ret_mask, uacpi_object **ret
+);
+
+/*
+ * A shorthand for uacpi_eval_typed with UACPI_OBJECT_INTEGER_BIT.
+ */
+uacpi_status uacpi_eval_integer(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_u64 *out_value
+);
+uacpi_status uacpi_eval_simple_integer(
+ uacpi_namespace_node *parent, const uacpi_char *path, uacpi_u64 *out_value
+);
+
+/*
+ * A shorthand for uacpi_eval_typed with
+ * UACPI_OBJECT_BUFFER_BIT | UACPI_OBJECT_STRING_BIT
+ *
+ * Use uacpi_object_get_string_or_buffer to retrieve the resulting buffer data.
+ */
+uacpi_status uacpi_eval_buffer_or_string(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_object **ret
+);
+uacpi_status uacpi_eval_simple_buffer_or_string(
+ uacpi_namespace_node *parent, const uacpi_char *path, uacpi_object **ret
+);
+
+/*
+ * A shorthand for uacpi_eval_typed with UACPI_OBJECT_STRING_BIT.
+ *
+ * Use uacpi_object_get_string to retrieve the resulting buffer data.
+ */
+uacpi_status uacpi_eval_string(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_object **ret
+);
+uacpi_status uacpi_eval_simple_string(
+ uacpi_namespace_node *parent, const uacpi_char *path, uacpi_object **ret
+);
+
+/*
+ * A shorthand for uacpi_eval_typed with UACPI_OBJECT_BUFFER_BIT.
+ *
+ * Use uacpi_object_get_buffer to retrieve the resulting buffer data.
+ */
+uacpi_status uacpi_eval_buffer(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_object **ret
+);
+uacpi_status uacpi_eval_simple_buffer(
+ uacpi_namespace_node *parent, const uacpi_char *path, uacpi_object **ret
+);
+
+/*
+ * A shorthand for uacpi_eval_typed with UACPI_OBJECT_PACKAGE_BIT.
+ *
+ * Use uacpi_object_get_package to retrieve the resulting object array.
+ */
+uacpi_status uacpi_eval_package(
+ uacpi_namespace_node *parent, const uacpi_char *path,
+ const uacpi_object_array *args, uacpi_object **ret
+);
+uacpi_status uacpi_eval_simple_package(
+ uacpi_namespace_node *parent, const uacpi_char *path, uacpi_object **ret
+);
+
+/*
+ * Get the bitness of the currently loaded AML code according to the DSDT.
+ *
+ * Returns either 32 or 64.
+ */
+uacpi_status uacpi_get_aml_bitness(uacpi_u8 *out_bitness);
+
+/*
+ * Helpers for entering & leaving ACPI mode. Note that ACPI mode is entered
+ * automatically during the call to uacpi_initialize().
+ */
+UACPI_ALWAYS_OK_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_enter_acpi_mode(void)
+)
+UACPI_ALWAYS_ERROR_FOR_REDUCED_HARDWARE(
+ uacpi_status uacpi_leave_acpi_mode(void)
+)
+
+/*
+ * Attempt to acquire the global lock for 'timeout' milliseconds.
+ * 0xFFFF implies infinite wait.
+ *
+ * On success, 'out_seq' is set to a unique sequence number for the current
+ * acquire transaction. This number is used for validation during release.
+ */
+uacpi_status uacpi_acquire_global_lock(uacpi_u16 timeout, uacpi_u32 *out_seq);
+uacpi_status uacpi_release_global_lock(uacpi_u32 seq);
+
+#endif // !UACPI_BAREBONES_MODE
+
+/*
+ * Reset the global uACPI state by freeing all internally allocated data
+ * structures & resetting any global variables. After this call, uACPI must be
+ * re-initialized from scratch to be used again.
+ *
+ * This is called by uACPI automatically if a fatal error occurs during a call
+ * to uacpi_initialize/uacpi_namespace_load etc. in order to prevent accidental
+ * use of partially uninitialized subsystems.
+ */
+void uacpi_state_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/acpi/uacpi/uacpi/utilities.h b/sys/include/dev/acpi/uacpi/uacpi/utilities.h
new file mode 100644
index 0000000..dfc41c3
--- /dev/null
+++ b/sys/include/dev/acpi/uacpi/uacpi/utilities.h
@@ -0,0 +1,188 @@
+#pragma once
+
+#include <uacpi/status.h>
+#include <uacpi/types.h>
+#include <uacpi/namespace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UACPI_BAREBONES_MODE
+
+/*
+ * Checks whether the device at 'node' matches any of the PNP ids provided in
+ * 'list' (terminated by a UACPI_NULL). This is done by first attempting to
+ * match the value returned from _HID and then the value(s) from _CID.
+ *
+ * Note that the presence of the device (_STA) is not verified here.
+ */
+uacpi_bool uacpi_device_matches_pnp_id(
+ uacpi_namespace_node *node,
+ const uacpi_char *const *list
+);
+
+/*
+ * Find all the devices in the namespace starting at 'parent' matching the
+ * specified 'hids' (terminated by a UACPI_NULL) against any value from _HID or
+ * _CID. Only devices reported as present via _STA are checked. Any matching
+ * devices are then passed to the 'cb'.
+ */
+uacpi_status uacpi_find_devices_at(
+ uacpi_namespace_node *parent,
+ const uacpi_char *const *hids,
+ uacpi_iteration_callback cb,
+ void *user
+);
+
+/*
+ * Same as uacpi_find_devices_at, except this starts at the root and only
+ * matches one hid.
+ */
+uacpi_status uacpi_find_devices(
+ const uacpi_char *hid,
+ uacpi_iteration_callback cb,
+ void *user
+);
+
+typedef enum uacpi_interrupt_model {
+ UACPI_INTERRUPT_MODEL_PIC = 0,
+ UACPI_INTERRUPT_MODEL_IOAPIC = 1,
+ UACPI_INTERRUPT_MODEL_IOSAPIC = 2,
+} uacpi_interrupt_model;
+
+uacpi_status uacpi_set_interrupt_model(uacpi_interrupt_model);
+
+typedef struct uacpi_pci_routing_table_entry {
+ uacpi_u32 address;
+ uacpi_u32 index;
+ uacpi_namespace_node *source;
+ uacpi_u8 pin;
+} uacpi_pci_routing_table_entry;
+
+typedef struct uacpi_pci_routing_table {
+ uacpi_size num_entries;
+ uacpi_pci_routing_table_entry entries[];
+} uacpi_pci_routing_table;
+void uacpi_free_pci_routing_table(uacpi_pci_routing_table*);
+
+uacpi_status uacpi_get_pci_routing_table(
+ uacpi_namespace_node *parent, uacpi_pci_routing_table **out_table
+);
+
+typedef struct uacpi_id_string {
+ // size of the string including the null byte
+ uacpi_u32 size;
+ uacpi_char *value;
+} uacpi_id_string;
+void uacpi_free_id_string(uacpi_id_string *id);
+
+/*
+ * Evaluate a device's _HID method and get its value.
+ * The returned struture must be freed using uacpi_free_id_string.
+ */
+uacpi_status uacpi_eval_hid(uacpi_namespace_node*, uacpi_id_string **out_id);
+
+typedef struct uacpi_pnp_id_list {
+ // number of 'ids' in the list
+ uacpi_u32 num_ids;
+
+ // size of the 'ids' list including the string lengths
+ uacpi_u32 size;
+
+ // list of PNP ids
+ uacpi_id_string ids[];
+} uacpi_pnp_id_list;
+void uacpi_free_pnp_id_list(uacpi_pnp_id_list *list);
+
+/*
+ * Evaluate a device's _CID method and get its value.
+ * The returned structure must be freed using uacpi_free_pnp_id_list.
+ */
+uacpi_status uacpi_eval_cid(uacpi_namespace_node*, uacpi_pnp_id_list **out_list);
+
+/*
+ * Evaluate a device's _STA method and get its value.
+ * If this method is not found, the value of 'flags' is set to all ones.
+ */
+uacpi_status uacpi_eval_sta(uacpi_namespace_node*, uacpi_u32 *flags);
+
+/*
+ * Evaluate a device's _ADR method and get its value.
+ */
+uacpi_status uacpi_eval_adr(uacpi_namespace_node*, uacpi_u64 *out);
+
+/*
+ * Evaluate a device's _CLS method and get its value.
+ * The format of returned string is BBSSPP where:
+ * BB => Base Class (e.g. 01 => Mass Storage)
+ * SS => Sub-Class (e.g. 06 => SATA)
+ * PP => Programming Interface (e.g. 01 => AHCI)
+ * The returned struture must be freed using uacpi_free_id_string.
+ */
+uacpi_status uacpi_eval_cls(uacpi_namespace_node*, uacpi_id_string **out_id);
+
+/*
+ * Evaluate a device's _UID method and get its value.
+ * The returned struture must be freed using uacpi_free_id_string.
+ */
+uacpi_status uacpi_eval_uid(uacpi_namespace_node*, uacpi_id_string **out_uid);
+
+
+// uacpi_namespace_node_info->flags
+#define UACPI_NS_NODE_INFO_HAS_ADR (1 << 0)
+#define UACPI_NS_NODE_INFO_HAS_HID (1 << 1)
+#define UACPI_NS_NODE_INFO_HAS_UID (1 << 2)
+#define UACPI_NS_NODE_INFO_HAS_CID (1 << 3)
+#define UACPI_NS_NODE_INFO_HAS_CLS (1 << 4)
+#define UACPI_NS_NODE_INFO_HAS_SXD (1 << 5)
+#define UACPI_NS_NODE_INFO_HAS_SXW (1 << 6)
+
+typedef struct uacpi_namespace_node_info {
+ // Size of the entire structure
+ uacpi_u32 size;
+
+ // Object information
+ uacpi_object_name name;
+ uacpi_object_type type;
+ uacpi_u8 num_params;
+
+ // UACPI_NS_NODE_INFO_HAS_*
+ uacpi_u8 flags;
+
+ /*
+ * A mapping of [S1..S4] to the shallowest D state supported by the device
+ * in that S state.
+ */
+ uacpi_u8 sxd[4];
+
+ /*
+ * A mapping of [S0..S4] to the deepest D state supported by the device
+ * in that S state to be able to wake itself.
+ */
+ uacpi_u8 sxw[5];
+
+ uacpi_u64 adr;
+ uacpi_id_string hid;
+ uacpi_id_string uid;
+ uacpi_id_string cls;
+ uacpi_pnp_id_list cid;
+} uacpi_namespace_node_info;
+void uacpi_free_namespace_node_info(uacpi_namespace_node_info*);
+
+/*
+ * Retrieve information about a namespace node. This includes the attached
+ * object's type, name, number of parameters (if it's a method), the result of
+ * evaluating _ADR, _UID, _CLS, _HID, _CID, as well as _SxD and _SxW.
+ *
+ * The returned structure must be freed with uacpi_free_namespace_node_info.
+ */
+uacpi_status uacpi_get_namespace_node_info(
+ uacpi_namespace_node *node, uacpi_namespace_node_info **out_info
+);
+
+#endif // !UACPI_BAREBONES_MODE
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sys/include/dev/cons/ansi.h b/sys/include/dev/cons/ansi.h
new file mode 100644
index 0000000..7a336d1
--- /dev/null
+++ b/sys/include/dev/cons/ansi.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CONS_ANSI_H_
+#define _CONS_ANSI_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+/* ANSI colors */
+#define ANSI_BLACK 0x000000
+#define ANSI_RED 0xAA0000
+#define ANSI_GREEN 0x00AA00
+#define ANSI_BLUE 0x00007F
+#define ANSI_YELLOW 0xAA5500
+#define ANSI_MAGENTA 0xAA00AA
+#define ANSI_CYAN 0x00AAAA
+#define ANSI_WHITE 0xAAAAAA
+
+/* ANSI_FEED update codes */
+#define ANSI_UPDATE_COLOR -1
+#define ANSI_UPDATE_CURSOR -2
+
+/*
+ * ANSI parser state machine.
+ *
+ * @prev: Previous char
+ * @csi: Encountered control seq introducer
+ * @reset_color: 1 if color is to be reset
+ * @set_fg: 1 if fg is being set
+ * @set_bg: 1 if bg is being set
+ * @fg: Foreground color
+ * @bg: Background color
+ * @flags: State flags
+ */
+struct ansi_state {
+ char prev;
+ uint8_t csi : 2;
+ uint8_t reset_color : 1;
+ uint8_t set_fg : 1;
+ uint8_t set_bg : 1;
+ uint32_t fg;
+ uint32_t bg;
+};
+
+int ansi_feed(struct ansi_state *statep, char c);
+
+#endif /* !_CONS_ANSI_H_ */
diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h
index 8e2c2c6..7599dd5 100644
--- a/sys/include/dev/cons/cons.h
+++ b/sys/include/dev/cons/cons.h
@@ -33,15 +33,20 @@
#include <sys/types.h>
#include <sys/spinlock.h>
#include <dev/video/fbdev.h>
+#include <dev/cons/consvar.h>
+#include <dev/cons/ansi.h>
struct cons_char {
char c;
uint32_t fg;
uint32_t bg;
+ uint32_t x;
+ uint32_t y;
};
struct cons_screen {
struct fbdev fbdev;
+ struct ansi_state ansi_s;
uint32_t fg;
uint32_t bg;
@@ -53,13 +58,20 @@ struct cons_screen {
uint32_t ch_row; /* Current row */
uint32_t curs_col; /* Cursor col */
uint32_t curs_row; /* Cursor row */
+ struct cons_buf *ib; /* Input buffer */
+ struct cons_buf **ob; /* Output buffers */
struct cons_char last_chr;
struct spinlock lock;
};
void cons_init(void);
void cons_expose(void);
+void cons_update_color(struct cons_screen *scr, uint32_t fg, uint32_t bg);
+void cons_clear_scr(struct cons_screen *scr, uint32_t bg);
+void cons_reset_color(struct cons_screen *scr);
+void cons_reset_cursor(struct cons_screen *scr);
int cons_putch(struct cons_screen *scr, char c);
+int cons_putstr(struct cons_screen *scr, const char *s, size_t len);
extern struct cons_screen g_root_scr;
diff --git a/sys/include/dev/cons/consvar.h b/sys/include/dev/cons/consvar.h
new file mode 100644
index 0000000..253176b
--- /dev/null
+++ b/sys/include/dev/cons/consvar.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_CONSVAR_H_
+#define _DEV_CONSVAR_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/spinlock.h>
+
+/* Buffer types */
+#define CONS_BUF_INPUT 0
+#define CONS_BUF_OUTPUT 1
+
+/* Buffer flags */
+#define CONS_BUF_CLEAN BIT(0) /* Not recently written to */
+
+extern struct cons_screen scr;
+
+/*
+ * The keyboard packet is two bytes
+ * and the bits are as follows:
+ *
+ * - 0:7 ~ ASCII character
+ * - 8:15 ~ Scancode
+ */
+struct cons_input {
+ union {
+ uint8_t chr;
+ uint8_t scancode;
+ };
+ uint16_t data;
+};
+
+/*
+ * A circular buffer for buffering
+ * keyboard input or console output.
+ */
+struct cons_buf {
+ struct spinlock lock;
+ union {
+ struct cons_input *ibuf;
+ struct cons_char *obuf;
+ void *raw;
+ };
+ uint8_t tail;
+ uint8_t head;
+ uint8_t type;
+ uint8_t flags;
+ size_t len;
+};
+
+struct cons_buf *cons_new_buf(uint8_t type, size_t len);
+int cons_obuf_push(struct cons_buf *bp, struct cons_char c);
+int cons_obuf_pop(struct cons_buf *bp, struct cons_char *res);
+
+int cons_ibuf_push(struct cons_screen *scr, struct cons_input input);
+int cons_ibuf_pop(struct cons_screen *scr, struct cons_input *res);
+
+#endif /* !_DEV_CONSVAR_H_ */
diff --git a/sys/include/dev/dmi/dmi.h b/sys/include/dev/dmi/dmi.h
new file mode 100644
index 0000000..d24397a
--- /dev/null
+++ b/sys/include/dev/dmi/dmi.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DMI_DMI_H_
+#define _DMI_DMI_H_
+
+#include <sys/types.h>
+
+const char *dmi_vendor(void);
+const char *dmi_prodver(void);
+const char *dmi_product(void);
+const char *dmi_cpu_manufact(void);
+
+#endif /* !_DMI_DMI_H_ */
diff --git a/sys/include/dev/ic/ahciregs.h b/sys/include/dev/ic/ahciregs.h
index 4a4dc65..232b41e 100644
--- a/sys/include/dev/ic/ahciregs.h
+++ b/sys/include/dev/ic/ahciregs.h
@@ -34,8 +34,10 @@
#include <sys/param.h>
struct hba_port {
- volatile uint64_t clb; /* Command list base (1k-byte aligned) */
- volatile uint64_t fb; /* FIS base (256-byte aligned) */
+ volatile uint32_t clb; /* Command list base low (1k-byte aligned) */
+ volatile uint32_t clbu; /* Command list base upper */
+ volatile uint32_t fb; /* FIS base (256-byte aligned) */
+ volatile uint32_t fbu; /* FIS base upper */
volatile uint32_t is; /* Interrupt status */
volatile uint32_t ie; /* Interrupt enable */
volatile uint32_t cmd; /* Command and status */
@@ -86,6 +88,7 @@ struct hba_memspace {
*/
#define AHCI_PXSSTS_DET(SSTS) (SSTS & 0xF)
#define AHCI_PXSSTS_IPM(SSTS) ((SSTS >> 8) & 0xF)
+#define AHCI_PXSSTS_SPD(SSTS) ((SSTS >> 4) & 0xF)
/*
* Port SATA control bits
@@ -98,6 +101,7 @@ struct hba_memspace {
* See section 3.3.7 of the AHCI spec.
*/
#define AHCI_PXCMD_ST BIT(0) /* Start */
+#define AHCI_PXCMD_SUD BIT(1) /* Spin-up device */
#define AHCI_PXCMD_FRE BIT(4) /* FIS Receive Enable */
#define AHCI_PXCMD_FR BIT(14) /* FIS Receive Running */
#define AHCI_PXCMD_CR BIT(15) /* Command List Running */
@@ -122,6 +126,9 @@ struct hba_memspace {
*/
#define AHCI_CAP_NP(CAP) (CAP & 0x1F) /* Number of ports */
#define AHCI_CAP_NCS(CAP) ((CAP >> 8) & 0x1F) /* Number of command slots */
+#define AHCI_CAP_EMS(CAP) ((CAP >> 6) & 1) /* Enclosure management support */
+#define AHCI_CAP_SAL(CAP) ((CAP >> 25) & 1) /* Supports activity LED */
+#define AHCI_CAP_SSS(CAP) ((CAP >> 27) & 1) /* Supports staggered spin up */
/*
* Device detection (DET) and Interface power
@@ -132,6 +139,31 @@ struct hba_memspace {
#define AHCI_DET_PRESENT 1 /* Device present (no PHY comm) */
#define AHCI_DET_COMM 3 /* Device present and phy comm established */
#define AHCI_IPM_ACTIVE 1
+#define AHCI_SPD_GEN1 1 /* 1.5 Gb/s */
+#define AHCI_SPD_GEN2 2 /* 3 Gb/s */
+#define AHCI_SPD_GEN3 3 /* 6 Gb/s */
+
+/*
+ * PxSERR bits
+ * See section 3.3.12 of the AHCI spec
+ */
+#define AHCI_SERR_I BIT(0) /* Recovered data integrity error */
+#define AHCI_SERR_M BIT(1) /* Recovered comms error */
+#define AHCI_SERR_T BIT(8) /* Transient data integrity error */
+#define AHCI_SERR_C BIT(9) /* Persistent comms error */
+#define AHCI_SERR_P BIT(10) /* Protocol error ("oh fuck!" bit) */
+#define AHCI_SERR_E BIT(11) /* Internal error (only God knows, just pray) */
+#define AHCI_DIAG_N BIT(16) /* PhyRdy change */
+#define AHCI_DIAG_I BIT(17) /* PHY internal error */
+#define AHCI_DIAG_W BIT(18) /* Comm wake */
+#define AHCI_DIAG_B BIT(19) /* 10B to 8B decode error */
+#define AHCI_DIAG_C BIT(21) /* CRC error */
+#define AHCI_DIAG_H BIT(22) /* Handshake error */
+#define AHCI_DIAG_S BIT(23) /* Link sequence error */
+#define AHCI_DIAG_T BIT(24) /* Transport state transition error */
+#define AHCI_DIAG_F BIT(25) /* Unknown FIS type */
+
+#define ATAPI_SIG 0xEB140101
/*
* Device detection initialization values
diff --git a/sys/include/dev/ic/ahcivar.h b/sys/include/dev/ic/ahcivar.h
index 0d307cd..67f2efe 100644
--- a/sys/include/dev/ic/ahcivar.h
+++ b/sys/include/dev/ic/ahcivar.h
@@ -30,12 +30,210 @@
#ifndef _IC_AHCIVAR_H_
#define _IC_AHCIVAR_H_
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <dev/dcdr/cache.h>
#include <dev/ic/ahciregs.h>
+#include <fs/ctlfs.h>
+#define AHCI_DCDR_CAP 16
+
+struct ahci_cmd_hdr;
+extern const struct ctlops g_sata_bsize_ops;
+
+struct ata_identity {
+ uint16_t rsvd0 : 1;
+ uint16_t unused0 : 1;
+ uint16_t incomplete : 1;
+ uint16_t unused1 : 3;
+ uint16_t fixed_dev : 1;
+ uint16_t removable : 1;
+ uint16_t unused2 : 7;
+ uint16_t device_type : 1;
+ uint16_t ncylinders;
+ uint16_t specific_config;
+ uint16_t nheads;
+ uint16_t unused3[2];
+ uint16_t sectors_per_track;
+ uint16_t vendor[3];
+ char serial_number[20];
+ uint16_t unused4[2];
+ uint16_t unused5;
+ char firmware_rev[8];
+ char model_number[40];
+ char pad[256];
+};
+
+/*
+ * AHCI Host Bus Adapter
+ *
+ * @io: HBA MMIO
+ * @maxports: Max number of HBA ports
+ * @nports: Number of implemented HBA ports.
+ * @nslots: Number of command slots
+ * @ems: Enclosure management support
+ * @sal: Supports activity LED
+ * @sss: Supports staggered spin up
+ */
struct ahci_hba {
struct hba_memspace *io;
+ uint32_t maxports;
+ uint32_t nports;
+ uint32_t nslots;
+ uint8_t ems : 1;
+ uint8_t sal : 1;
+ uint8_t sss : 1;
+ devmajor_t major;
+};
+
+/*
+ * A device attached to a physical HBA port.
+ *
+ * [d]: Dynalloc'd memory
+ * [p]: Paged memory (allocated pageframe)
+ *
+ * @io: Memory mapped port registers
+ * @hba: HBA descriptor
+ * @cmdlist: Command list [p]
+ * @nlba: Max number of addressable blocks
+ * @fra: FIS receive area [p]
+ * @dev: Device minor number.
+ */
+struct hba_device {
+ struct hba_port *io;
+ struct ahci_hba *hba;
+ struct ahci_cmd_hdr *cmdlist;
+ struct dcdr *dcdr;
+ uint32_t nlba;
+ void *fra;
+ dev_t dev;
+};
+
+/*
+ * Command header
+ *
+ * @cfl: Command FIS length
+ * @a: ATAPI
+ * @w: Write
+ * @p: Prefetchable
+ * @r: Reset
+ * @c: Clear busy upon R_OK
+ * @rsvd0: Reserved
+ * @pmp: Port multiplier port
+ * @prdtl: PRDT length (in entries)
+ * @prdbc: PRDT bytes transferred count
+ * @ctba: Command table descriptor base addr
+ * @rsvd1: Reserved
+ */
+struct ahci_cmd_hdr {
+ uint8_t cfl : 5;
+ uint8_t a : 1;
+ uint8_t w : 1;
+ uint8_t p : 1;
+ uint8_t r : 1;
+ uint8_t c : 1;
+ uint8_t rsvd0 : 1;
+ uint8_t pmp : 4;
+ uint16_t prdtl;
+ volatile uint32_t prdbc;
+ uintptr_t ctba;
+ uint32_t rsvd1[4];
+};
+
+/*
+ * Physical region descriptor
+ *
+ * @dba: Data base address
+ * @rsvd0: Reserved
+ * @dbc: Count
+ * @rsvd1: Reserved
+ * @i: Interrupt on completion
+ */
+struct ahci_prdt_entry {
+ uintptr_t dba;
+ uint32_t rsvd0;
+ uint32_t dbc : 22;
+ uint16_t rsvd1 : 9;
+ uint8_t i : 1;
+};
+
+/*
+ * Command table
+ *
+ * @cfis: Command FIS
+ * @acmd: ATAPI command
+ * @rsvd: Reserved
+ * @prdt: Physical region descriptors
+ */
+struct ahci_cmdtab {
+ uint8_t cfis[64];
+ uint8_t acmd[16];
+ uint8_t rsvd[48];
+ struct ahci_prdt_entry prdt[1];
+};
+
+/*
+ * Host to device FIS
+ *
+ * [h]: Set by host
+ * [d]: Set by device
+ * [srb]: Shadow register block
+ *
+ * @type: Must be 0x27 for H2D [h]
+ * @pmp: Port multiplier port [h]
+ * @c: Set to denote command FIS [h]
+ * @command: Command type [h/srb]
+ * @feature1: Features register (7:0) [h/srb]
+ * @lba0: LBA low [h/srb]
+ * @lba1: LBA mid [h/srb]
+ * @lba2: LBA hi [h/srb]
+ * @device: Set bit 7 for LBA [h/srb]
+ * @lba3: LBA (31:24) [h/srb]
+ * @lba4: LBA (39:32) [h/srb]
+ * @lba5: LBA (47:40) [h/srb]
+ * @featureh: Features high [h/srb]
+ * @countl: Count low (block aligned) [h/srb]
+ * @counth: Count high (block aligned) [h/srb]
+ */
+struct ahci_fis_h2d {
+ uint8_t type;
+ uint8_t pmp : 4;
+ uint8_t rsvd0 : 3;
+ uint8_t c : 1;
+ uint8_t command;
+ uint8_t featurel;
+ uint8_t lba0;
+ uint8_t lba1;
+ uint8_t lba2;
+ uint8_t device;
+ uint8_t lba3;
+ uint8_t lba4;
+ uint8_t lba5;
+ uint8_t featureh;
+ uint8_t countl;
+ uint8_t counth;
+ uint8_t icc;
+ uint8_t control;
+ uint8_t rsvd1[4];
};
#define AHCI_TIMEOUT 500 /* In ms */
+/* AHCI size constants */
+#define AHCI_FIS_SIZE 256
+#define AHCI_CMDTAB_SIZE 256
+#define AHCI_CMDENTRY_SIZE 32
+#define AHCI_SECTOR_SIZE 512
+
+/* AHCI FIS types */
+#define FIS_TYPE_H2D 0x27
+#define FIS_TYPE_D2H 0x34
+
+/* ATA commands */
+#define ATA_CMD_NOP 0x00
+#define ATA_CMD_IDENTIFY 0xEC
+#define ATA_CMD_READ_DMA 0x25
+#define ATA_CMD_WRITE_DMA 0x35
+
#endif /* !_IC_AHCIVAR_H_ */
diff --git a/sys/include/dev/pci/pci.h b/sys/include/dev/pci/pci.h
index 4bfacdd..144b500 100644
--- a/sys/include/dev/pci/pci.h
+++ b/sys/include/dev/pci/pci.h
@@ -54,6 +54,7 @@ struct pci_device {
uint8_t slot;
uint8_t func;
+ uint16_t segment;
uint16_t msix_capoff;
uint16_t device_id;
uint16_t vendor_id;
@@ -61,6 +62,7 @@ struct pci_device {
uint8_t pci_subclass;
uint8_t prog_if;
uint8_t hdr_type;
+ uint8_t pci_express : 1;
uint8_t pri_bus;
uint8_t sec_bus;
@@ -74,7 +76,7 @@ struct pci_device {
struct msi_intr {
const char *name;
- void(*handler)(void *);
+ int(*handler)(void *);
};
pcireg_t pci_readl(struct pci_device *dev, uint32_t offset);
@@ -84,6 +86,8 @@ int pci_map_bar(struct pci_device *dev, uint8_t barno, void **vap);
void pci_writel(struct pci_device *dev, uint32_t offset, pcireg_t val);
int pci_enable_msix(struct pci_device *dev, const struct msi_intr *intr);
+void pci_add_device(struct pci_device *dev);
+
void pci_msix_eoi(void);
int pci_init(void);
diff --git a/sys/include/dev/phy/e1000regs.h b/sys/include/dev/phy/e1000regs.h
new file mode 100644
index 0000000..7caceee
--- /dev/null
+++ b/sys/include/dev/phy/e1000regs.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PHY_E1000_REGS_H_
+#define _PHY_E1000_REGS_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+/*
+ * E1000 register offsets
+ *
+ * XXX: Notes about reserve fields:
+ *
+ * - The `EERD' register is reserved and should NOT be touched
+ * for the 82544GC/EI card.
+ *
+ * - The `FLA' register is only usable for the 82541xx and
+ * 82547GI/EI cards, this is reserved and should NOT be
+ * touched on any other cards.
+ *
+ * - The `TXCW' and `RXCW' registers are reserved and should NOT
+ * be touched for the 82540EP/EM, 82541xx and 82547GI/EI cards.
+ *
+ * - The `LEDCTL' register is reserved and should NOT be touched
+ * for the 82544GC/EI card.
+ */
+#define E1000_CTL 0x00000 /* Control register */
+#define E1000_STATUS 0x00008 /* Status register */
+#define E1000_EECD 0x00010 /* EEPROM/flash control and data register */
+#define E1000_EERD 0x00014 /* EEPROM/flash read register */
+#define E1000_FLA 0x0001C /* EEPROM/flash read register */
+#define E1000_CTRL_EXT 0x00018 /* Extended device control register */
+#define E1000_MDIC 0x00020 /* PHY management data interface control register */
+#define E1000_FCAL 0x00028 /* Flow control low register */
+#define E1000_FCAH 0x0002C /* Flow control high register */
+#define E1000_FCT 0x00030 /* Flow control type register */
+#define E1000_VET 0x00038 /* VLAN ethertype register */
+#define E1000_FCTTV 0x00170 /* Flow control transmit timer value register */
+#define E1000_TXCW 0x00178 /* Transmit config word register */
+#define E1000_RXCW 0x00180 /* Receive config word register */
+#define E1000_LEDCTL 0x00E00 /* LED control register */
+
+/*
+ * Device control register (`ctl') bits
+ *
+ * See section 13.4.1 of the PCI/PCI-X Intel Gigabit
+ * Ethernet Controllers spec
+ *
+ * XXX: Notes about reserved bits:
+ *
+ * - The CTL.LRST bit is reserved and should NOT be touched
+ * for the 82540EP/EM, 82541xx, or 82547GI/EI cards.
+ */
+#define E1000_CTL_FD BIT(0) /* Full-duplex */
+#define E1000_CTL_LRST BIT(3) /* Link-reset */
+#define E1000_CTL_RST BIT(26) /* Device reset */
+
+/*
+ * EEPROM/flash control and data register (`eecd')
+ * bits
+ *
+ * See section 13.4.3 of the PCI/PCI-X Intel Gigabit
+ * Ethernet controller spec
+ */
+#define E1000_EECD_SK BIT(0) /* EEPROM clock input */
+#define E1000_EECD_CS BIT(1) /* EEPROM chip select */
+#define E1000_EECD_DI BIT(2) /* EEPROM data input */
+#define E1000_EECD_DO BIT(3) /* EEPROM data output */
+#define E1000_EECD_FWE BIT(4) /* EEPROM flash write enable ctl (4:5) */
+#define E1000_EECD_REQ BIT(6) /* Request EEPROM access */
+#define E1000_EECD_GNT BIT(7) /* Grant EEPROM access */
+#define E1000_EECD_PRES BIT(8) /* EEPROM present */
+#define E1000_EECD_SIZE BIT(9) /* EEPROM size (1024-bit [0], 4096-bit [1]) */
+#define E1000_EECD_TYPE BIT(13) /* EEPROM type (microwire [0], SPI [1]) */
+
+/*
+ * EEPROM read (`eerd') register bits
+ *
+ * See section 13.4.4 of the PCI/PCI-X Intel Gigabit
+ * Ethernet controller spec
+ */
+#define E1000_EERD_START BIT(0) /* Start read */
+#define E1000_EERD_DONE BIT(4) /* EEPROM read finished */
+
+/*
+ * EEPROM word addresses
+ */
+#define E1000_HWADDR0 0x00 /* Word 0 */
+#define E1000_HWADDR1 0x01 /* Word 1 */
+#define E1000_HWADDR2 0x02 /* Word 2 */
+
+#endif /* !_PHY_E1000_REGS_H_ */
diff --git a/sys/include/dev/phy/rt8139.h b/sys/include/dev/phy/rtl.h
index ef7b127..f3178d0 100644
--- a/sys/include/dev/phy/rt8139.h
+++ b/sys/include/dev/phy/rtl.h
@@ -33,7 +33,14 @@
#include <sys/types.h>
#include <sys/param.h>
-#define RT_IDR0 0x00 /* MAC address */
+/* MAC address */
+#define RT_IDR0 0x00
+#define RT_IDR1 0x00
+#define RT_IDR2 0x02
+#define RT_IDR3 0x03
+#define RT_IDR4 0x04
+#define RT_IDR5 0x05
+
#define RT_MAR0 0x08 /* Multicast filter */
#define RT_TXSTATUS0 0x10 /* Transmit status (4 32bit regs) */
#define RT_TXADDR0 0x20 /* Tx descriptors (also 4 32bit) */
@@ -64,12 +71,19 @@
#define RT_AS_LPAR 0x68 /* Auto-negotiation link partner reg (16 bits) */
#define RT_AS_EXPANSION 0x6A /* Auto-negotiation expansion reg (16 bits) */
+#define RT_TXAD_N(N) (RT_TXADDR0 + (N))
+#define RT_TXSTATUS_N(N) (RT_TXSTATUS0 + ((N)))
+
/* Command register bits */
#define RT_BUFEN BIT(0) /* Buffer empty */
#define RT_TE BIT(2) /* Transmitter enable */
#define RT_RE BIT(3) /* Receiver enable */
#define RT_RST BIT(4) /* Reset */
+/* 93C46 EEPROM mode bits */
+#define RT_EEM0 BIT(6)
+#define RT_EEM1 BIT(7)
+
/* Receive register bits */
#define RT_AAP BIT(0) /* Accept all packets */
#define RT_APM BIT(1) /* Accept physical match packets */
diff --git a/sys/include/dev/timer.h b/sys/include/dev/timer.h
index e54adcc..fe91323 100644
--- a/sys/include/dev/timer.h
+++ b/sys/include/dev/timer.h
@@ -69,6 +69,7 @@ struct timer {
const char *name; /* e.g "HPET" */
size_t(*calibrate)(void); /* Returns frequency, 0 for unspecified */
size_t(*get_time_usec)(void); /* Time since init (microseconds) */
+ size_t(*get_time_nsec)(void); /* Time since init (nanoseconds) */
size_t(*get_time_sec)(void); /* Time since init (seconds) */
int(*msleep)(size_t ms);
int(*usleep)(size_t us);
diff --git a/sys/include/dev/usb/xhciregs.h b/sys/include/dev/usb/xhciregs.h
index 69515e4..1cbfd14 100644
--- a/sys/include/dev/usb/xhciregs.h
+++ b/sys/include/dev/usb/xhciregs.h
@@ -98,6 +98,13 @@ struct xhci_opregs {
#define XHCI_RTS(BASE, RTSOFF) PTR_OFFSET(BASE, RTSOFF)
#define XHCI_CMD_DB(BASE, DBOFF) PTR_OFFSET(BASE, DBOFF)
+/* Runtime register offsets */
+#define XHCI_RT_IMAN 0x20
+#define XHCI_RT_IMOD 0x24
+#define XHCI_RT_ERSTSZ 0x28
+#define XHCI_RT_ERSTBA 0x30
+#define XHCI_RT_ERDP 0x38
+
/* Support protocol cap fields */
#define XHCI_PROTO_ID(PROTO) (PROTO & 0xFF)
#define XHCI_PROTO_MINOR(PROTO) ((PROTO >> 16) & 0xFF)
diff --git a/sys/include/dev/usb/xhcivar.h b/sys/include/dev/usb/xhcivar.h
index 0488ad8..a9a8fc1 100644
--- a/sys/include/dev/usb/xhcivar.h
+++ b/sys/include/dev/usb/xhcivar.h
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/types.h>
+#include <sys/param.h>
#include <dev/usb/xhciregs.h>
#define XHCI_TIMEOUT 500 /* In ms */
@@ -41,6 +42,9 @@
#define XHCI_MAX_PROTOS 4
#define XHCI_IMOD_DEFAULT 0
+/* Quirks */
+#define XHCI_QUIRK_HANDOFF BIT(0)
+
/*
* USB proto (USB 2.0 or 3.0)
*/
@@ -108,6 +112,7 @@ struct xhci_hc {
uint32_t *evring;
uint8_t maxslots;
uint8_t cr_cycle : 1;
+ uint16_t quirks;
size_t maxports;
size_t protocnt;
struct xhci_caps *caps;
diff --git a/sys/include/dev/video/fbdev.h b/sys/include/dev/video/fbdev.h
index d23fcd6..c9fec94 100644
--- a/sys/include/dev/video/fbdev.h
+++ b/sys/include/dev/video/fbdev.h
@@ -38,6 +38,7 @@ struct fbdev {
uint32_t width;
uint32_t height;
uint32_t pitch;
+ uint32_t bpp;
};
/*
@@ -51,5 +52,6 @@ fbdev_get_index(const struct fbdev *fbdev, uint32_t x, uint32_t y)
}
struct fbdev fbdev_get(void);
+void fbdev_init_dev(void);
#endif /* !_DEV_FBDEV_H_ */
diff --git a/sys/include/fs/ctlfs.h b/sys/include/fs/ctlfs.h
new file mode 100644
index 0000000..90f42f0
--- /dev/null
+++ b/sys/include/fs/ctlfs.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FS_CTLFS_H_
+#define _FS_CTLFS_H_
+
+#include <sys/sio.h>
+
+struct ctlfs_dev;
+
+struct ctlops {
+ int(*read)(struct ctlfs_dev *cdp, struct sio_txn *sio);
+ int(*write)(struct ctlfs_dev *cdp, struct sio_txn *sio);
+};
+
+/*
+ * Ctlfs op arguments
+ *
+ * @devname: Device name.
+ * @major: Device major
+ * @minor: Device minor.
+ * @mode: Access flags.
+ * @devname [1]: Device name (node name)
+ * @ctlname: [1]: Control name (node entry name)
+ */
+struct ctlfs_dev {
+ union {
+ const char *devname;
+ const char *ctlname;
+ };
+ const struct ctlops *ops;
+ mode_t mode;
+};
+
+int ctlfs_create_node(const char *name, const struct ctlfs_dev *dp);
+int ctlfs_create_entry(const char *name, const struct ctlfs_dev *dp);
+
+#endif /* !_FS_CTLFS_H_ */
diff --git a/sys/include/fs/tmpfs.h b/sys/include/fs/tmpfs.h
new file mode 100644
index 0000000..b2a5bbe
--- /dev/null
+++ b/sys/include/fs/tmpfs.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FS_TMPFS_H_
+#define _FS_TMPFS_H_
+
+#include <sys/types.h>
+#include <sys/limits.h>
+#include <sys/vnode.h>
+#include <sys/queue.h>
+#include <sys/spinlock.h>
+#include <vm/vm_obj.h>
+
+extern const struct vops g_tmpfs_vops;
+
+/* Tmpfs node types */
+#define TMPFS_NONE (VNON) /* No type */
+#define TMPFS_REG (VREG) /* Regular file [f] */
+#define TMPFS_DIR (VDIR) /* Directory [d] */
+
+struct tmpfs_node;
+
+/*
+ * A tmpfs node represents an object within the
+ * tmpfs namespace such as a file, directory, etc.
+ *
+ * @rpath: /tmp/ relative path (for lookups)
+ * @type: The tmpfs node type [one-to-one to vtype]
+ * @len: Length of buffer
+ * @data: The backing file data
+ * @dirvp: Vnode of the parent node
+ * @vp: Vnode of the current node
+ * @lock: Lock protecting this node
+ */
+struct tmpfs_node {
+ char rpath[PATH_MAX];
+ uint8_t type;
+ size_t len;
+ void *data;
+ struct vnode *dirvp;
+ struct vnode *vp;
+ struct spinlock lock;
+ TAILQ_HEAD(, tmpfs_node) dirents;
+ TAILQ_ENTRY(tmpfs_node) link;
+};
+
+#endif /* !_FS_TMPFS_H_ */
diff --git a/sys/include/lib/stdbool.h b/sys/include/lib/stdbool.h
new file mode 100644
index 0000000..a7a35f1
--- /dev/null
+++ b/sys/include/lib/stdbool.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_STDBOOL_H_
+#define _LIB_STDBOOL_H_
+
+typedef _Bool bool;
+
+#define true 1
+#define false 0
+
+#endif /* !_LIB_STDBOOL_H_ */
diff --git a/sys/include/lib/stddef.h b/sys/include/lib/stddef.h
new file mode 100644
index 0000000..cf23841
--- /dev/null
+++ b/sys/include/lib/stddef.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_STDDEF_H_
+#define _LIB_STDDEF_H_
+
+/* Compat */
+#include <sys/types.h>
+
+#endif /* !_LIB_STDDEF_H_ */
diff --git a/sys/include/lib/stdint.h b/sys/include/lib/stdint.h
new file mode 100644
index 0000000..6eb99f0
--- /dev/null
+++ b/sys/include/lib/stdint.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_STDINT_H_
+#define _LIB_STDINT_H_
+
+/* Compat */
+#include <sys/types.h>
+
+#endif /* !_LIB_STDINT_H_ */
diff --git a/sys/include/lib/string.h b/sys/include/lib/string.h
index c138cf1..c09e6f4 100644
--- a/sys/include/lib/string.h
+++ b/sys/include/lib/string.h
@@ -47,5 +47,6 @@ int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
int atoi(char *s);
+void *memmove(void *s1, const void *s2, size_t n);
#endif /* !_LIB_STRING_H_ */
diff --git a/sys/include/net/ethertypes.h b/sys/include/net/ethertypes.h
new file mode 100644
index 0000000..753ea10
--- /dev/null
+++ b/sys/include/net/ethertypes.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_ETHERTYPES_H_
+#define _NET_ETHERTYPES_H_
+
+#define ETHERTYPE_IPV4 0x0800
+#define ETHERTYPE_ARP 0x0806
+
+#endif /* !_NET_ETHERTYPES_H_ */
diff --git a/sys/include/net/if.h b/sys/include/net/if.h
new file mode 100644
index 0000000..bd57509
--- /dev/null
+++ b/sys/include/net/if.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_IF_H_
+#define _NET_IF_H_
+
+#define IFNAMESIZ 16
+
+#endif /* !_NET_IF_H_ */
diff --git a/sys/include/net/if_arp.h b/sys/include/net/if_arp.h
new file mode 100644
index 0000000..cbfb2fe
--- /dev/null
+++ b/sys/include/net/if_arp.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NETINET_IF_ARP_H_
+#define _NETINET_IF_ARP_H_
+
+#include <sys/types.h>
+#include <net/ethertypes.h>
+
+/* ARP hardware types */
+#define ARP_HWTYPE_ETHER 1
+
+/* ARP operation types */
+#define ARP_REQUEST 1
+#define ARP_REPLY 2
+
+struct arp_hdr {
+ uint16_t hw_type; /* See ARP_HWTYPE_* */
+ uint16_t proto_type; /* See ETHERTYPE_* */
+ uint8_t hw_len; /* See ETHER_ADDR_LEN */
+ uint8_t proto_len; /* Protocol address length */
+ uint16_t op_type; /* See operation types above */
+};
+
+#endif /* !_NETINET_IF_ARP_H_ */
diff --git a/sys/include/net/if_var.h b/sys/include/net/if_var.h
new file mode 100644
index 0000000..e032ff4
--- /dev/null
+++ b/sys/include/net/if_var.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_IF_VAR_H_
+#define _NET_IF_VAR_H_
+
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <net/netbuf.h>
+
+#define NETIF_ADDR_LEN 32 /* In bytes */
+
+/* Return values for netif hooks */
+#define NETIF_ENQ_OK 0 /* Enqueued */
+#define NETIF_ENQ_FLUSHED 1 /* Internal queue flushed */
+
+/* Interface types */
+#define NETIF_TYPE_ANY 0 /* Any type */
+#define NETIF_TYPE_WIRE 1 /* Ethernet */
+
+/*
+ * Represents the address of a network
+ * interface.
+ *
+ * @data: Raw address bytes
+ */
+struct netif_addr {
+ uint8_t data[NETIF_ADDR_LEN];
+};
+
+/*
+ * Represents a network interface
+ *
+ * @name: Interface name
+ * @type: Interface type (see NETIF_TYPE*)
+ * @tx_enq: Enqueue a packet
+ * @tx_start: Start a packet
+ *
+ * XXX: tx_enq() returns 0 on success and 1 if a flush was needed
+ * and the packets have been transmitted. Less than zero values
+ * indicate failure.
+ */
+struct netif {
+ char name[IFNAMESIZ];
+ uint8_t type;
+ TAILQ_ENTRY(netif) link;
+ struct netif_addr addr;
+ int(*tx_enq)(struct netif *nifp, struct netbuf *nbp, void *data);
+ void(*tx_start)(struct netif *nifp);
+};
+
+void netif_add(struct netif *nifp);
+int netif_lookup(const char *name, uint8_t type, struct netif **res);
+
+#endif /* !_NET_IF_VAR_H_ */
diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h
new file mode 100644
index 0000000..33ba06f
--- /dev/null
+++ b/sys/include/net/netbuf.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_NETBUF_H_
+#define _NET_NETBUF_H_
+
+#define NETBUF_LEN 256
+
+struct netbuf {
+ char data[NETBUF_LEN];
+ size_t len;
+};
+
+#endif /* !_NET_NETBUF_H_ */
diff --git a/sys/include/netinet/if_ether.h b/sys/include/netinet/if_ether.h
new file mode 100644
index 0000000..d3dc9b7
--- /dev/null
+++ b/sys/include/netinet/if_ether.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NETINET_IF_ETHER_H_
+#define _NETINET_IF_ETHER_H_
+
+#include <sys/types.h>
+#include <net/if_arp.h>
+#include <net/if_var.h>
+
+#define ETHER_ADDR_LEN 6
+
+struct ether_arp {
+ struct arp_hdr hdr;
+ uint8_t sha[ETHER_ADDR_LEN];
+ uint8_t spa[4];
+ uint8_t tha[ETHER_ADDR_LEN];
+ uint8_t tpa[4];
+};
+
+struct ether_frame {
+ uint8_t ether_daddr[ETHER_ADDR_LEN];
+ uint8_t ether_saddr[ETHER_ADDR_LEN];
+ uint16_t ether_type;
+};
+
+int arp_request(struct netif *nifp, uint8_t *sproto, uint8_t *tproto);
+int arp_reply(struct netif *netif, uint8_t *sproto, uint8_t *tproto);
+
+#endif /* !_NETINET_IF_ETHER_H_ */
diff --git a/sys/include/sys/bitops.h b/sys/include/sys/bitops.h
new file mode 100644
index 0000000..e8e9567
--- /dev/null
+++ b/sys/include/sys/bitops.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_BITOPS_H_
+#define _SYS_BITOPS_H_
+
+#include <sys/cdefs.h>
+
+#define BOPS_M1 0x5555555555555555ULL /* 01010101... */
+#define BOPS_M2 0x3333333333333333ULL /* 00110011... */
+#define BOPS_M4 0x0F0F0F0F0F0F0F0FULL /* 00001111... */
+#define BOPS_M8 0x00FF00FF00FF00FFULL /* x4(0), x4(1) */
+#define BOPS_M16 0x0000FFFF0000FFFFULL /* x16(0), x16(1) */
+#define BOPS_M32 0x00000000FFFFFFFFULL /* x32(0), x32(1) */
+#define BOPS_H0 0x0101010101010101ULL /* sum of 256^{0,1,2,3...} */
+
+__always_inline static inline int
+popcnt(uint64_t x)
+{
+ x -= (x >> 1) & BOPS_M1;
+ x = (x & BOPS_M2) + ((x >> 2) & BOPS_M2);
+ x = (x + (x >> 4)) & BOPS_M4;
+ return (x * BOPS_H0) >> 56;
+}
+
+#endif /* !_SYS_BITOPS_H_ */
diff --git a/sys/include/sys/cdefs.h b/sys/include/sys/cdefs.h
index 61106fa..725193e 100644
--- a/sys/include/sys/cdefs.h
+++ b/sys/include/sys/cdefs.h
@@ -42,7 +42,9 @@
#define __dead __attribute__((__noreturn__))
#define __cold __attribute__((__cold__))
#define __dead_cold __attribute__((__noreturn__, __cold__))
+#define __aligned(n) __attribute__((__aligned__((n))))
#define __unused __attribute__((__unused__))
+#define __used __attribute__((__used__))
#define __nothing ((void)0)
#define __likely(exp) __builtin_expect(((exp) != 0), 1)
#define __unlikely(exp) __builtin_expect(((exp) != 0), 0)
diff --git a/sys/include/sys/device.h b/sys/include/sys/device.h
index f5f92ad..04b66fc 100644
--- a/sys/include/sys/device.h
+++ b/sys/include/sys/device.h
@@ -36,21 +36,28 @@
#include <sys/queue.h>
#include <sys/proc.h>
#include <sys/sio.h>
+#include <vm/vm_obj.h>
typedef uint8_t devmajor_t;
/* Device operation typedefs */
typedef int(*dev_read_t)(dev_t, struct sio_txn *, int);
typedef int(*dev_write_t)(dev_t, struct sio_txn *, int);
+typedef int(*dev_bsize_t)(dev_t);
struct cdevsw {
int(*read)(dev_t dev, struct sio_txn *sio, int flags);
int(*write)(dev_t dev, struct sio_txn *sio, int flags);
+ paddr_t(*mmap)(dev_t dev, size_t size, off_t off, int flags);
+
+ /* Private */
+ struct vm_object vmobj;
};
struct bdevsw {
int(*read)(dev_t dev, struct sio_txn *sio, int flags);
int(*write)(dev_t dev, struct sio_txn *sio, int flags);
+ int(*bsize)(dev_t dev);
};
void *dev_get(devmajor_t major, dev_t dev);
@@ -61,10 +68,12 @@ int dev_register(devmajor_t major, dev_t dev, void *devsw);
int dev_noread(void);
int dev_nowrite(void);
+int dev_nobsize(void);
/* Device operation stubs */
#define noread ((dev_read_t)dev_noread)
#define nowrite ((dev_write_t)dev_nowrite)
+#define nobsize ((dev_bsize_t)dev_nobsize)
#endif /* _KERNEL */
#endif /* !_SYS_DEVICE_H_ */
diff --git a/sys/include/sys/disklabel.h b/sys/include/sys/disklabel.h
new file mode 100644
index 0000000..895c35e
--- /dev/null
+++ b/sys/include/sys/disklabel.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_DISKLABEL_H_
+#define _SYS_DISKLABEL_H_
+
+#include <sys/types.h>
+
+#define DISK_MAG 0x4F445421UL /* "ODT!" */
+
+/*
+ * Represents a disk table.
+ *
+ * @magic: Magic number (`DISK_MAG')
+ * @sect_size: Disk sector size
+ */
+struct disklabel {
+ uint32_t magic;
+ uint32_t sect_size;
+};
+
+#endif /* !_SYS_DISKLABEL_H_ */
diff --git a/sys/include/sys/driver.h b/sys/include/sys/driver.h
index 05c40fa..9f08de3 100644
--- a/sys/include/sys/driver.h
+++ b/sys/include/sys/driver.h
@@ -31,27 +31,83 @@
#define _SYS_DRIVER_H_
#include <sys/cdefs.h>
+#include <sys/proc.h>
+#include <sys/types.h>
#if defined(_KERNEL)
+/* Variable driver data */
+struct driver_var {
+ uint8_t deferred : 1;
+};
+
struct driver {
int(*init)(void);
+ struct driver_var *data;
};
+extern struct proc g_proc0;
+
+/* Early (high priority) drivers */
extern char __drivers_init_start[];
extern char __drivers_init_end[];
+/* Deferred (low priority) drivers */
+extern char __driversd_init_start[];
+extern char __driversd_init_end[];
+
#define DRIVER_EXPORT(INIT) \
+ static struct driver_var __driver_var = { \
+ .deferred = 0 \
+ }; \
+ \
__attribute__((used, section(".drivers"))) \
static struct driver __driver_desc = { \
.init = INIT, \
+ .data = &__driver_var \
+ }
+
+/*
+ * Some drivers are not required to start up
+ * early for proper system operation and may
+ * be deferred to start at a later time.
+ *
+ * Examples of such (deferrable) drivers include code
+ * that waits for I/O (e.g., disks, network cards,
+ * et cetera). This allows for faster boot times
+ * as only *required* drivers are started before
+ * everything else.
+ *
+ * Drivers that wish to be deferred may export themselves
+ * via the DRIVER_DEFER() macro. The DRIVER_DEFERRED()
+ * macro gives the value of 1 if the current driver
+ * context has yet to be initialized. The driver may
+ * use this to defer requests for I/O.
+ */
+#define DRIVER_DEFER(INIT) \
+ static struct driver_var __driver_var = { \
+ .deferred = 1 \
+ }; \
+ \
+ __attribute__((used, section(".drivers.defer"))) \
+ static struct driver __driver_desc = { \
+ .init = INIT, \
+ .data = &__driver_var \
}
+#define DRIVER_DEFERRED() __driver_var.deferred
+
#define DRIVERS_INIT() \
for (struct driver *__d = (struct driver *)__drivers_init_start; \
(uintptr_t)__d < (uintptr_t)__drivers_init_end; ++__d) \
{ \
__d->init(); \
}
+
+#define DRIVERS_SCHED() \
+ spawn(&g_proc0, __driver_init_td, NULL, 0, NULL)
+
+void __driver_init_td(void);
+
#endif /* _KERNEL */
#endif /* !_SYS_DRIVER_H_ */
diff --git a/sys/include/sys/elf.h b/sys/include/sys/elf.h
index af5f6d6..76c6d43 100644
--- a/sys/include/sys/elf.h
+++ b/sys/include/sys/elf.h
@@ -496,4 +496,70 @@ typedef struct {
Elf64_Xword sh_entsize; /* Entry size if section holds table */
} Elf64_Shdr;
+/* Special section indices. */
+
+#define SHN_UNDEF 0 /* Undefined section */
+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
+#define SHN_LOPROC 0xff00 /* Start of processor-specific */
+#define SHN_BEFORE 0xff00 /* Order section before all others
+ (Solaris). */
+#define SHN_AFTER 0xff01 /* Order section after all others
+ (Solaris). */
+#define SHN_HIPROC 0xff1f /* End of processor-specific */
+#define SHN_LOOS 0xff20 /* Start of OS-specific */
+#define SHN_HIOS 0xff3f /* End of OS-specific */
+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
+#define SHN_COMMON 0xfff2 /* Associated symbol is common */
+#define SHN_XINDEX 0xffff /* Index is in extra table. */
+#define SHN_HIRESERVE 0xffff /* End of reserved indices */
+
+/* Legal values for sh_type (section type). */
+
+#define SHT_NULL 0 /* Section header table entry unused */
+#define SHT_PROGBITS 1 /* Program data */
+#define SHT_SYMTAB 2 /* Symbol table */
+#define SHT_STRTAB 3 /* String table */
+#define SHT_RELA 4 /* Relocation entries with addends */
+#define SHT_HASH 5 /* Symbol hash table */
+#define SHT_DYNAMIC 6 /* Dynamic linking information */
+#define SHT_NOTE 7 /* Notes */
+#define SHT_NOBITS 8 /* Program space with no data (bss) */
+#define SHT_REL 9 /* Relocation entries, no addends */
+#define SHT_SHLIB 10 /* Reserved */
+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY 14 /* Array of constructors */
+#define SHT_FINI_ARRAY 15 /* Array of destructors */
+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
+#define SHT_GROUP 17 /* Section group */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
+#define SHT_NUM 19 /* Number of defined types. */
+#define SHT_LOOS 0x60000000 /* Start OS-specific. */
+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
+#define SHT_HIOS 0x6fffffff /* End OS-specific type */
+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
+#define SHT_LOUSER 0x80000000 /* Start of application-specific */
+#define SHT_HIUSER 0x8fffffff /* End of application-specific */
+
+/* Legal values for sh_flags (section flags). */
+
+#define SHF_WRITE (1 << 0) /* Writable */
+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
+#define SHF_EXECINSTR (1 << 2) /* Executable */
+#define SHF_MERGE (1 << 4) /* Might be merged */
+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
+ required */
+#define SHF_GROUP (1 << 9) /* Section is member of a group. */
+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
+#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
#endif /* _SYS_ELF_H_ */
diff --git a/sys/include/sys/endian.h b/sys/include/sys/endian.h
new file mode 100644
index 0000000..5cbc94a
--- /dev/null
+++ b/sys/include/sys/endian.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_ENDIAN_H_
+#define _SYS_ENDIAN_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#define swap16(x) __swap16((x))
+#define swap32(x) __swap32((x))
+
+__always_inline static inline uint16_t
+__swap16(uint16_t x)
+{
+ return ((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF);
+}
+
+__always_inline static inline uint32_t
+__swap32(uint32_t x)
+{
+ return ((x << 24) & 0xFF000000) |
+ ((x << 8) & 0x00FF0000) |
+ ((x >> 8) & 0x0000FF00) |
+ ((x >> 24) & 0x000000FF);
+}
+
+#endif /* !_SYS_ENDIAN_H_ */
diff --git a/sys/include/sys/exec.h b/sys/include/sys/exec.h
index 7e720fc..aa2a729 100644
--- a/sys/include/sys/exec.h
+++ b/sys/include/sys/exec.h
@@ -32,7 +32,6 @@
#include <sys/types.h>
-#if defined(_KERNEL)
/* Danger: Do not change these !! */
#define AT_NULL 0
@@ -45,7 +44,9 @@
#define AT_RANDOM 7
#define AT_EXECFN 8
#define AT_PAGESIZE 9
+#define _AT_MAX 16
+#if defined(_KERNEL)
#define MAX_PHDRS 32
#define STACK_PUSH(PTR, VAL) *(--(PTR)) = VAL
#define AUXVAL(PTR, TAG, VAL) \
diff --git a/sys/include/sys/fbdev.h b/sys/include/sys/fbdev.h
new file mode 100644
index 0000000..e206889
--- /dev/null
+++ b/sys/include/sys/fbdev.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_FBDEV_H_
+#define _SYS_FBDEV_H_
+
+struct fbattr {
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+ uint32_t bpp;
+};
+
+#endif /* !_SYS_FBDEV_H_ */
diff --git a/sys/include/sys/fcntl.h b/sys/include/sys/fcntl.h
index 122a378..83d38af 100644
--- a/sys/include/sys/fcntl.h
+++ b/sys/include/sys/fcntl.h
@@ -33,6 +33,7 @@
#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
+#define O_CREAT 0x0004
/* Makes seal checking easier */
#if defined(_KERNEL)
diff --git a/sys/include/sys/filedesc.h b/sys/include/sys/filedesc.h
index a544811..4ce2db2 100644
--- a/sys/include/sys/filedesc.h
+++ b/sys/include/sys/filedesc.h
@@ -31,8 +31,15 @@
#define _SYS_FILEDESC_H_
#include <sys/types.h>
+#if defined(_KERNEL)
#include <sys/vnode.h>
+#include <sys/syscall.h>
#include <sys/spinlock.h>
+#include <sys/syscall.h>
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
struct filedesc {
int fdno;
@@ -50,8 +57,12 @@ int fd_write(unsigned int fd, void *buf, size_t count);
int fd_alloc(struct filedesc **fd_out);
int fd_open(const char *pathname, int flags);
+off_t fd_seek(int fildes, off_t offset, int whence);
int fd_dup(int fd);
struct filedesc *fd_get(unsigned int fdno);
+scret_t sys_lseek(struct syscall_args *scargs);
+
+#endif /* _KERNEL */
#endif /* !_SYS_FILEDESC_H_ */
diff --git a/sys/include/sys/krq.h b/sys/include/sys/krq.h
new file mode 100644
index 0000000..9cb6ec6
--- /dev/null
+++ b/sys/include/sys/krq.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_KRQ_H_
+#define _SYS_KRQ_H_
+
+#include <sys/syscall.h>
+
+#if defined(_KERNEL)
+scret_t sys_inject(struct syscall_args *scargs);
+#else
+int inject(const char *path);
+#endif /* _KERNEL */
+#endif /* !_SYS_KRQ_H_ */
diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h
index 6185719..f56958e 100644
--- a/sys/include/sys/limits.h
+++ b/sys/include/sys/limits.h
@@ -32,6 +32,9 @@
#define PATH_MAX 1024
#define SSIZE_MAX 32767
+#define ARG_MAX 4096
#define CHAR_BIT 8
-
+#if defined(_KERNEL)
+#define CPU_MAX 256
+#endif /* _KERNEL */
#endif /* !_SYS_LIMITS_H_ */
diff --git a/sys/include/sys/mman.h b/sys/include/sys/mman.h
index 4ead9ba..de360e4 100644
--- a/sys/include/sys/mman.h
+++ b/sys/include/sys/mman.h
@@ -35,6 +35,8 @@
#if defined(_KERNEL)
#include <sys/tree.h>
#include <vm/vm_obj.h>
+#else
+#include <stddef.h>
#endif /* _KERNEL */
/*
@@ -49,10 +51,10 @@
#endif /* !_KERNEL */
/* mmap() flags */
+#define MAP_ANON 0x0000
#define MAP_SHARED 0x0001
#define MAP_PRIVATE 0x0002
#define MAP_FIXED 0x0004
-#define MAP_ANON 0x0008
#if defined(_KERNEL)
/*
@@ -80,19 +82,19 @@ struct mmap_lgdr {
size_t nbytes;
};
-/* Kernel munmap() routine */
-int munmap_at(void *addr, size_t len);
-
-/* Kernel mmap() routine */
-void *mmap_at(void *addr, size_t len, int prot, int flags,
- int fildes, off_t off);
-
int mmap_entrycmp(const struct mmap_entry *a, const struct mmap_entry *b);
RBT_PROTOTYPE(lgdr_entries, mmap_entry, hd, mmap_entrycmp)
-#endif /* _KERNEL */
/* Syscall layer */
-scret_t mmap(struct syscall_args *scargs);
-scret_t munmap(struct syscall_args *scargs);
+scret_t sys_mmap(struct syscall_args *scargs);
+scret_t sys_munmap(struct syscall_args *scargs);
+#endif /* _KERNEL */
+
+/* Kernel munmap() routine */
+int munmap(void *addr, size_t len);
+
+/* Kernel mmap() routine */
+void *mmap(void *addr, size_t len, int prot, int flags,
+ int fildes, off_t off);
#endif /* !_SYS_MMAN_H_ */
diff --git a/sys/include/sys/mount.h b/sys/include/sys/mount.h
index 3b5d89e..636c7bf 100644
--- a/sys/include/sys/mount.h
+++ b/sys/include/sys/mount.h
@@ -46,6 +46,8 @@
*/
#define MOUNT_RAMFS "initramfs"
#define MOUNT_DEVFS "devfs"
+#define MOUNT_CTLFS "ctlfs"
+#define MOUNT_TMPFS "tmpfs"
struct vfsops;
struct mount;
@@ -57,6 +59,8 @@ extern mountlist_t g_mountlist;
/* Filesystem operations */
extern const struct vfsops g_initramfs_vfsops;
extern const struct vfsops g_devfs_vfsops;
+extern const struct vfsops g_ctlfs_vfsops;
+extern const struct vfsops g_tmpfs_vfsops;
struct mount {
char *name;
diff --git a/sys/include/sys/namei.h b/sys/include/sys/namei.h
index f81f905..ccd7f35 100644
--- a/sys/include/sys/namei.h
+++ b/sys/include/sys/namei.h
@@ -32,6 +32,9 @@
#include <sys/types.h>
#include <sys/vnode.h>
+#include <sys/param.h>
+
+#define NAMEI_WANTPARENT BIT(0) /* Request parent only */
struct nameidata {
const char *path; /* Pathname */
diff --git a/sys/include/sys/param.h b/sys/include/sys/param.h
index c0a5686..7331d5f 100644
--- a/sys/include/sys/param.h
+++ b/sys/include/sys/param.h
@@ -67,8 +67,12 @@
/* Gives 1 if pointer is aligned */
#define PTR_ALIGNED(PTR, ALIGN) (!((uintptr_t)PTR & (ALIGN - 1)))
-/* Adds a value to a pointer */
+/*
+ * PTR_OFFSET: Adds an offset to the pointer
+ * PTR_NOFFSET: Subtracts a negative offset from the pointer
+ */
#define PTR_OFFSET(PTR, OFF) ((void *)((uintptr_t)PTR + OFF))
+#define PTR_NOFFSET(PTR, NOFF) ((void *)((uintptr_t)PTR - NOFF))
#define NELEM(a) (sizeof(a) / sizeof(a[0]))
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h
index c561e91..241d990 100644
--- a/sys/include/sys/proc.h
+++ b/sys/include/sys/proc.h
@@ -63,26 +63,43 @@ struct proc {
struct spinlock vcache_lock;
struct trapframe tf;
struct pcb pcb;
+ struct proc *parent;
+ void *data;
size_t priority;
+ int exit_status;
bool rested;
- uint32_t flags;
+ volatile uint32_t flags;
+ uint32_t nleaves;
uintptr_t stack_base;
struct spinlock ksigq_lock;
+ TAILQ_HEAD(, proc) leafq;
+ TAILQ_ENTRY(proc) leaf_link;
TAILQ_HEAD(, ksiginfo) ksigq;
TAILQ_ENTRY(proc) link;
};
#define PROC_EXITING BIT(0) /* Exiting */
#define PROC_EXEC BIT(1) /* Exec called (cleared by sched) */
+#define PROC_ZOMB BIT(2) /* Zombie (dead but not deallocated) */
+#define PROC_LEAFQ BIT(3) /* Leaf queue is active */
+#define PROC_WAITED BIT(4) /* Being waited on by parent */
+#define PROC_KTD BIT(5) /* Kernel thread */
+#define PROC_SLEEP BIT(6) /* Thread execution paused */
struct proc *this_td(void);
-int md_fork(struct proc *p, struct proc *parent, uintptr_t ip);
+struct proc *get_child(struct proc *cur, pid_t pid);
+void proc_reap(struct proc *td);
-void md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog);
+int md_spawn(struct proc *p, struct proc *parent, uintptr_t ip);
+
+scret_t sys_spawn(struct syscall_args *scargs);
+pid_t spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **newprocp);
+
+uintptr_t md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog);
__dead void md_td_kick(struct proc *td);
int fork1(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp);
-int exit1(struct proc *td);
+int exit1(struct proc *td, int flags);
__dead scret_t sys_exit(struct syscall_args *scargs);
#endif /* _KERNEL */
diff --git a/sys/include/sys/reboot.h b/sys/include/sys/reboot.h
index 86fc45d..846073d 100644
--- a/sys/include/sys/reboot.h
+++ b/sys/include/sys/reboot.h
@@ -32,12 +32,15 @@
#include <sys/param.h>
#include <sys/cdefs.h>
+#include <sys/syscall.h>
-#define REBOOT_HALT BIT(0) /* Halt instead of rebooting */
-
-#if defined(_KERNEL)
+#define REBOOT_RESET 0x00000000
+#define REBOOT_HALT BIT(0) /* Halt instead of rebooting */
+#define REBOOT_POWEROFF BIT(1) /* Power off (needs REBOOT_HALT set too) */
void cpu_reboot(int method);
+#if defined(_KERNEL)
+scret_t sys_reboot(struct syscall_args *scargs);
#endif /* _KERNEL */
#endif /* _SYS_REBOOT_H_ */
diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h
index 7f5e65f..7d17607 100644
--- a/sys/include/sys/sched.h
+++ b/sys/include/sys/sched.h
@@ -37,6 +37,10 @@
void sched_init(void);
void sched_yield(void);
+
+void sched_switch_to(struct trapframe *tf, struct proc *td);
+void sched_detach(struct proc *td);
+
__dead void sched_enter(void);
void sched_enqueue_td(struct proc *td);
diff --git a/sys/include/sys/schedvar.h b/sys/include/sys/schedvar.h
index 509e2c9..5ed9f5f 100644
--- a/sys/include/sys/schedvar.h
+++ b/sys/include/sys/schedvar.h
@@ -36,7 +36,7 @@
#include <machine/cdefs.h>
#if defined(_KERNEL)
-#define DEFAULT_TIMESLICE_USEC 500
+#define DEFAULT_TIMESLICE_USEC 9000
#define SHORT_TIMESLICE_USEC 10
#define SCHED_POLICY_MLFQ 0x00U /* Multilevel feedback queue */
diff --git a/sys/include/sys/spawn.h b/sys/include/sys/spawn.h
new file mode 100644
index 0000000..0c54e4c
--- /dev/null
+++ b/sys/include/sys/spawn.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SPAWN_H_
+#define _SYS_SPAWN_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#define SPAWN_WAIT BIT(0)
+
+#if !defined(_KERNEL)
+pid_t spawn(const char *pathname, char **argv, char **envp, int flags);
+#endif /* _KERNEL */
+#endif /* !_SYS_SPAWN_H_ */
diff --git a/sys/include/sys/stat.h b/sys/include/sys/stat.h
index 6303630..5409f2c 100644
--- a/sys/include/sys/stat.h
+++ b/sys/include/sys/stat.h
@@ -32,6 +32,8 @@
#include <sys/types.h>
+#define S_IFBLK 0060000
+
struct stat {
dev_t st_dev;
ino_t st_ino;
@@ -46,4 +48,6 @@ struct stat {
time_t st_ctime;
};
+int stat(const char *path, struct stat *buf);
+
#endif /* _SYS_STAT_H_ */
diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h
index 41d1e78..08bd989 100644
--- a/sys/include/sys/syscall.h
+++ b/sys/include/sys/syscall.h
@@ -33,7 +33,10 @@
#if !defined(__ASSEMBLER__)
#include <sys/types.h>
#include <sys/cdefs.h>
-#endif /* !__ASSEMBLER__ */
+#if defined(_KERNEL) || defined(_OLIBC)
+#include <machine/syscall.h>
+#endif /* _KERNEL || _OLIBC */
+#endif
#define SYS_none 0
#define SYS_exit 1
@@ -43,6 +46,14 @@
#define SYS_stat 5
#define SYS_sysctl 6
#define SYS_write 7
+#define SYS_spawn 8
+#define SYS_reboot 9
+#define SYS_mmap 10
+#define SYS_munmap 11
+#define SYS_access 12
+#define SYS_lseek 13
+#define SYS_sleep 14
+#define SYS_inject 15
#if defined(_KERNEL)
/* Syscall return value and arg type */
@@ -64,76 +75,4 @@ extern const size_t MAX_SYSCALLS;
extern scret_t(*g_sctab[])(struct syscall_args *);
#endif /* _KERNEL */
-#if !defined(__ASSEMBLER__)
-__always_inline static inline long
-syscall0(uint64_t code)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code));
- return ret;
-}
-
-__always_inline static inline long
-syscall1(uint64_t code, uint64_t arg0)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0) : "memory");
- return ret;
-}
-
-__always_inline static long inline
-syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
-{
- volatile long ret;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
-{
- volatile long ret;
- register uint64_t _arg3 asm("r10") = arg3;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
-{
- volatile long ret;
- register uint64_t _arg3 asm("r10") = arg3;
- register uint64_t _arg4 asm("r9") = arg4;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4) : "memory");
- return ret;
-}
-
-__always_inline static inline long
-syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5)
-{
- volatile long ret;
- register uint64_t _arg3 asm("r10") = arg3;
- register uint64_t _arg4 asm("r9") = arg4;
- register uint64_t _arg5 asm("r8") = arg5;
- __ASMV("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) : "memory");
- return ret;
-}
-
-#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
- name
-
-#define syscall(...) \
-_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
- syscall4, syscall3, syscall2, syscall1, \
- syscall0)(__VA_ARGS__)
-
-#endif /* !__ASSEMBLER__ */
#endif /* _SYS_SYSCALL_H_ */
diff --git a/sys/include/sys/syslog.h b/sys/include/sys/syslog.h
index defb341..b9d34ab 100644
--- a/sys/include/sys/syslog.h
+++ b/sys/include/sys/syslog.h
@@ -31,11 +31,13 @@
#define _SYS_SYSLOG_H_
#include <stdarg.h>
+#include <stdbool.h>
#if defined(_KERNEL)
#define OMIT_TIMESTAMP "\x01"
+void syslog_silence(bool option);
void kprintf(const char *fmt, ...);
void serial_init(void);
void serial_putc(char c);
diff --git a/sys/include/sys/time.h b/sys/include/sys/time.h
new file mode 100644
index 0000000..ce66885
--- /dev/null
+++ b/sys/include/sys/time.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_TIME_H_
+#define _SYS_TIME_H_
+
+#include <sys/types.h>
+#if defined(_KERNEL)
+#include <sys/syscall.h>
+#endif /* _KERNEL */
+
+struct timeval {
+ time_t tv_sec;
+ time_t tv_usec;
+};
+
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+
+struct date {
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t sec;
+ uint8_t min;
+ uint8_t hour;
+};
+
+#if defined(_KERNEL)
+scret_t sys_sleep(struct syscall_args *scargs);
+#endif
+#endif /* !_SYS_TIME_H_ */
diff --git a/sys/include/sys/types.h b/sys/include/sys/types.h
index 5501cc3..5cb2fc7 100644
--- a/sys/include/sys/types.h
+++ b/sys/include/sys/types.h
@@ -36,8 +36,7 @@
/* Compat */
#if defined(_KERNEL)
-#define true 1
-#define false 0
+#include <stdbool.h>
#if !defined(NULL)
#define NULL ((void *)0)
#endif /* !NULL */
@@ -113,11 +112,6 @@ typedef uint64_t time_t;
typedef __ptrdiff_t ptrdiff_t;
#endif /* _HAVE_PTRDIFF_T */
-/* Compat */
-#if defined(_KERNEL)
-typedef _Bool bool;
-#endif
-
#if defined(_KERNEL)
typedef uintptr_t paddr_t;
typedef uintptr_t vaddr_t;
diff --git a/sys/include/sys/vfs.h b/sys/include/sys/vfs.h
index 1ff722a..fcb7391 100644
--- a/sys/include/sys/vfs.h
+++ b/sys/include/sys/vfs.h
@@ -40,6 +40,7 @@ scret_t sys_close(struct syscall_args *args);
scret_t sys_read(struct syscall_args *scargs);
scret_t sys_write(struct syscall_args *sargs);
scret_t sys_stat(struct syscall_args *scargs);
+scret_t sys_access(struct syscall_args *scargs);
#endif /* _KERNEL */
#endif /* !_SYS_VFS_H_ */
diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h
index 33092f9..1a6b2aa 100644
--- a/sys/include/sys/vnode.h
+++ b/sys/include/sys/vnode.h
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/queue.h>
+#include <sys/vnode.h>
#include <sys/atomic.h>
#include <sys/sio.h>
#include <vm/vm_obj.h>
@@ -47,6 +48,8 @@ struct vnode {
const struct vops *vops;
struct vm_object vobj;
uint32_t refcount;
+ dev_t major;
+ dev_t dev;
TAILQ_ENTRY(vnode) vcache_link;
};
@@ -83,6 +86,13 @@ struct vop_lookup_args {
struct vnode **vpp; /* Result vnode */
};
+struct vop_create_args {
+ const char *path; /* Full path */
+ const char *ppath; /* Parent path */
+ struct vnode *dirvp; /* Directory vnode */
+ struct vnode **vpp; /* Result vnode */
+};
+
/*
* A field in this structure is unavailable
* if it has a value of VNOVAL.
@@ -103,6 +113,7 @@ struct vops {
int(*read)(struct vnode *vp, struct sio_txn *sio);
int(*write)(struct vnode *vp, struct sio_txn *sio);
int(*reclaim)(struct vnode *vp);
+ int(*create)(struct vop_create_args *args);
};
extern struct vnode *g_root_vnode;
diff --git a/sys/include/vm/pmap.h b/sys/include/vm/pmap.h
index 9eed184..e0549d4 100644
--- a/sys/include/vm/pmap.h
+++ b/sys/include/vm/pmap.h
@@ -76,9 +76,25 @@ int pmap_map(struct vas vas, vaddr_t va, paddr_t pa, vm_prot_t prot);
int pmap_unmap(struct vas vas, vaddr_t va);
/*
+ * Returns true if the page is clean (modified), otherwise
+ * returns false.
+ */
+bool pmap_is_clean(struct vas vas, vaddr_t va);
+
+/*
+ * Marks a page as clean (unmodified)
+ */
+void pmap_mark_clean(struct vas vas, vaddr_t va);
+
+/*
* Mark a virtual address with a specific
* caching type.
*/
int pmap_set_cache(struct vas vas, vaddr_t va, int type);
+/*
+ * Machine dependent pmap init code.
+ */
+int pmap_init(void);
+
#endif /* !_VM_PMAP_H_ */
diff --git a/sys/include/vm/vm_device.h b/sys/include/vm/vm_device.h
new file mode 100644
index 0000000..da476e2
--- /dev/null
+++ b/sys/include/vm/vm_device.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VM_DEVICE_H_
+#define _VM_DEVICE_H_
+
+#include <sys/types.h>
+#include <sys/vnode.h>
+#include <sys/device.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_obj.h>
+
+extern const struct vm_pagerops vm_vnops;
+
+struct vm_object *dv_attach(devmajor_t major, dev_t dev, vm_prot_t prot);
+
+#endif /* !_VM_DEVICE_H_ */