From b51b8c7b1bceb42e13a732c3dec229421ed1faf0 Mon Sep 17 00:00:00 2001 From: break27 Date: Sun, 1 Jun 2025 12:34:17 +0800 Subject: [PATCH] initial commit --- .gitignore | 3 ++ .zigversion | 1 + build.zig | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ build.zig.zon | 61 ++++++++++++++++++++++++++++++++++++++ src/root.zig | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 221 insertions(+) create mode 100644 .gitignore create mode 100644 .zigversion create mode 100644 build.zig create mode 100644 build.zig.zon create mode 100644 src/root.zig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f73c045 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.vscode +/.zig-cache +/zig-out \ No newline at end of file diff --git a/.zigversion b/.zigversion new file mode 100644 index 0000000..0548fb4 --- /dev/null +++ b/.zigversion @@ -0,0 +1 @@ +0.14.0 \ No newline at end of file diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..2cbe40c --- /dev/null +++ b/build.zig @@ -0,0 +1,81 @@ +const std = @import("std"); + +// Although this function looks imperative, note that its job is to +// declaratively construct a build graph that will be executed by an external +// runner. +pub fn build(b: *std.Build) !void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard optimization options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not + // set a preferred release mode, allowing the user to decide how to optimize. + const optimize = b.standardOptimizeOption(.{}); + + // This creates a "module", which represents a collection of source files alongside + // some compilation options, such as optimization mode and linked system libraries. + // Every executable or library we compile will be based on one or more modules. + const mod = b.addModule("acpi", .{ + // `root_source_file` is the Zig "entry point" of the module. If a module + // only contains e.g. external object files, you can make this `null`. + // In this case the main source file is merely a path, however, in more + // complicated build scripts, this could be a generated file. + .root_source_file = b.path("src/root.zig"), + .target = target, + .optimize = optimize, + }); + + const uacpi = b.dependency("uacpi", .{}); + var flags: std.ArrayList([]const u8) = .init(b.allocator); + + for (b.debug_log_scopes) |scope| { + if (std.mem.eql(u8, scope, "uacpi")) { + try flags.append("-DUACPI_DEFAULT_LOG_LEVEL=UACPI_LOG_TRACE"); + break; + } + } + + mod.addIncludePath(uacpi.path("include")); + mod.addCSourceFiles(.{ + .root = uacpi.path("source"), + .files = &.{ + "default_handlers.c", + "event.c", + "interpreter.c", + "io.c", + "mutex.c", + "namespace.c", + "notify.c", + "opcodes.c", + "opregion.c", + "osi.c", + "registers.c", + "resources.c", + "shareable.c", + "sleep.c", + "stdlib.c", + "tables.c", + "types.c", + "uacpi.c", + "utilities.c", + }, + .flags = try flags.toOwnedSlice(), + }); + + // Creates a step for unit testing. This only builds the test executable + // but does not run it. + const unit_tests = b.addTest(.{ + .root_module = mod, + }); + + const run_unit_tests = b.addRunArtifact(unit_tests); + + // Similar to creating the run step earlier, this exposes a `test` step to + // the `zig build --help` menu, providing a way for the user to request + // running the unit tests. + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&run_unit_tests.step); +} diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..0e400bf --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,61 @@ +.{ + // This is the default name used by packages depending on this one. For + // example, when a user runs `zig fetch --save `, this field is used + // as the key in the `dependencies` table. Although the user can choose a + // different name, most users will stick with this provided value. + // + // It is redundant to include "zig" in this name because it is already + // within the Zig package namespace. + .name = .acpi, + + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.0.1", + + // Together with name, this represents a globally unique package + // identifier. This field is generated by the Zig toolchain when the + // package is first created, and then *never changes*. This allows + // unambiguous detection of one package being an updated version of + // another. + // + // When forking a Zig project, this id should be regenerated (delete the + // field and run `zig build`) if the upstream project is still maintained. + // Otherwise, the fork is *hostile*, attempting to take control over the + // original project's identity. Thus it is recommended to leave the comment + // on the following line intact, so that it shows up in code reviews that + // modify the field. + .fingerprint = 0xf31e9a09992d882e, // Changing this has security and trust implications. + + // Tracks the earliest Zig version that the package considers to be a + // supported use case. + .minimum_zig_version = "0.14.0", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{ + .uacpi = .{ + .url = "https://github.com/uACPI/uACPI/archive/refs/tags/1.0.1.tar.gz", + .hash = "N-V-__8AACLYEgAEaPtnHAQiXwTYfg_hEx5JzNFT6HC-boWN", + }, + }, + + // Specifies the set of files and directories that are included in this package. + // Only files and directories listed here are included in the `hash` that + // is computed for this package. Only files listed here will remain on disk + // when using the zig package manager. As a rule of thumb, one should list + // files required for compilation plus any license(s). + // Paths are relative to the build root. Use the empty string (`""`) to refer to + // the build root itself. + // A directory listed here means that all files within, recursively, are included. + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + // For example... + //"LICENSE", + //"README.md", + }, +} diff --git a/src/root.zig b/src/root.zig new file mode 100644 index 0000000..b7370d4 --- /dev/null +++ b/src/root.zig @@ -0,0 +1,75 @@ +const C = @cImport({ + @cInclude("uacpi/event.h"); + @cInclude("uacpi/io.h"); + @cInclude("uacpi/namespace.h"); + @cInclude("uacpi/notify.h"); + @cInclude("uacpi/opregion.h"); + @cInclude("uacpi/osi.h"); + @cInclude("uacpi/resources.h"); + @cInclude("uacpi/sleep.h"); + @cInclude("uacpi/status.h"); + @cInclude("uacpi/tables.h"); + @cInclude("uacpi/types.h"); + @cInclude("uacpi/uacpi.h"); + @cInclude("uacpi/utilities.h"); +}); + +pub const Status = enum(C.uacpi_status) { + ok = C.UACPI_STATUS_OK, + mapping_failed = C.UACPI_STATUS_MAPPING_FAILED, + out_of_memory = C.UACPI_STATUS_OUT_OF_MEMORY, + bad_checksum = C.UACPI_STATUS_BAD_CHECKSUM, + invalid_signature = C.UACPI_STATUS_INVALID_SIGNATURE, + invalid_table_length = C.UACPI_STATUS_INVALID_TABLE_LENGTH, + not_found = C.UACPI_STATUS_NOT_FOUND, + invalid_argument = C.UACPI_STATUS_INVALID_ARGUMENT, + unimplemented = C.UACPI_STATUS_UNIMPLEMENTED, + already_exists = C.UACPI_STATUS_ALREADY_EXISTS, + internal_error = C.UACPI_STATUS_INTERNAL_ERROR, + type_mismatch = C.UACPI_STATUS_TYPE_MISMATCH, + init_level_mismatch = C.UACPI_STATUS_INIT_LEVEL_MISMATCH, + namespace_node_dangling = C.UACPI_STATUS_NAMESPACE_NODE_DANGLING, + no_handler = C.UACPI_STATUS_NO_HANDLER, + no_resource_end_tag = C.UACPI_STATUS_NO_RESOURCE_END_TAG, + compiled_out = C.UACPI_STATUS_COMPILED_OUT, + hardware_timeout = C.UACPI_STATUS_HARDWARE_TIMEOUT, + timeout = C.UACPI_STATUS_TIMEOUT, + overridden = C.UACPI_STATUS_OVERRIDDEN, + denied = C.UACPI_STATUS_DENIED, + + // All errors that have bytecode-related origin should go here + aml_undefined_reference = C.UACPI_STATUS_AML_UNDEFINED_REFERENCE, + aml_invalid_namestring = C.UACPI_STATUS_AML_INVALID_NAMESTRING, + aml_object_already_exists = C.UACPI_STATUS_AML_OBJECT_ALREADY_EXISTS, + aml_invalid_opcode = C.UACPI_STATUS_AML_INVALID_OPCODE, + aml_incompatible_object_type = C.UACPI_STATUS_AML_INCOMPATIBLE_OBJECT_TYPE, + aml_bad_encoding = C.UACPI_STATUS_AML_BAD_ENCODING, + aml_out_of_bounds_index = C.UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX, + aml_sync_level_too_high = C.UACPI_STATUS_AML_SYNC_LEVEL_TOO_HIGH, + aml_invalid_resource = C.UACPI_STATUS_AML_INVALID_RESOURCE, + aml_loop_timeout = C.UACPI_STATUS_AML_LOOP_TIMEOUT, + aml_call_stack_depth_limit = C.UACPI_STATUS_AML_CALL_STACK_DEPTH_LIMIT, +}; + +pub const InterruptResult = enum(C.uacpi_interrupt_ret) { + not_handled = C.UACPI_INTERRUPT_NOT_HANDLED, + handled = C.UACPI_INTERRUPT_HANDLED, +}; + +pub const LogLevel = enum(C.uacpi_log_level) { + debug = C.UACPI_LOG_DEBUG, + err = C.UACPI_LOG_ERROR, + info = C.UACPI_LOG_INFO, + trace = C.UACPI_LOG_TRACE, + warn = C.UACPI_LOG_WARN, +}; + +pub const InterruptHandler = *const fn(Handle) callconv(.C) InterruptResult; + +pub const Handle = C.uacpi_handle; +pub const CpuFlags = C.uacpi_cpu_flags; +pub const PhysAddr = C.uacpi_phys_addr; +pub const ThreadId = C.uacpi_thread_id; +pub const WorkType = C.uacpi_work_type; +pub const PciAddress = C.uacpi_pci_address; +pub const WorkHandler = C.uacpi_work_handler; \ No newline at end of file