diff --git a/.gitignore b/.gitignore
index eb5a316c..77746140 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
target
+/config.toml
+.gitlab-ci-local/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..f3efafbe
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,30 @@
+image: "redoxos/redoxer:latest"
+
+variables:
+ GIT_SUBMODULE_STRATEGY: recursive
+
+stages:
+ - host
+ - build
+ - test
+ # TODO: benchmarks and profiling (maybe manually enabled for relevant MRs)?
+
+build:
+ stage: build
+ script:
+ - mkdir -p target/${ARCH}
+ - TARGET=${ARCH}-unknown-redox redoxer env make BUILD=target/${ARCH}
+ parallel:
+ matrix:
+ - ARCH: [x86_64, i686, aarch64, riscv64gc]
+
+fmt:
+ stage: host
+ script:
+ - rustup component add rustfmt-preview
+ - cargo fmt -- --check
+
+unit_test:
+ stage: test
+ script:
+ - TARGET=x86_64-unknown-redox redoxer test
diff --git a/.gitmodules b/.gitmodules
index 94e58ada..0a0f6ac8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,11 @@
-[submodule "syscall"]
- path = syscall
- url = https://gitlab.redox-os.org/redox-os/syscall.git
[submodule "slab_allocator"]
path = slab_allocator
url = https://gitlab.redox-os.org/redox-os/slab_allocator
+[submodule "rmm"]
+ path = rmm
+ url = https://gitlab.redox-os.org/redox-os/rmm.git
+ branch = master
+[submodule "redox-path"]
+ path = redox-path
+ url = https://gitlab.redox-os.org/redox-os/redox-path.git
+ branch = main
diff --git a/.helix/config.toml b/.helix/config.toml
new file mode 100644
index 00000000..a1ec3e0a
--- /dev/null
+++ b/.helix/config.toml
@@ -0,0 +1,2 @@
+[editor]
+auto-format = false
diff --git a/.helix/languages.toml b/.helix/languages.toml
new file mode 100644
index 00000000..c86c7b8a
--- /dev/null
+++ b/.helix/languages.toml
@@ -0,0 +1,13 @@
+[[language]]
+name = "rust"
+
+[[language-server.rust-analyzer.config.cargo]]
+extraEnv = ["RUST_TARGET_PATH=targets"]
+# Select one of targets to make lsp work for your confguration
+# Do not commit this change
+# TODO: find a better way to do this
+# target = "aarch64-unknown-kernel"
+
+[[language-server.rust-analyzer.config.check]]
+targets = ["x86_64-unknown-kernel", "i686-unknown-kernel", "aarch64-unknown-kernel"]
+
diff --git a/Cargo.lock b/Cargo.lock
index db7f9e16..be23923f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,552 +1,502 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 4
+
[[package]]
-name = "aho-corasick"
-version = "0.7.3"
+name = "ahash"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
- "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if",
+ "once_cell",
+ "version_check",
+ "zerocopy",
]
[[package]]
-name = "ansi_term"
-version = "0.11.0"
+name = "arrayvec"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "autocfg"
-version = "0.1.2"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
-name = "backtrace"
-version = "0.3.15"
+name = "bit_field"
+version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
-name = "backtrace-sys"
-version = "0.1.28"
+name = "bitfield"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
name = "bitflags"
-version = "0.7.0"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "0.9.1"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
-name = "bitflags"
-version = "1.0.4"
+name = "byteorder"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
-name = "cargo_metadata"
-version = "0.5.8"
+name = "cc"
+version = "1.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
dependencies = [
- "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "shlex",
]
-[[package]]
-name = "cc"
-version = "1.0.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "cfg-if"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "clippy"
-version = "0.0.209"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy_lints 0.0.209 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "clippy_lints"
-version = "0.0.209"
+name = "equivalent"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
-name = "either"
-version = "1.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+name = "fdt"
+version = "0.2.0-alpha1"
+source = "git+https://github.com/repnop/fdt.git?rev=2fb1409edd1877c714a0aa36b6a7c5351004be54#2fb1409edd1877c714a0aa36b6a7c5351004be54"
[[package]]
-name = "error-chain"
-version = "0.11.0"
+name = "goblin"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884"
dependencies = [
- "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plain",
+ "scroll",
]
[[package]]
-name = "getopts"
-version = "0.2.18"
+name = "hashbrown"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
- "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ahash",
]
[[package]]
-name = "goblin"
-version = "0.0.21"
+name = "hashbrown"
+version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
[[package]]
-name = "idna"
-version = "0.1.5"
+name = "indexmap"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "equivalent",
+ "hashbrown 0.15.3",
]
[[package]]
-name = "if_chain"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+name = "kernel"
+version = "0.5.12"
+dependencies = [
+ "arrayvec",
+ "bitfield",
+ "bitflags 2.9.0",
+ "byteorder",
+ "cc",
+ "fdt",
+ "goblin",
+ "hashbrown 0.14.5",
+ "indexmap",
+ "linked_list_allocator 0.9.1",
+ "log",
+ "raw-cpuid",
+ "redox-path",
+ "redox_syscall",
+ "rmm",
+ "rustc-cfg",
+ "rustc-demangle",
+ "sbi-rt",
+ "slab",
+ "slab_allocator",
+ "spin 0.9.8",
+ "spinning_top 0.3.0",
+ "toml",
+ "x86",
+]
[[package]]
-name = "itertools"
-version = "0.7.11"
+name = "linked_list_allocator"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47de1a43fad0250ee197e9e124e5b5deab3d7b39d4428ae8a6d741ceb340c362"
dependencies = [
- "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "spin 0.5.2",
]
[[package]]
-name = "itoa"
-version = "0.4.3"
+name = "linked_list_allocator"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "kernel"
-version = "0.1.54"
+checksum = "549ce1740e46b291953c4340adcd74c59bcf4308f4cac050fd33ba91b7168f4a"
dependencies = [
- "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy 0.0.209 (registry+https://github.com/rust-lang/crates.io-index)",
- "goblin 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "raw-cpuid 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.56",
- "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "slab_allocator 0.3.1",
- "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "x86 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "spinning_top 0.2.5",
]
[[package]]
-name = "lazy_static"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "libc"
-version = "0.2.51"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "linked_list_allocator"
-version = "0.6.4"
+name = "lock_api"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
- "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg",
+ "scopeguard",
]
[[package]]
-name = "matches"
-version = "0.1.8"
+name = "log"
+version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
-version = "2.2.0"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
-name = "percent-encoding"
-version = "1.0.1"
+name = "once_cell"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "plain"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
[[package]]
name = "proc-macro2"
-version = "0.4.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "pulldown-cmark"
-version = "0.1.2"
+version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
- "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-ident",
]
-[[package]]
-name = "quine-mc_cluskey"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "quote"
-version = "0.6.11"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
- "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
]
[[package]]
name = "raw-cpuid"
-version = "2.0.2"
+version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.3.2",
]
[[package]]
-name = "raw-cpuid"
-version = "4.0.0"
+name = "redox-path"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7"
[[package]]
name = "redox_syscall"
-version = "0.1.56"
-
-[[package]]
-name = "regex"
-version = "1.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.5.12"
+source = "git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=master#fe32c6b89dae51e609d5c53880dec1834ec9bde0"
dependencies = [
- "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 2.9.0",
]
[[package]]
-name = "regex-syntax"
-version = "0.6.6"
+name = "rmm"
+version = "0.1.0"
+
+[[package]]
+name = "rustc-cfg"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ddf7a5e441e8003a5a88aab97f1c6113043ddde252d789ef9dea3871b78633a"
dependencies = [
- "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thiserror",
]
[[package]]
name = "rustc-demangle"
-version = "0.1.13"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
-name = "rustc_version"
-version = "0.2.3"
+name = "sbi-rt"
+version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0"
dependencies = [
- "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "sbi-spec",
]
[[package]]
-name = "ryu"
-version = "0.2.7"
+name = "sbi-spec"
+version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "scroll"
-version = "0.9.2"
+version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec"
[[package]]
-name = "semver"
-version = "0.9.0"
+name = "serde"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
- "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive",
]
[[package]]
-name = "semver-parser"
-version = "0.7.0"
+name = "serde_derive"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
[[package]]
-name = "serde"
-version = "1.0.90"
+name = "serde_spanned"
+version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+dependencies = [
+ "serde",
+]
[[package]]
-name = "serde_derive"
-version = "1.0.90"
+name = "shlex"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)",
-]
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
-name = "serde_json"
-version = "1.0.39"
+name = "slab"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
- "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg",
]
[[package]]
name = "slab_allocator"
version = "0.3.1"
dependencies = [
- "linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "linked_list_allocator 0.6.6",
+ "spin 0.4.10",
]
-[[package]]
-name = "smallvec"
-version = "0.6.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "spin"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f"
[[package]]
name = "spin"
-version = "0.5.0"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
-name = "syn"
-version = "0.15.30"
+name = "spin"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
- "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lock_api",
]
[[package]]
-name = "thread_local"
-version = "0.3.6"
+name = "spinning_top"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
dependencies = [
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lock_api",
]
[[package]]
-name = "toml"
-version = "0.4.10"
+name = "spinning_top"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
dependencies = [
- "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lock_api",
]
[[package]]
-name = "ucd-util"
-version = "0.1.3"
+name = "syn"
+version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
[[package]]
-name = "unicode-bidi"
-version = "0.3.4"
+name = "thiserror"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thiserror-impl",
]
[[package]]
-name = "unicode-normalization"
-version = "0.1.8"
+name = "thiserror-impl"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
- "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
-name = "unicode-width"
-version = "0.1.5"
+name = "toml"
+version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
[[package]]
-name = "unicode-xid"
-version = "0.1.0"
+name = "toml_datetime"
+version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
+dependencies = [
+ "serde",
+]
[[package]]
-name = "url"
-version = "1.7.2"
+name = "toml_edit"
+version = "0.22.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
dependencies = [
- "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_write",
+ "winnow",
]
[[package]]
-name = "utf8-ranges"
-version = "1.0.2"
+name = "toml_write"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
[[package]]
-name = "winapi"
-version = "0.3.7"
+name = "unicode-ident"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "winnow"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
dependencies = [
- "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr",
]
[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
+name = "x86"
+version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55b5be8cc34d017d8aabec95bc45a43d0f20e8b2a31a453cabc804fe996f8dca"
+dependencies = [
+ "bit_field",
+ "bitflags 1.3.2",
+ "raw-cpuid",
+]
[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
+name = "zerocopy"
+version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+dependencies = [
+ "zerocopy-derive",
+]
[[package]]
-name = "x86"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "raw-cpuid 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[metadata]
-"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c"
-"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
-"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637"
-"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
-"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
-"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
-"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
-"checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0"
-"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83"
-"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
-"checksum clippy 0.0.209 (registry+https://github.com/rust-lang/crates.io-index)" = "fe56cba96f8d67cd3af996bd2c61fbfea263cc555db9180dc1f7413418454c7d"
-"checksum clippy_lints 0.0.209 (registry+https://github.com/rust-lang/crates.io-index)" = "891679ac4d0890425ce9aa4db6ab7c05a60506048fb5e0fc2ae2eeaeb02626e8"
-"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
-"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
-"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
-"checksum goblin 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6a4013e9182f2345c6b7829b9ef6e670bce0dfca12c6f974457ed2160c2c7fe9"
-"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-"checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
-"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
-"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
-"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
-"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
-"checksum linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "47314ec1d29aa869ee7cb5a5be57be9b1055c56567d59c3fb6689926743e0bea"
-"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
-"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
-"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
-"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
-"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
-"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
-"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
-"checksum raw-cpuid 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13b844e4049605ff38fed943f5c7b2c691fad68d9d5bf074d2720554c4e48246"
-"checksum raw-cpuid 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90e0d3209fac374e168cef2d8806dde7b31ef0ee82a965bcc0bec562c078a6f5"
-"checksum regex 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "559008764a17de49a3146b234641644ed37d118d1ef641a0bb573d146edc6ce0"
-"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96"
-"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
-"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
-"checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
-"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4"
-"checksum serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "58fc82bec244f168b23d1963b45c8bf5726e9a15a9d146a067f9081aeed2de79"
-"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
-"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
-"checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f"
-"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
-"checksum syn 0.15.30 (registry+https://github.com/rust-lang/crates.io-index)" = "66c8865bf5a7cbb662d8b011950060b3c8743dca141b054bf7195b20d314d8e2"
-"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
-"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
-"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
-"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
-"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
-"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
-"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
-"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
-"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
-"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
-"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-"checksum x86 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "178718d3f2c7dd98d44f8e353b0ccc8c89b2e81e31e5eed93e7fdf5f36db7a13"
+name = "zerocopy-derive"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/Cargo.toml b/Cargo.toml
index fc579efd..9ea701a0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,44 +1,91 @@
[package]
name = "kernel"
-version = "0.1.54"
+version = "0.5.12"
build = "build.rs"
-edition = "2018"
+edition = "2021"
-[lib]
-name = "kernel"
-path = "src/lib.rs"
-crate-type = ["staticlib"]
+[build-dependencies]
+cc = "1.0"
+rustc-cfg = "0.5"
+toml = "0.8"
[dependencies]
-bitflags = "1.0.3"
-clippy = { version = "0.0.209", optional = true }
-linked_list_allocator = "0.6.2"
-raw-cpuid = "4.0.0"
-redox_syscall = { path = "syscall" }
+bitflags = "2"
+bitfield = "0.13.2"
+hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "inline-more"] }
+linked_list_allocator = "0.9.0"
+log = "0.4"
+redox-path = "0.2.0"
+redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git", branch = "master", default-features = false }
slab_allocator = { path = "slab_allocator", optional = true }
-spin = "0.4.8"
+spin = "0.9.8"
+spinning_top = { version = "0.3", features = ["arc_lock"] }
+rmm = { path = "rmm", default-features = false }
+arrayvec = { version = "0.7.4", default-features = false }
+slab = { version = "0.4", default-features = false }
+# TODO: Remove
+indexmap = { version = "2.5.0", default-features = false }
[dependencies.goblin]
-version = "0.0.21"
+version = "0.2.1"
default-features = false
features = ["elf32", "elf64"]
[dependencies.rustc-demangle]
-version = "0.1.13"
+version = "0.1.16"
default-features = false
-[dependencies.x86]
-version = "0.9.0"
-default-features = false
+[target.'cfg(any(target_arch = "aarch64", target_arch = "riscv64"))'.dependencies]
+byteorder = { version = "1", default-features = false }
+fdt = { git = "https://github.com/repnop/fdt.git", rev = "2fb1409edd1877c714a0aa36b6a7c5351004be54" }
+
+[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
+raw-cpuid = "10.2.0"
+x86 = { version = "0.47.0", default-features = false }
+
+[target.'cfg(any(target_arch = "riscv64", target_arch = "riscv32"))'.dependencies]
+sbi-rt = "0.0.3"
[features]
-default = ["serial_debug"]
+default = [
+ "acpi",
+ #TODO: issues with Alder Lake and newer CPUs: "multi_core",
+ "graphical_debug",
+ "serial_debug",
+ "self_modifying",
+ "x86_kvm_pv",
+]
+
+# Activates some limited code-overwriting optimizations, based on CPU features.
+self_modifying = []
+
acpi = []
-doc = []
graphical_debug = []
-live = []
-multi_core = []
+lpss_debug = []
+multi_core = ["acpi"]
+profiling = []
+#TODO: remove when threading issues are fixed
pti = []
qemu_debug = []
serial_debug = []
+system76_ec_debug = []
slab = ["slab_allocator"]
+sys_stat = []
+x86_kvm_pv = []
+
+debugger = ["syscall_debug"]
+syscall_debug = []
+
+sys_fdstat = []
+
+[profile.dev]
+# Avoids having to define the eh_personality lang item and reduces kernel size
+panic = "abort"
+
+[profile.release]
+# Avoids having to define the eh_personality lang item and reduces kernel size
+panic = "abort"
+
+lto = true
+
+debug = "full"
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..5703ee2f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
+SOURCE:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
+BUILD?=$(CURDIR)
+export RUST_TARGET_PATH=$(SOURCE)/targets
+
+ifeq ($(TARGET),)
+ ARCH?=$(shell uname -m)
+else
+ ARCH?=$(shell echo "$(TARGET)" | cut -d - -f1)
+endif
+
+ifeq ($(ARCH),riscv64gc)
+ override ARCH:=riscv64
+endif
+GNU_TARGET=$(ARCH)-unknown-redox
+
+
+all: $(BUILD)/kernel $(BUILD)/kernel.sym
+
+LD_SCRIPT=$(SOURCE)/linkers/$(ARCH).ld
+TARGET_SPEC=$(RUST_TARGET_PATH)/$(ARCH)-unknown-kernel.json
+
+$(BUILD)/kernel.all: $(LD_SCRIPT) $(TARGET_SPEC) $(shell find $(SOURCE) -name "*.rs" -type f)
+ cargo rustc \
+ --bin kernel \
+ --manifest-path "$(SOURCE)/Cargo.toml" \
+ --target "$(TARGET_SPEC)" \
+ --release \
+ -Z build-std=core,alloc \
+ -- \
+ -C link-arg=-T -Clink-arg="$(LD_SCRIPT)" \
+ -C link-arg=-z -Clink-arg=max-page-size=0x1000 \
+ --emit link="$(BUILD)/kernel.all"
+
+$(BUILD)/kernel.sym: $(BUILD)/kernel.all
+ $(GNU_TARGET)-objcopy \
+ --only-keep-debug \
+ "$(BUILD)/kernel.all" \
+ "$(BUILD)/kernel.sym"
+
+$(BUILD)/kernel: $(BUILD)/kernel.all
+ $(GNU_TARGET)-objcopy \
+ --strip-debug \
+ "$(BUILD)/kernel.all" \
+ "$(BUILD)/kernel"
diff --git a/README.md b/README.md
index 8bf172e7..cf54d099 100644
--- a/README.md
+++ b/README.md
@@ -1,46 +1,81 @@
-# kernel
+# Kernel
Redox OS Microkernel
+[](https://docs.rs/redox_syscall/latest/syscall/)
+[](https://github.com/XAMPPRocky/tokei)
[](./LICENSE)
-[](https://doc.redox-os.org/kernel/kernel/)
-[](https://github.com/Aaronepower/tokei)
-## Debugging the redox kernel
+## Requirements
-Running [qemu] with the `-s` flag will set up [qemu] to listen on port 1234 for
-a [gdb] client to connect to it. To debug the redox kernel run.
+* [`nasm`](https://nasm.us/) needs to be available on the PATH at build time.
+## Building The Documentation
+
+Use this command:
+
+```sh
+cargo doc --open --target x86_64-unknown-none
```
-make qemu debug=yes
+
+## Debugging
+
+### QEMU
+
+Running [QEMU](https://www.qemu.org) with the `-s` flag will set up QEMU to listen on port `1234` for a GDB client to connect to it. To debug the redox kernel run.
+
+```sh
+make qemu gdb=yes
```
-This will start a VM with and listen on port 1234 for a [gdb] or [lldb] client.
+This will start a virtual machine with and listen on port `1234` for a GDB or LLDB client.
-## [gdb]
+### GDB
-If you are going to use [gdb], run the following to load debug symbols and connect
-to your running kernel.
+If you are going to use [GDB](https://www.gnu.org/software/gdb/), run these commands to load debug symbols and connect to your running kernel:
```
(gdb) symbol-file build/kernel.sym
(gdb) target remote localhost:1234
```
-## [lldb]
+### LLDB
-If you are going to use [lldb], run the following to start debugging.
+If you are going to use [LLDB](https://lldb.llvm.org/), run these commands to start debugging:
```
(lldb) target create -s build/kernel.sym build/kernel
(lldb) gdb-remote localhost:1234
```
-## Debugging
-
After connecting to your kernel you can set some interesting breakpoints and `continue`
the process. See your debuggers man page for more information on useful commands to run.
-[qemu]: https://www.qemu.org
-[gdb]: https://www.gnu.org/software/gdb/
-[lldb]: https://lldb.llvm.org/
+## Notes
+
+- Always use `foo.get(n)` instead of `foo[n]` and try to cover for the possibility of `Option::None`. Doing the regular way may work fine for applications, but never in the kernel. No possible panics should ever exist in kernel space, because then the whole OS would just stop working.
+
+- If you receive a kernel panic in QEMU, use `pkill qemu-system` to kill the frozen QEMU process.
+
+## How To Contribute
+
+To learn how to contribute to this system component you need to read the following document:
+
+- [CONTRIBUTING.md](https://gitlab.redox-os.org/redox-os/redox/-/blob/master/CONTRIBUTING.md)
+
+## Development
+
+To learn how to do development with this system component inside the Redox build system you need to read the [Build System](https://doc.redox-os.org/book/build-system-reference.html) and [Coding and Building](https://doc.redox-os.org/book/coding-and-building.html) pages.
+
+### How To Build
+
+To build this system component you need to download the Redox build system, you can learn how to do it on the [Building Redox](https://doc.redox-os.org/book/podman-build.html) page.
+
+This is necessary because they only work with cross-compilation to a Redox virtual machine, but you can do some testing from Linux.
+
+## Funding - _Unix-style Signals and Process Management_
+
+This project is funded through [NGI Zero Core](https://nlnet.nl/core), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/RedoxOS-Signals).
+
+[
](https://nlnet.nl)
+[
](https://nlnet.nl/core)
diff --git a/Xargo.toml b/Xargo.toml
deleted file mode 100644
index ea3144eb..00000000
--- a/Xargo.toml
+++ /dev/null
@@ -1 +0,0 @@
-[dependencies.alloc]
diff --git a/build.rs b/build.rs
index acc24d22..2b326211 100644
--- a/build.rs
+++ b/build.rs
@@ -1,124 +1,90 @@
-use std::env;
-use std::fs;
-use std::io::{Error, Write};
-use std::path::Path;
-use std::collections::HashMap;
+use rustc_cfg::Cfg;
+use std::{env, path::Path, process::Command};
+use toml::Table;
+fn parse_kconfig(arch: &str) -> Option<()> {
+ println!("cargo:rerun-if-changed=config.toml");
-// View loc folder with subfolders, get listings
-// Returns touple (folder_map, file_list)
-// folder_map keys are folders, and values are lists of direct childs
-// file_list is a vector of all detected files with full path
-fn scan_folder(loc: &Path) -> (HashMap>, Vec) {
- let mut folders: HashMap> = HashMap::new();
- let mut files: Vec = Vec::new();
- let mut current = Vec::new();
-
- if loc.is_dir() {
- for entry in fs::read_dir(loc).unwrap() {
- let entry = entry.unwrap();
- let path = entry.path();
- let path_str = String::from(path.to_str().unwrap()).replace("\\", "/");
-
- current.push(path_str.clone());
-
- // if folder then scan recursively
- if path.is_dir() {
- let (d, mut f) = scan_folder(&path);
- for (key, value) in d.into_iter() {
- folders.insert(key, value);
- }
-
- files.append(&mut f);
- } else {
- files.push(path_str);
- }
- }
-
- current.sort();
- folders.entry(String::from(loc.to_str().unwrap()).replace("\\", "/")).or_insert(current);
- } else {
- panic!("{:?} is not a folder!", loc);
- }
-
- (folders, files)
-}
-
-// Write folder/file information to output file
-fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> {
- let (folders, mut files) = scan_folder(loc);
- let mut folder_it:Vec<_> = folders.keys().collect();
-
- let loc_str = loc.to_str().unwrap();
- let mut idx = loc_str.len();
-
- if !loc_str.ends_with("/") {
- idx += 1;
+ assert!(Path::new("config.toml.example").try_exists().unwrap());
+ if !Path::new("config.toml").try_exists().unwrap() {
+ std::fs::copy("config.toml.example", "config.toml").unwrap();
}
-
- folder_it.sort();
- files.sort();
- for dir in folder_it.iter() {
- let strip: String = dir.chars().skip(idx).collect();
- write!(f, " files.insert(b\"{}\", (b\"", strip)?;
-
- // Write child elements separated with \n
- let sub = folders.get(*dir).unwrap();
- let mut first = true;
- for child in sub.iter() {
- let idx = child.rfind('/').unwrap() + 1;
- let (_, c) = child.split_at(idx);
- if first {
- write!(f, "{}", c)?;
- first = false;
- } else {
- write!(f, "\\n{}", c)?;
- }
+ let config_str = std::fs::read_to_string("config.toml").unwrap();
+ let root: Table = toml::from_str(&config_str).unwrap();
+
+ let altfeatures = root
+ .get("arch")?
+ .as_table()
+ .unwrap()
+ .get(arch)?
+ .as_table()
+ .unwrap()
+ .get("features")?
+ .as_table()
+ .unwrap();
+
+ let self_modifying = env::var("CARGO_FEATURE_SELF_MODIFYING").is_ok();
+
+ for (name, value) in altfeatures {
+ let mut choice = value.as_str().unwrap();
+ assert!(matches!(choice, "always" | "never" | "auto"));
+
+ if !self_modifying && choice == "auto" {
+ choice = "never";
}
- write!(f, "\", true));\n")?;
- }
- for name in files.iter() {
- let (_, strip) = name.split_at(idx);
- write!(f, " files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n", strip, name)?;
+ println!("cargo:rustc-cfg=cpu_feature_{choice}=\"{name}\"");
}
- Ok(())
+ Some(())
}
fn main() {
println!("cargo:rustc-env=TARGET={}", env::var("TARGET").unwrap());
- println!("cargo:rerun-if-env-changed=INITFS_FOLDER");
let out_dir = env::var("OUT_DIR").unwrap();
- let dest_path = Path::new(&out_dir).join("gen.rs");
- let mut f = fs::File::create(&dest_path).unwrap();
- let src = env::var("INITFS_FOLDER");
-
- // Write header
- f.write_all(b"
-mod gen {
- use alloc::collections::BTreeMap;
- pub fn gen() -> BTreeMap<&'static [u8], (&'static [u8], bool)> {
- let mut files: BTreeMap<&'static [u8], (&'static [u8], bool)> = BTreeMap::new();
-").unwrap();
+ let cfg = Cfg::of(env::var("TARGET").unwrap().as_str()).unwrap();
+ let arch_str = cfg.target_arch.as_str();
- match src {
- Ok(v) => {
- println!("cargo:rerun-if-changed={}", v);
- fill_from_location(&mut f, Path::new(&v)).unwrap()
- },
- Err(e) => {
- f.write_all(
- b" files.clear();" // Silence mutability warning
- ).unwrap();
- println!("cargo:warning=location not found: {}, please set proper INITFS_FOLDER.", e);
+ match arch_str {
+ "aarch64" => {
+ println!("cargo:rustc-cfg=dtb");
+ }
+ "x86" => {
+ println!("cargo:rerun-if-changed=src/asm/x86/trampoline.asm");
+
+ let status = Command::new("nasm")
+ .arg("-f")
+ .arg("bin")
+ .arg("-o")
+ .arg(format!("{}/trampoline", out_dir))
+ .arg("src/asm/x86/trampoline.asm")
+ .status()
+ .expect("failed to run nasm");
+ if !status.success() {
+ panic!("nasm failed with exit status {}", status);
+ }
+ }
+ "x86_64" => {
+ println!("cargo:rerun-if-changed=src/asm/x86_64/trampoline.asm");
+
+ let status = Command::new("nasm")
+ .arg("-f")
+ .arg("bin")
+ .arg("-o")
+ .arg(format!("{}/trampoline", out_dir))
+ .arg("src/asm/x86_64/trampoline.asm")
+ .status()
+ .expect("failed to run nasm");
+ if !status.success() {
+ panic!("nasm failed with exit status {}", status);
+ }
}
+ "riscv64" => {
+ println!("cargo:rustc-cfg=dtb");
+ }
+ _ => (),
}
- f.write_all(b"
- files
- }
-}
-").unwrap();
+ let _ = parse_kconfig(arch_str);
}
diff --git a/clippy.sh b/clippy.sh
index f128f482..655f1b89 100755
--- a/clippy.sh
+++ b/clippy.sh
@@ -3,15 +3,5 @@
set -e
export RUST_TARGET_PATH="${PWD}/targets"
-xargo rustc --lib --release \
- --target x86_64-unknown-none \
- --features clippy \
- -- \
- -C soft-float -C debuginfo=2 \
- -W anonymous-parameters \
- -W trivial-numeric-casts \
- -W unused-extern-crates \
- -W unused-import-braces \
- -W unused-qualifications \
- -W variant-size-differences \
- -Z no-trans -Z extra-plugins=clippy
+export RUSTFLAGS="-C soft-float -C debuginfo=2"
+cargo clippy --lib --release --target x86_64-unknown-none "$@"
diff --git a/config.toml.example b/config.toml.example
new file mode 100644
index 00000000..b3cdb9e7
--- /dev/null
+++ b/config.toml.example
@@ -0,0 +1,7 @@
+[arch.x86_64.features]
+smap = "auto"
+fsgsbase = "auto"
+xsave = "auto"
+xsaveopt = "auto"
+
+# vim: ft=toml
diff --git a/linkers/aarch64.ld b/linkers/aarch64.ld
new file mode 100644
index 00000000..f679c9af
--- /dev/null
+++ b/linkers/aarch64.ld
@@ -0,0 +1,62 @@
+ENTRY(kstart)
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+
+KERNEL_OFFSET = 0xFFFFFF0000000000;
+
+SECTIONS {
+ . = KERNEL_OFFSET;
+
+ . += SIZEOF_HEADERS;
+
+ /* Force the zero page to be part of a segment by creating a
+ * dummy section in the zero page.
+ * Limine will map the segment with the lowest vaddr value at
+ * 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
+ * As such without the zero page being part of a segment, the
+ * kernel would be loaded at an offset from the expected
+ * location. As the redox kernel is not currently relocatable,
+ * this would result in a crash. A similar issue likely exists
+ * with multiboot/multiboot2 and the paddr of the segment.
+ */
+ .dummy ALIGN(8) : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
+
+ . = ALIGN(4096);
+
+ .text : AT(ADDR(.text) - KERNEL_OFFSET) {
+ __text_start = .;
+ *(.text*)
+ __usercopy_start = .;
+ *(.usercopy-fns)
+ __usercopy_end = .;
+ . = ALIGN(4096);
+ __text_end = .;
+ }
+
+ .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
+ __rodata_start = .;
+ *(.rodata*)
+ . = ALIGN(4096);
+ __rodata_end = .;
+ }
+
+ .data : AT(ADDR(.data) - KERNEL_OFFSET) {
+ __data_start = .;
+ *(.data*)
+ . = ALIGN(4096);
+ __data_end = .;
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4096);
+ __bss_end = .;
+ }
+
+ __end = .;
+
+ /DISCARD/ : {
+ *(.comment*)
+ *(.eh_frame*)
+ *(.gcc_except_table*)
+ *(.note*)
+ *(.rel.eh_frame*)
+ }
+}
diff --git a/linkers/i686.ld b/linkers/i686.ld
new file mode 100644
index 00000000..f7eb9c42
--- /dev/null
+++ b/linkers/i686.ld
@@ -0,0 +1,57 @@
+ENTRY(kstart)
+OUTPUT_FORMAT(elf32-i386)
+
+KERNEL_OFFSET = 0xC0000000;
+
+SECTIONS {
+ . = KERNEL_OFFSET;
+
+ . += SIZEOF_HEADERS;
+
+ /* Force the zero page to be part of a segment by creating a
+ * dummy section in the zero page.
+ * Limine will map the segment with the lowest vaddr value at
+ * 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
+ * As such without the zero page being part of a segment, the
+ * kernel would be loaded at an offset from the expected
+ * location. As the redox kernel is not currently relocatable,
+ * this would result in a crash. A similar issue likely exists
+ * with multiboot/multiboot2 and the paddr of the segment.
+ */
+ .dummy : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
+
+ .text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET) {
+ __text_start = .;
+ *(.text*)
+ __usercopy_start = .;
+ *(.usercopy-fns)
+ __usercopy_end = .;
+ }
+
+ .rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET) {
+ __text_end = .;
+ __rodata_start = .;
+ *(.rodata*)
+ }
+
+ .data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET) {
+ __rodata_end = .;
+ __data_start = .;
+ *(.data*)
+ . = ALIGN(4K);
+ __data_end = .;
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4K);
+ }
+
+ __end = .;
+
+ /DISCARD/ : {
+ *(.comment*)
+ *(.eh_frame*)
+ *(.gcc_except_table*)
+ *(.note*)
+ *(.rel.eh_frame*)
+ }
+}
diff --git a/linkers/riscv64.ld b/linkers/riscv64.ld
new file mode 100644
index 00000000..634b5c2c
--- /dev/null
+++ b/linkers/riscv64.ld
@@ -0,0 +1,68 @@
+ENTRY(kstart)
+OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv" )
+
+KERNEL_OFFSET = 0xFFFFFF0000000000;
+
+SECTIONS {
+ . = KERNEL_OFFSET;
+
+ . += SIZEOF_HEADERS;
+
+ /* Force the zero page to be part of a segment by creating a
+ * dummy section in the zero page.
+ * Linker will map the segment with the lowest vaddr value at
+ * 0xFFFFFF0000000000 even if the segment has a higher vaddr.
+ * As such without the zero page being part of a segment, the
+ * kernel would be loaded at an offset from the expected
+ * location. As the redox kernel is not currently relocatable,
+ * this would result in a crash. A similar issue likely exists
+ * with multiboot/multiboot2 and the paddr of the segment.
+ */
+ .dummy ALIGN(8) : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
+
+ . = ALIGN(4096);
+
+ .text : AT(ADDR(.text) - KERNEL_OFFSET) {
+ __text_start = .;
+ *(.early_init.text*)
+ . = ALIGN(4096);
+ *(.text*)
+ __usercopy_start = .;
+ *(.usercopy-fns)
+ __usercopy_end = .;
+ . = ALIGN(4096);
+ __text_end = .;
+ }
+
+ .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
+ __rodata_start = .;
+ *(.rodata*)
+ . = ALIGN(4096);
+ __rodata_end = .;
+ }
+
+ .data : AT(ADDR(.data) - KERNEL_OFFSET) {
+ __data_start = .;
+ *(.data*)
+ *(.sdata*)
+ . = ALIGN(4096);
+ __data_end = .;
+ *(.got*)
+ . = ALIGN(4096);
+ __bss_start = .;
+ *(.bss*)
+ *(.sbss*)
+ . = ALIGN(4096);
+ __bss_end = .;
+ }
+
+ __end = .;
+
+ /DISCARD/ : {
+ *(.comment*)
+ *(.eh_frame*)
+ *(.gcc_except_table*)
+ *(.note*)
+ *(.rel.eh_frame*)
+ }
+}
diff --git a/linkers/x86_64.ld b/linkers/x86_64.ld
index e88c9d07..6610509a 100644
--- a/linkers/x86_64.ld
+++ b/linkers/x86_64.ld
@@ -1,49 +1,57 @@
ENTRY(kstart)
OUTPUT_FORMAT(elf64-x86-64)
-KERNEL_OFFSET = 0xffffff0000100000;
+KERNEL_OFFSET = 0xFFFFFFFF80000000;
SECTIONS {
. = KERNEL_OFFSET;
. += SIZEOF_HEADERS;
- . = ALIGN(4096);
- .text : AT(ADDR(.text) - KERNEL_OFFSET) {
+ /* Force the zero page to be part of a segment by creating a
+ * dummy section in the zero page.
+ * Limine will map the segment with the lowest vaddr value at
+ * 0xFFFFFFFF80000000 even if the segment has a higher vaddr.
+ * As such without the zero page being part of a segment, the
+ * kernel would be loaded at an offset from the expected
+ * location. As the redox kernel is not currently relocatable,
+ * this would result in a crash. A similar issue likely exists
+ * with multiboot/multiboot2 and the paddr of the segment.
+ */
+ .dummy : AT(ADDR(.dummy) - KERNEL_OFFSET) {}
+
+ .text ALIGN(4K) : AT(ADDR(.text) - KERNEL_OFFSET) {
__text_start = .;
*(.text*)
- . = ALIGN(4096);
- __text_end = .;
+ __usercopy_start = .;
+ *(.usercopy-fns)
+ __usercopy_end = .;
}
- .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) {
+ .rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET) {
+ __text_end = .;
__rodata_start = .;
*(.rodata*)
- . = ALIGN(4096);
- __rodata_end = .;
+ __altcode_start = .;
+ KEEP(*(.altcode*))
+ __altcode_end = .;
+ . = ALIGN(8);
+ __altrelocs_start = .;
+ KEEP(*(.altrelocs*))
+ __altrelocs_end = .;
+ __altfeatures_start = .;
+ KEEP(*(.altfeatures*))
+ __altfeatures_end = .;
}
- .data : AT(ADDR(.data) - KERNEL_OFFSET) {
+ .data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET) {
+ __rodata_end = .;
__data_start = .;
*(.data*)
- . = ALIGN(4096);
+ . = ALIGN(4K);
__data_end = .;
__bss_start = .;
*(.bss*)
- . = ALIGN(4096);
- __bss_end = .;
- }
-
- .tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
- __tdata_start = .;
- *(.tdata*)
- . = ALIGN(4096);
- __tdata_end = .;
- __tbss_start = .;
- *(.tbss*)
- . += 8;
- . = ALIGN(4096);
- __tbss_end = .;
}
__end = .;
diff --git a/rmm b/rmm
new file mode 160000
index 00000000..63669069
--- /dev/null
+++ b/rmm
@@ -0,0 +1 @@
+Subproject commit 63669069f4eb2e3bf04c0399d28fb2e3e3c58166
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 00000000..becbe9e6
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,21 @@
+blank_lines_lower_bound = 0 # default
+blank_lines_upper_bound = 1 # default
+brace_style = "SameLineWhere" # default
+disable_all_formatting = false # default
+edition = "2021"
+empty_item_single_line = true # default
+fn_single_line = false # default
+force_explicit_abi = true # default
+format_strings = false # default
+hard_tabs = false # default
+show_parse_errors = true # default
+imports_granularity = "Crate" # default = Preserve
+imports_indent = "Block" # default
+imports_layout = "Mixed" # default
+indent_style = "Block" # default
+max_width = 100 # default
+newline_style = "Unix" # default = Auto
+skip_children = false # default
+tab_spaces = 4 # default
+trailing_comma = "Vertical" # default
+where_single_line = false # default
diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs
deleted file mode 100644
index e0f26211..00000000
--- a/src/acpi/aml/dataobj.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-use alloc::vec::Vec;
-use alloc::string::String;
-
-use super::AmlError;
-use super::parser::{ AmlParseType, ParseResult, AmlExecutionContext, ExecutionState };
-use super::namespace::{ AmlValue, ObjectReference };
-
-use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package};
-use super::termlist::parse_term_arg;
-use super::namestring::parse_super_name;
-
-pub fn parse_data_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_computational_data,
- parse_def_package,
- parse_def_var_package
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_data_ref_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_data_obj,
- parse_term_arg
- };
-
- match parse_super_name(data, ctx) {
- Ok(res) => match res.val {
- AmlValue::String(s) => Ok(AmlParseType {
- val: AmlValue::ObjectReference(ObjectReference::Object(s)),
- len: res.len
- }),
- _ => Ok(res)
- },
- Err(e) => Err(e)
- }
-}
-
-pub fn parse_arg_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- match data[0] {
- 0x68 ... 0x6E => Ok(AmlParseType {
- val: AmlValue::ObjectReference(ObjectReference::ArgObj(data[0] - 0x68)),
- len: 1 as usize
- }),
- _ => Err(AmlError::AmlInvalidOpCode)
- }
-}
-
-pub fn parse_local_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- match data[0] {
- 0x68 ... 0x6E => Ok(AmlParseType {
- val: AmlValue::ObjectReference(ObjectReference::LocalObj(data[0] - 0x60)),
- len: 1 as usize
- }),
- _ => Err(AmlError::AmlInvalidOpCode)
- }
-}
-
-fn parse_computational_data(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- match data[0] {
- 0x0A => Ok(AmlParseType {
- val: AmlValue::Integer(data[1] as u64),
- len: 2 as usize
- }),
- 0x0B => {
- let res = (data[1] as u16) +
- ((data[2] as u16) << 8);
-
- Ok(AmlParseType {
- val: AmlValue::Integer(res as u64),
- len: 3 as usize
- })
- },
- 0x0C => {
- let res = (data[1] as u32) +
- ((data[2] as u32) << 8) +
- ((data[3] as u32) << 16) +
- ((data[4] as u32) << 24);
-
- Ok(AmlParseType {
- val: AmlValue::Integer(res as u64),
- len: 5 as usize
- })
- },
- 0x0D => {
- let mut cur_ptr: usize = 1;
- let mut cur_string: Vec = vec!();
-
- while data[cur_ptr] != 0x00 {
- cur_string.push(data[cur_ptr]);
- cur_ptr += 1;
- }
-
- match String::from_utf8(cur_string) {
- Ok(s) => Ok(AmlParseType {
- val: AmlValue::String(s.clone()),
- len: s.clone().len() + 2
- }),
- Err(_) => Err(AmlError::AmlParseError("String data - invalid string"))
- }
- },
- 0x0E => {
- let res = (data[1] as u64) +
- ((data[2] as u64) << 8) +
- ((data[3] as u64) << 16) +
- ((data[4] as u64) << 24) +
- ((data[5] as u64) << 32) +
- ((data[6] as u64) << 40) +
- ((data[7] as u64) << 48) +
- ((data[8] as u64) << 56);
-
- Ok(AmlParseType {
- val: AmlValue::Integer(res as u64),
- len: 9 as usize
- })
- },
- 0x00 => Ok(AmlParseType {
- val: AmlValue::IntegerConstant(0 as u64),
- len: 1 as usize
- }),
- 0x01 => Ok(AmlParseType {
- val: AmlValue::IntegerConstant(1 as u64),
- len: 1 as usize
- }),
- 0x5B => if data[1] == 0x30 {
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(2017_0630 as u64),
- len: 2 as usize
- })
- } else {
- Err(AmlError::AmlInvalidOpCode)
- },
- 0xFF => Ok(AmlParseType {
- val: AmlValue::IntegerConstant(0xFFFF_FFFF_FFFF_FFFF),
- len: 1 as usize
- }),
- _ => parse_def_buffer(data, ctx)
- }
-}
diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs
deleted file mode 100644
index 332e5fbb..00000000
--- a/src/acpi/aml/mod.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-//! # AML
-//! Code to parse and execute AML tables
-
-use alloc::string::String;
-use alloc::vec::Vec;
-use core::str::FromStr;
-
-use super::sdt::Sdt;
-
-#[macro_use]
-mod parsermacros;
-
-mod namespace;
-mod termlist;
-mod namespacemodifier;
-mod pkglength;
-mod namestring;
-mod namedobj;
-mod dataobj;
-mod type1opcode;
-mod type2opcode;
-mod parser;
-
-use self::parser::AmlExecutionContext;
-use self::termlist::parse_term_list;
-pub use self::namespace::AmlValue;
-
-#[derive(Debug)]
-pub enum AmlError {
- AmlParseError(&'static str),
- AmlInvalidOpCode,
- AmlValueError,
- AmlDeferredLoad,
- AmlFatalError(u8, u16, AmlValue),
- AmlHardFatal
-}
-
-pub fn parse_aml_table(sdt: &Sdt) -> Result, AmlError> {
- parse_aml_with_scope(sdt, String::from_str("\\").unwrap())
-}
-
-pub fn parse_aml_with_scope(sdt: &Sdt, scope: String) -> Result, AmlError> {
- let data = sdt.data();
- let mut ctx = AmlExecutionContext::new(scope);
-
- parse_term_list(data, &mut ctx)?;
-
- Ok(ctx.namespace_delta)
-}
-
-pub fn is_aml_table(sdt: &Sdt) -> bool {
- if &sdt.signature == b"DSDT" || &sdt.signature == b"SSDT" {
- true
- } else {
- false
- }
-}
diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs
deleted file mode 100644
index 8422b419..00000000
--- a/src/acpi/aml/namedobj.rs
+++ /dev/null
@@ -1,1045 +0,0 @@
-use alloc::boxed::Box;
-use alloc::string::String;
-use alloc::btree_map::BTreeMap;
-
-use super::AmlError;
-use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext, ExecutionState };
-use super::namespace::{AmlValue, FieldSelector, Method, get_namespace_string,
- Accessor, BufferField, FieldUnit, Processor, PowerResource, OperationRegion,
- Device, ThermalZone};
-use super::namestring::{parse_name_string, parse_name_seg};
-use super::termlist::{parse_term_arg, parse_object_list};
-use super::pkglength::parse_pkg_length;
-use super::type2opcode::parse_def_buffer;
-
-#[derive(Debug, Copy, Clone)]
-pub enum RegionSpace {
- SystemMemory,
- SystemIO,
- PCIConfig,
- EmbeddedControl,
- SMBus,
- SystemCMOS,
- PciBarTarget,
- IPMI,
- GeneralPurposeIO,
- GenericSerialBus,
- UserDefined(u8)
-}
-
-#[derive(Debug, Clone)]
-pub struct FieldFlags {
- access_type: AccessType,
- lock_rule: bool,
- update_rule: UpdateRule
-}
-
-#[derive(Debug, Clone)]
-pub enum AccessType {
- AnyAcc,
- ByteAcc,
- WordAcc,
- DWordAcc,
- QWordAcc,
- BufferAcc(AccessAttrib)
-}
-
-#[derive(Debug, Clone)]
-pub enum UpdateRule {
- Preserve,
- WriteAsOnes,
- WriteAsZeros
-}
-
-#[derive(Debug, Clone)]
-pub struct NamedField {
- name: String,
- length: usize
-}
-
-#[derive(Debug, Clone)]
-pub struct AccessField {
- access_type: AccessType,
- access_attrib: AccessAttrib
-}
-
-#[derive(Debug, Clone)]
-pub enum AccessAttrib {
- AttribBytes(u8),
- AttribRawBytes(u8),
- AttribRawProcessBytes(u8),
- AttribQuick,
- AttribSendReceive,
- AttribByte,
- AttribWord,
- AttribBlock,
- AttribProcessCall,
- AttribBlockProcessCall
-}
-
-pub fn parse_named_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_def_bank_field,
- parse_def_create_bit_field,
- parse_def_create_byte_field,
- parse_def_create_word_field,
- parse_def_create_dword_field,
- parse_def_create_qword_field,
- parse_def_create_field,
- parse_def_data_region,
- parse_def_event,
- parse_def_external,
- parse_def_device,
- parse_def_op_region,
- parse_def_field,
- parse_def_index_field,
- parse_def_method,
- parse_def_mutex,
- parse_def_power_res,
- parse_def_processor,
- parse_def_thermal_zone
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-fn parse_def_bank_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 3 {
- return Err(AmlError::AmlParseError("DefBankField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x87);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
- let data = &data[2 + pkg_length_len .. 2 + pkg_length];
-
- let region_name = parse_name_string(data, ctx)?;
- let bank_name = parse_name_string(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], ctx)?;
-
- let bank_value = parse_term_arg(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], ctx)?;
-
- let flags_raw = data[2 + pkg_length_len + region_name.len + bank_name.len + bank_value.len];
- let mut flags = FieldFlags {
- access_type: match flags_raw & 0x0F {
- 0 => AccessType::AnyAcc,
- 1 => AccessType::ByteAcc,
- 2 => AccessType::WordAcc,
- 3 => AccessType::DWordAcc,
- 4 => AccessType::QWordAcc,
- 5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
- _ => return Err(AmlError::AmlParseError("BankField - invalid access type"))
- },
- lock_rule: (flags_raw & 0x10) == 0x10,
- update_rule: match (flags_raw & 0x60) >> 5 {
- 0 => UpdateRule::Preserve,
- 1 => UpdateRule::WriteAsOnes,
- 2 => UpdateRule::WriteAsZeros,
- _ => return Err(AmlError::AmlParseError("BankField - invalid update rule"))
- }
- };
-
- let selector = FieldSelector::Bank {
- region: region_name.val.get_as_string()?,
- bank_register: bank_name.val.get_as_string()?,
- bank_selector: Box::new(bank_value.val)
- };
-
- parse_field_list(&data[3 + pkg_length_len + region_name.len + bank_name.len + bank_value.len ..
- 2 + pkg_length], ctx, selector, &mut flags)?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_length
- })
-}
-
-fn parse_def_create_bit_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefCreateBitField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x8D);
-
- let source_buf = parse_term_arg(&data[2..], ctx)?;
- let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
- let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
- source_buf: Box::new(source_buf.val),
- index: Box::new(bit_index.val),
- length: Box::new(AmlValue::IntegerConstant(1))
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + source_buf.len + bit_index.len
- })
-}
-
-fn parse_def_create_byte_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefCreateByteField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x8C);
-
- let source_buf = parse_term_arg(&data[2..], ctx)?;
- let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
- let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
- source_buf: Box::new(source_buf.val),
- index: Box::new(bit_index.val),
- length: Box::new(AmlValue::IntegerConstant(8))
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + source_buf.len + bit_index.len
- })
-}
-
-fn parse_def_create_word_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefCreateWordField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x8B);
-
- let source_buf = parse_term_arg(&data[2..], ctx)?;
- let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
- let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
- source_buf: Box::new(source_buf.val),
- index: Box::new(bit_index.val),
- length: Box::new(AmlValue::IntegerConstant(16))
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + source_buf.len + bit_index.len
- })
-}
-
-fn parse_def_create_dword_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefCreateDwordField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x8A);
-
- let source_buf = parse_term_arg(&data[2..], ctx)?;
- let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
- let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- let _ = ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
- source_buf: Box::new(source_buf.val),
- index: Box::new(bit_index.val),
- length: Box::new(AmlValue::IntegerConstant(32))
- }));
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + source_buf.len + bit_index.len
- })
-}
-
-fn parse_def_create_qword_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefCreateQwordField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x8F);
-
- let source_buf = parse_term_arg(&data[2..], ctx)?;
- let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
- let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
- source_buf: Box::new(source_buf.val),
- index: Box::new(bit_index.val),
- length: Box::new(AmlValue::IntegerConstant(64))
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + source_buf.len + bit_index.len
- })
-}
-
-fn parse_def_create_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefCreateField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x13);
-
- let source_buf = parse_term_arg(&data[2..], ctx)?;
- let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
- let num_bits = parse_term_arg(&data[2 + source_buf.len + bit_index.len..], ctx)?;
- let name = parse_name_string(&data[2 + source_buf.len + bit_index.len + num_bits.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
- source_buf: Box::new(source_buf.val),
- index: Box::new(bit_index.val),
- length: Box::new(num_bits.val)
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + source_buf.len + bit_index.len + num_bits.len
- })
-}
-
-fn parse_def_data_region(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefDataRegion - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: Find the actual offset and length, once table mapping is implemented
- parser_opcode_extended!(data, 0x88);
-
- let name = parse_name_string(&data[2..], ctx)?;
- let signature = parse_term_arg(&data[2 + name.len..], ctx)?;
- let oem_id = parse_term_arg(&data[2 + name.len + signature.len..], ctx)?;
- let oem_table_id = parse_term_arg(&data[2 + name.len + signature.len + oem_id.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::OperationRegion(OperationRegion {
- region: RegionSpace::SystemMemory,
- offset: Box::new(AmlValue::IntegerConstant(0)),
- len: Box::new(AmlValue::IntegerConstant(0)),
- accessor: Accessor {
- read: |_x| 0 as u64,
- write: |_x, _y| ()
- },
- accessed_by: None
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + signature.len + oem_id.len + oem_table_id.len
- })
-}
-
-fn parse_def_event(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefEvent - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x02);
-
- let name = parse_name_string(&data[2..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
- ctx.add_to_namespace(local_scope_string, AmlValue::Event(0))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len
- })
-}
-
-fn parse_def_device(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefDevice - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: How to handle local context deferreds
- parser_opcode_extended!(data, 0x82);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
- let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
- let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
-
- parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::Device(Device {
- obj_list: local_ctx.namespace_delta.clone(),
- notify_methods: BTreeMap::new()
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_length
- })
-}
-
-fn parse_def_op_region(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 3 {
- return Err(AmlError::AmlParseError("DefOpRegion - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x80);
-
- let name = parse_name_string(&data[2..], ctx)?;
- let region = match data[2 + name.len] {
- 0x00 => RegionSpace::SystemMemory,
- 0x01 => RegionSpace::SystemIO,
- 0x02 => RegionSpace::PCIConfig,
- 0x03 => RegionSpace::EmbeddedControl,
- 0x04 => RegionSpace::SMBus,
- 0x05 => RegionSpace::SystemCMOS,
- 0x06 => RegionSpace::PciBarTarget,
- 0x07 => RegionSpace::IPMI,
- 0x08 => RegionSpace::GeneralPurposeIO,
- 0x09 => RegionSpace::GenericSerialBus,
- 0x80 ... 0xFF => RegionSpace::UserDefined(data[2 + name.len]),
- _ => return Err(AmlError::AmlParseError("OpRegion - invalid region"))
- };
-
- let offset = parse_term_arg(&data[3 + name.len..], ctx)?;
- let len = parse_term_arg(&data[3 + name.len + offset.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
- ctx.add_to_namespace(local_scope_string, AmlValue::OperationRegion(OperationRegion {
- region: region,
- offset: Box::new(offset.val),
- len: Box::new(len.val),
- accessor: Accessor {
- read: |_x| 0 as u64,
- write: |_x, _y| ()
- },
- accessed_by: None
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 3 + name.len + offset.len + len.len
- })
-}
-
-fn parse_def_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 3 {
- return Err(AmlError::AmlParseError("DefField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x81);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
- let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
-
- let flags_raw = data[2 + pkg_length_len + name.len];
- let mut flags = FieldFlags {
- access_type: match flags_raw & 0x0F {
- 0 => AccessType::AnyAcc,
- 1 => AccessType::ByteAcc,
- 2 => AccessType::WordAcc,
- 3 => AccessType::DWordAcc,
- 4 => AccessType::QWordAcc,
- 5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
- _ => return Err(AmlError::AmlParseError("Field - Invalid access type"))
- },
- lock_rule: (flags_raw & 0x10) == 0x10,
- update_rule: match (flags_raw & 0x60) >> 5 {
- 0 => UpdateRule::Preserve,
- 1 => UpdateRule::WriteAsOnes,
- 2 => UpdateRule::WriteAsZeros,
- _ => return Err(AmlError::AmlParseError("Field - Invalid update rule"))
- }
- };
-
- let selector = FieldSelector::Region(name.val.get_as_string()?);
-
- parse_field_list(&data[3 + pkg_length_len + name.len .. 2 + pkg_length], ctx, selector, &mut flags)?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_length
- })
-}
-
-fn parse_def_index_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 3 {
- return Err(AmlError::AmlParseError("DefIndexField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x86);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
- let idx_name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
- let data_name = parse_name_string(&data[2 + pkg_length_len + idx_name.len .. 2 + pkg_length], ctx)?;
-
- let flags_raw = data[2 + pkg_length_len + idx_name.len + data_name.len];
- let mut flags = FieldFlags {
- access_type: match flags_raw & 0x0F {
- 0 => AccessType::AnyAcc,
- 1 => AccessType::ByteAcc,
- 2 => AccessType::WordAcc,
- 3 => AccessType::DWordAcc,
- 4 => AccessType::QWordAcc,
- 5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
- _ => return Err(AmlError::AmlParseError("IndexField - Invalid access type"))
- },
- lock_rule: (flags_raw & 0x10) == 0x10,
- update_rule: match (flags_raw & 0x60) >> 5 {
- 0 => UpdateRule::Preserve,
- 1 => UpdateRule::WriteAsOnes,
- 2 => UpdateRule::WriteAsZeros,
- _ => return Err(AmlError::AmlParseError("IndexField - Invalid update rule"))
- }
- };
-
- let selector = FieldSelector::Index {
- index_selector: idx_name.val.get_as_string()?,
- data_selector: data_name.val.get_as_string()?
- };
-
- parse_field_list(&data[3 + pkg_length_len + idx_name.len + data_name.len .. 2 + pkg_length],
- ctx, selector, &mut flags)?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_length
- })
-}
-
-fn parse_field_list(data: &[u8],
- ctx: &mut AmlExecutionContext,
- selector: FieldSelector,
- flags: &mut FieldFlags) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let mut current_offset: usize = 0;
- let mut field_offset: usize = 0;
- let mut connection = AmlValue::Uninitialized;
-
- while current_offset < data.len() {
- let res = parse_field_element(&data[current_offset..], ctx, selector.clone(), &mut connection, flags, &mut field_offset)?;
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- current_offset += res.len;
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: data.len()
- })
-}
-
-fn parse_field_element(data: &[u8],
- ctx: &mut AmlExecutionContext,
- selector: FieldSelector,
- connection: &mut AmlValue,
- flags: &mut FieldFlags,
- offset: &mut usize) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let length = if let Ok(field) = parse_named_field(data, ctx) {
- let local_scope_string = get_namespace_string(ctx.scope.clone(), AmlValue::String(field.val.name.clone()))?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::FieldUnit(FieldUnit {
- selector: selector.clone(),
- connection: Box::new(connection.clone()),
- flags: flags.clone(),
- offset: offset.clone(),
- length: field.val.length
- }))?;
-
- *offset += field.val.length;
- field.len
- } else if let Ok(field) = parse_reserved_field(data, ctx) {
- *offset += field.val;
- field.len
- } else if let Ok(field) = parse_access_field(data, ctx) {
- match field.val.access_type {
- AccessType::BufferAcc(_) =>
- flags.access_type = AccessType::BufferAcc(field.val.access_attrib.clone()),
- ref a => flags.access_type = a.clone()
- }
-
- field.len
- } else if let Ok(field) = parse_connect_field(data, ctx) {
- *connection = field.val.clone();
- field.len
- } else {
- return Err(AmlError::AmlInvalidOpCode);
- };
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: length
- })
-}
-
-fn parse_named_field(data: &[u8], _ctx: &mut AmlExecutionContext) -> Result, AmlError> {
- if data.len() < 4 {
- return Err(AmlError::AmlParseError("NamedField - data truncated"))
- }
-
- let (name_seg, name_seg_len) = parse_name_seg(&data[0..4])?;
- let name = match String::from_utf8(name_seg) {
- Ok(s) => s,
- Err(_) => return Err(AmlError::AmlParseError("NamedField - invalid name"))
- };
- let (length, length_len) = parse_pkg_length(&data[4..])?;
-
- Ok(AmlParseTypeGeneric {
- val: NamedField { name, length },
- len: name_seg_len + length_len
- })
-}
-
-fn parse_reserved_field(data: &[u8], _ctx: &mut AmlExecutionContext) -> Result, AmlError> {
- if data.len() < 1 {
- return Err(AmlError::AmlParseError("ReservedField - data truncated"))
- }
-
- parser_opcode!(data, 0x00);
-
- let (length, length_len) = parse_pkg_length(&data[1..])?;
- Ok(AmlParseTypeGeneric {
- val: length,
- len: 1 + length_len
- })
-}
-
-fn parse_access_field(data: &[u8], _ctx: &mut AmlExecutionContext) -> Result, AmlError> {
- if data.len() < 3 {
- return Err(AmlError::AmlParseError("AccessField - data truncated"))
- }
-
- parser_opcode!(data, 0x01, 0x03);
-
- let flags_raw = data[1];
- let access_type = match flags_raw & 0x0F {
- 0 => AccessType::AnyAcc,
- 1 => AccessType::ByteAcc,
- 2 => AccessType::WordAcc,
- 3 => AccessType::DWordAcc,
- 4 => AccessType::QWordAcc,
- 5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
- _ => return Err(AmlError::AmlParseError("AccessField - Invalid access type"))
- };
-
- let access_attrib = match (flags_raw & 0xC0) >> 6 {
- 0 => match data[2] {
- 0x02 => AccessAttrib::AttribQuick,
- 0x04 => AccessAttrib::AttribSendReceive,
- 0x06 => AccessAttrib::AttribByte,
- 0x08 => AccessAttrib::AttribWord,
- 0x0A => AccessAttrib::AttribBlock,
- 0x0B => AccessAttrib::AttribBytes(data[3]),
- 0x0C => AccessAttrib::AttribProcessCall,
- 0x0D => AccessAttrib::AttribBlockProcessCall,
- 0x0E => AccessAttrib::AttribRawBytes(data[3]),
- 0x0F => AccessAttrib::AttribRawProcessBytes(data[3]),
- _ => return Err(AmlError::AmlParseError("AccessField - Invalid access attrib"))
- },
- 1 => AccessAttrib::AttribBytes(data[2]),
- 2 => AccessAttrib::AttribRawBytes(data[2]),
- 3 => AccessAttrib::AttribRawProcessBytes(data[2]),
- _ => return Err(AmlError::AmlParseError("AccessField - Invalid access attrib"))
- // This should never happen but the compiler bitches if I don't cover this
- };
-
- Ok(AmlParseTypeGeneric {
- val: AccessField { access_type, access_attrib },
- len: if data[0] == 0x01 {
- 3 as usize
- } else {
- 4 as usize
- }
- })
-}
-
-fn parse_connect_field(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 1 {
- return Err(AmlError::AmlParseError("ConnectField - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x02);
-
- if let Ok(e) = parse_def_buffer(&data[1..], ctx) {
- Ok(AmlParseType {
- val: e.val,
- len: e.len + 1
- })
- } else {
- let name = parse_name_string(&data[1..], ctx)?;
- Ok(AmlParseType {
- val: AmlValue::Alias(name.val.get_as_string()?),
- len: name.len + 1
- })
- }
-}
-
-fn parse_def_method(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 1 {
- return Err(AmlError::AmlParseError("DefMethod - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x14);
-
- let (pkg_len, pkg_len_len) = parse_pkg_length(&data[1..])?;
- let name = parse_name_string(&data[1 + pkg_len_len..], ctx)?;
- let flags = data[1 + pkg_len_len + name.len];
-
- let arg_count = flags & 0x07;
- let serialized = (flags & 0x08) == 0x08;
- let sync_level = flags & 0xF0 >> 4;
-
- let term_list = &data[2 + pkg_len_len + name.len .. 1 + pkg_len];
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
- ctx.add_to_namespace(local_scope_string, AmlValue::Method(Method {
- arg_count,
- serialized,
- sync_level,
- term_list: term_list.to_vec()
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + pkg_len
- })
-}
-
-fn parse_def_mutex(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 1 {
- return Err(AmlError::AmlParseError("DefMutex - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x01);
-
- let name = parse_name_string(&data[2 ..], ctx)?;
- let flags = data[2 + name.len];
- let sync_level = flags & 0x0F;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
- ctx.add_to_namespace(local_scope_string, AmlValue::Mutex((sync_level, None)))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 3 + name.len
- })
-}
-
-fn parse_def_power_res(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 5 {
- return Err(AmlError::AmlParseError("DefPowerRes - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: How to handle local context deferreds
- parser_opcode_extended!(data, 0x84);
-
- let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
- let name = parse_name_string(&data[2 + pkg_len_len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- let system_level = data[2 + pkg_len_len + name.len];
- let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) +
- ((data[4 + pkg_len_len + name.len] as u16) << 8);
-
- let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
- parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::PowerResource(PowerResource {
- system_level,
- resource_order,
- obj_list: local_ctx.namespace_delta.clone()
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_len
- })
-}
-
-fn parse_def_processor(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 8 {
- return Err(AmlError::AmlParseError("DefProcessor - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x83);
-
- let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
- let name = parse_name_string(&data[2 + pkg_len_len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- let proc_id = data[2 + pkg_len_len + name.len];
- let p_blk_addr: u32 = (data[3 + pkg_len_len + name.len] as u32) +
- ((data[4 + pkg_len_len + name.len] as u32) << 8) +
- ((data[5 + pkg_len_len + name.len] as u32) << 16) +
- ((data[6 + pkg_len_len + name.len] as u32) << 24);
- let p_blk_len = data[7 + pkg_len_len + name.len];
-
- let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
- parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::Processor(Processor {
- proc_id: proc_id,
- p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None },
- obj_list: local_ctx.namespace_delta.clone(),
- notify_methods: BTreeMap::new()
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_len
- })
-}
-
-fn parse_def_thermal_zone(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefThermalZone - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x85);
-
- let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
- let name = parse_name_string(&data[2 + pkg_len_len .. 2 + pkg_len], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
- parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::ThermalZone(ThermalZone {
- obj_list: local_ctx.namespace_delta.clone(),
- notify_methods: BTreeMap::new()
- }))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + pkg_len
- })
-}
-
-fn parse_def_external(data: &[u8], ctx: &mut AmlExecutionContext) -> ParseResult {
- if data.len() < 2 {
- return Err(AmlError::AmlParseError("DefExternal - data truncated"))
- }
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x15);
-
- let object_name = parse_name_string(&data[1..], ctx)?;
- let object_type = data[1 + object_name.len];
- let argument_count = data[2 + object_name.len];
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), object_name.val)?;
-
- let obj = match object_type {
- 8 => AmlValue::Method(Method {
- arg_count: argument_count,
- serialized: false,
- sync_level: 0,
- term_list: vec!()
- }),
- _ => AmlValue::Uninitialized
- };
-
- ctx.add_to_namespace(local_scope_string, obj)?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 3 + object_name.len
- })
-}
diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs
deleted file mode 100644
index 906d3f63..00000000
--- a/src/acpi/aml/namespace.rs
+++ /dev/null
@@ -1,493 +0,0 @@
-use alloc::boxed::Box;
-use alloc::string::String;
-use alloc::string::ToString;
-use alloc::vec::Vec;
-use alloc::btree_map::BTreeMap;
-
-use core::fmt::{Debug, Formatter, Error};
-use core::str::FromStr;
-
-use super::termlist::parse_term_list;
-use super::namedobj::{ RegionSpace, FieldFlags };
-use super::parser::{AmlExecutionContext, ExecutionState};
-use super::AmlError;
-
-use acpi::{SdtSignature, get_signature_from_index, get_index_from_signature};
-
-#[derive(Clone)]
-pub enum FieldSelector {
- Region(String),
- Bank {
- region: String,
- bank_register: String,
- bank_selector: Box
- },
- Index {
- index_selector: String,
- data_selector: String
- }
-}
-
-#[derive(Clone)]
-pub enum ObjectReference {
- ArgObj(u8),
- LocalObj(u8),
- Object(String),
- Index(Box, Box)
-}
-
-#[derive(Clone)]
-pub struct Method {
- pub arg_count: u8,
- pub serialized: bool,
- pub sync_level: u8,
- pub term_list: Vec
-}
-
-#[derive(Clone)]
-pub struct BufferField {
- pub source_buf: Box,
- pub index: Box,
- pub length: Box
-}
-
-#[derive(Clone)]
-pub struct FieldUnit {
- pub selector: FieldSelector,
- pub connection: Box,
- pub flags: FieldFlags,
- pub offset: usize,
- pub length: usize
-}
-
-#[derive(Clone)]
-pub struct Device {
- pub obj_list: Vec,
- pub notify_methods: BTreeMap>
-}
-
-#[derive(Clone)]
-pub struct ThermalZone {
- pub obj_list: Vec,
- pub notify_methods: BTreeMap>
-}
-
-#[derive(Clone)]
-pub struct Processor {
- pub proc_id: u8,
- pub p_blk: Option,
- pub obj_list: Vec,
- pub notify_methods: BTreeMap>
-}
-
-#[derive(Clone)]
-pub struct OperationRegion {
- pub region: RegionSpace,
- pub offset: Box,
- pub len: Box,
- pub accessor: Accessor,
- pub accessed_by: Option
-}
-
-#[derive(Clone)]
-pub struct PowerResource {
- pub system_level: u8,
- pub resource_order: u16,
- pub obj_list: Vec
-}
-
-pub struct Accessor {
- pub read: fn(usize) -> u64,
- pub write: fn(usize, u64)
-}
-
-impl Clone for Accessor {
- fn clone(&self) -> Accessor {
- Accessor {
- read: (*self).read,
- write: (*self).write
- }
- }
-}
-
-#[derive(Clone)]
-pub enum AmlValue {
- None,
- Uninitialized,
- Alias(String),
- Buffer(Vec),
- BufferField(BufferField),
- DDBHandle((Vec, SdtSignature)),
- DebugObject,
- Device(Device),
- Event(u64),
- FieldUnit(FieldUnit),
- Integer(u64),
- IntegerConstant(u64),
- Method(Method),
- Mutex((u8, Option)),
- ObjectReference(ObjectReference),
- OperationRegion(OperationRegion),
- Package(Vec),
- String(String),
- PowerResource(PowerResource),
- Processor(Processor),
- RawDataBuffer(Vec),
- ThermalZone(ThermalZone)
-}
-
-impl Debug for AmlValue {
- fn fmt(&self, _f: &mut Formatter) -> Result<(), Error> { Ok(()) }
-}
-
-impl AmlValue {
- pub fn get_type_string(&self) -> String {
- match *self {
- AmlValue::Uninitialized => String::from_str("[Uninitialized Object]").unwrap(),
- AmlValue::Integer(_) => String::from_str("[Integer]").unwrap(),
- AmlValue::String(_) => String::from_str("[String]").unwrap(),
- AmlValue::Buffer(_) => String::from_str("[Buffer]").unwrap(),
- AmlValue::Package(_) => String::from_str("[Package]").unwrap(),
- AmlValue::FieldUnit(_) => String::from_str("[Field]").unwrap(),
- AmlValue::Device(_) => String::from_str("[Device]").unwrap(),
- AmlValue::Event(_) => String::from_str("[Event]").unwrap(),
- AmlValue::Method(_) => String::from_str("[Control Method]").unwrap(),
- AmlValue::Mutex(_) => String::from_str("[Mutex]").unwrap(),
- AmlValue::OperationRegion(_) => String::from_str("[Operation Region]").unwrap(),
- AmlValue::PowerResource(_) => String::from_str("[Power Resource]").unwrap(),
- AmlValue::Processor(_) => String::from_str("[Processor]").unwrap(),
- AmlValue::ThermalZone(_) => String::from_str("[Thermal Zone]").unwrap(),
- AmlValue::BufferField(_) => String::from_str("[Buffer Field]").unwrap(),
- AmlValue::DDBHandle(_) => String::from_str("[DDB Handle]").unwrap(),
- AmlValue::DebugObject => String::from_str("[Debug Object]").unwrap(),
- _ => String::new()
- }
- }
-
- pub fn get_as_type(&self, t: AmlValue) -> Result {
- match t {
- AmlValue::None => Ok(AmlValue::None),
- AmlValue::Uninitialized => Ok(self.clone()),
- AmlValue::Alias(_) => match *self {
- AmlValue::Alias(_) => Ok(self.clone()),
- _ => Err(AmlError::AmlValueError)
- },
- AmlValue::Buffer(_) => Ok(AmlValue::Buffer(self.get_as_buffer()?)),
- AmlValue::BufferField(_) => Ok(AmlValue::BufferField(self.get_as_buffer_field()?)),
- AmlValue::DDBHandle(_) => Ok(AmlValue::DDBHandle(self.get_as_ddb_handle()?)),
- AmlValue::DebugObject => match *self {
- AmlValue::DebugObject => Ok(self.clone()),
- _ => Err(AmlError::AmlValueError)
- },
- AmlValue::Device(_) => Ok(AmlValue::Device(self.get_as_device()?)),
- AmlValue::Event(_) => Ok(AmlValue::Event(self.get_as_event()?)),
- AmlValue::FieldUnit(_) => Ok(AmlValue::FieldUnit(self.get_as_field_unit()?)),
- AmlValue::Integer(_) => Ok(AmlValue::Integer(self.get_as_integer()?)),
- AmlValue::IntegerConstant(_) => Ok(AmlValue::IntegerConstant(self.get_as_integer_constant()?)),
- AmlValue::Method(_) => Ok(AmlValue::Method(self.get_as_method()?)),
- AmlValue::Mutex(_) => Ok(AmlValue::Mutex(self.get_as_mutex()?)),
- AmlValue::ObjectReference(_) => Ok(AmlValue::ObjectReference(self.get_as_object_reference()?)),
- AmlValue::OperationRegion(_) => match *self {
- AmlValue::OperationRegion(_) => Ok(self.clone()),
- _ => Err(AmlError::AmlValueError)
- },
- AmlValue::Package(_) => Ok(AmlValue::Package(self.get_as_package()?)),
- AmlValue::String(_) => Ok(AmlValue::String(self.get_as_string()?)),
- AmlValue::PowerResource(_) => Ok(AmlValue::PowerResource(self.get_as_power_resource()?)),
- AmlValue::Processor(_) => Ok(AmlValue::Processor(self.get_as_processor()?)),
- AmlValue::RawDataBuffer(_) => Ok(AmlValue::RawDataBuffer(self.get_as_raw_data_buffer()?)),
- AmlValue::ThermalZone(_) => Ok(AmlValue::ThermalZone(self.get_as_thermal_zone()?))
- }
- }
-
- pub fn get_as_buffer(&self) -> Result, AmlError> {
- match *self {
- AmlValue::Buffer(ref b) => Ok(b.clone()),
- AmlValue::Integer(ref i) => {
- let mut v: Vec = vec!();
- let mut i = i.clone();
-
- while i != 0 {
- v.push((i & 0xFF) as u8);
- i >>= 8;
- }
-
- while v.len() < 8 {
- v.push(0);
- }
-
- Ok(v)
- },
- AmlValue::String(ref s) => {
- Ok(s.clone().into_bytes())
- },
- AmlValue::BufferField(ref b) => {
- let buf = b.source_buf.get_as_buffer()?;
- let idx = b.index.get_as_integer()? as usize;
- let len = b.length.get_as_integer()? as usize;
-
- if idx + len > buf.len() {
- return Err(AmlError::AmlValueError);
- }
-
- Ok(buf[idx .. idx + len].to_vec())
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_buffer_field(&self) -> Result {
- match *self {
- AmlValue::BufferField(ref b) => Ok(b.clone()),
- _ => {
- let raw_buf = self.get_as_buffer()?;
- let buf = Box::new(AmlValue::Buffer(raw_buf.clone()));
- let idx = Box::new(AmlValue::IntegerConstant(0));
- let len = Box::new(AmlValue::Integer(raw_buf.len() as u64));
-
- Ok(BufferField {
- source_buf: buf,
- index: idx,
- length: len
- })
- }
- }
- }
-
- pub fn get_as_ddb_handle(&self) -> Result<(Vec, SdtSignature), AmlError> {
- match *self {
- AmlValue::DDBHandle(ref v) => Ok(v.clone()),
- AmlValue::Integer(i) => if let Some(sig) = get_signature_from_index(i as usize) {
- Ok((vec!(), sig))
- } else {
- Err(AmlError::AmlValueError)
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_device(&self) -> Result {
- match *self {
- AmlValue::Device(ref s) => Ok(s.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_event(&self) -> Result {
- match *self {
- AmlValue::Event(ref e) => Ok(e.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_field_unit(&self) -> Result {
- match *self {
- AmlValue::FieldUnit(ref e) => Ok(e.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_integer(&self) -> Result {
- match *self {
- AmlValue::IntegerConstant(ref i) => Ok(i.clone()),
- AmlValue::Integer(ref i) => Ok(i.clone()),
- AmlValue::Buffer(ref b) => {
- let mut b = b.clone();
- if b.len() > 8 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut i: u64 = 0;
-
- while b.len() > 0 {
- i <<= 8;
- i += b.pop().expect("Won't happen") as u64;
- }
-
- Ok(i)
- },
- AmlValue::BufferField(_) => {
- let mut b = self.get_as_buffer()?;
- if b.len() > 8 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut i: u64 = 0;
-
- while b.len() > 0 {
- i <<= 8;
- i += b.pop().expect("Won't happen") as u64;
- }
-
- Ok(i)
- },
- AmlValue::DDBHandle(ref v) => if let Some(idx) = get_index_from_signature(v.1.clone()) {
- Ok(idx as u64)
- } else {
- Err(AmlError::AmlValueError)
- },
- AmlValue::String(ref s) => {
- let s = s.clone()[0..8].to_string().to_uppercase();
- let mut i: u64 = 0;
-
- for c in s.chars() {
- if !c.is_digit(16) {
- break;
- }
-
- i <<= 8;
- i += c.to_digit(16).unwrap() as u64;
- }
-
- Ok(i)
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_integer_constant(&self) -> Result {
- match *self {
- AmlValue::IntegerConstant(ref i) => Ok(i.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_method(&self) -> Result {
- match *self {
- AmlValue::Method(ref m) => Ok(m.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_mutex(&self) -> Result<(u8, Option), AmlError> {
- match *self {
- AmlValue::Mutex(ref m) => Ok(m.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_object_reference(&self) -> Result {
- match *self {
- AmlValue::ObjectReference(ref m) => Ok(m.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- /*
- pub fn get_as_operation_region(&self) -> Result {
- match *self {
- AmlValue::OperationRegion(ref p) => Ok(p.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
- */
-
- pub fn get_as_package(&self) -> Result, AmlError> {
- match *self {
- AmlValue::Package(ref p) => Ok(p.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_string(&self) -> Result {
- match *self {
- AmlValue::String(ref s) => Ok(s.clone()),
- AmlValue::Integer(ref i) => Ok(format!("{:X}", i)),
- AmlValue::IntegerConstant(ref i) => Ok(format!("{:X}", i)),
- AmlValue::Buffer(ref b) => Ok(String::from_utf8(b.clone()).expect("Invalid UTF-8")),
- AmlValue::BufferField(_) => {
- let b = self.get_as_buffer()?;
- Ok(String::from_utf8(b).expect("Invalid UTF-8"))
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_power_resource(&self) -> Result {
- match *self {
- AmlValue::PowerResource(ref p) => Ok(p.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_processor(&self) -> Result {
- match *self {
- AmlValue::Processor(ref p) => Ok(p.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_raw_data_buffer(&self) -> Result, AmlError> {
- match *self {
- AmlValue::RawDataBuffer(ref p) => Ok(p.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_as_thermal_zone(&self) -> Result {
- match *self {
- AmlValue::ThermalZone(ref p) => Ok(p.clone()),
- _ => Err(AmlError::AmlValueError)
- }
- }
-}
-
-impl Method {
- pub fn execute(&self, scope: String, parameters: Vec) -> AmlValue {
- let mut ctx = AmlExecutionContext::new(scope);
- ctx.init_arg_vars(parameters);
-
- let _ = parse_term_list(&self.term_list[..], &mut ctx);
- ctx.clean_namespace();
-
- match ctx.state {
- ExecutionState::RETURN(v) => v,
- _ => AmlValue::IntegerConstant(0)
- }
- }
-}
-
-pub fn get_namespace_string(current: String, modifier_v: AmlValue) -> Result {
- let mut modifier = modifier_v.get_as_string()?;
-
- if current.len() == 0 {
- return Ok(modifier);
- }
-
- if modifier.len() == 0 {
- return Ok(current);
- }
-
- if modifier.starts_with("\\") {
- return Ok(modifier);
- }
-
- let mut namespace = current.clone();
-
- if modifier.starts_with("^") {
- while modifier.starts_with("^") {
- modifier = modifier[1..].to_string();
-
- if namespace.ends_with("\\") {
- return Err(AmlError::AmlValueError);
- }
-
- loop {
- if namespace.ends_with(".") {
- namespace.pop();
- break;
- }
-
- if namespace.pop() == None {
- return Err(AmlError::AmlValueError);
- }
- }
- }
- }
-
- if !namespace.ends_with("\\") {
- namespace.push('.');
- }
-
- Ok(namespace + &modifier)
-}
diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs
deleted file mode 100644
index 77fa1406..00000000
--- a/src/acpi/aml/namespacemodifier.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-use super::AmlError;
-use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
-use super::namespace::{AmlValue, get_namespace_string};
-use super::pkglength::parse_pkg_length;
-use super::namestring::parse_name_string;
-use super::termlist::parse_term_list;
-use super::dataobj::parse_data_ref_obj;
-
-pub fn parse_namespace_modifier(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_alias_op,
- parse_scope_op,
- parse_name_op
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-fn parse_alias_op(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x06);
-
- let source_name = parse_name_string(&data[1..], ctx)?;
- let alias_name = parse_name_string(&data[1 + source_name.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), source_name.val)?;
- let local_alias_string = get_namespace_string(ctx.scope.clone(), alias_name.val)?;
-
- ctx.add_to_namespace(local_scope_string, AmlValue::Alias(local_alias_string))?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + source_name.len + alias_name.len
- })
-}
-
-fn parse_name_op(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x08);
-
- let name = parse_name_string(&data[1..], ctx)?;
- let data_ref_obj = parse_data_ref_obj(&data[1 + name.len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
-
- ctx.add_to_namespace(local_scope_string, data_ref_obj.val)?;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + name.len + data_ref_obj.len
- })
-}
-
-fn parse_scope_op(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x10);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
- let name = parse_name_string(&data[1 + pkg_length_len..], ctx)?;
-
- let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val.clone())?;
- let containing_scope_string = ctx.scope.clone();
-
- ctx.scope = local_scope_string;
- parse_term_list(&data[1 + pkg_length_len + name.len .. 1 + pkg_length], ctx)?;
- ctx.scope = containing_scope_string;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + pkg_length
- })
-}
diff --git a/src/acpi/aml/namestring.rs b/src/acpi/aml/namestring.rs
deleted file mode 100644
index ecc52daa..00000000
--- a/src/acpi/aml/namestring.rs
+++ /dev/null
@@ -1,226 +0,0 @@
-use alloc::vec::Vec;
-use alloc::string::String;
-
-use super::AmlError;
-use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
-use super::namespace::AmlValue;
-use super::dataobj::{parse_arg_obj, parse_local_obj};
-use super::type2opcode::parse_type6_opcode;
-
-pub fn parse_name_string(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let mut characters: Vec = vec!();
- let mut starting_index: usize = 0;
-
- if data[0] == 0x5C {
- characters.push(data[0]);
- starting_index = 1;
- } else if data[0] == 0x5E {
- while data[starting_index] == 0x5E {
- characters.push(data[starting_index]);
- starting_index += 1;
- }
- }
-
- let sel = |data| {
- parser_selector_simple! {
- data,
- parse_dual_name_path,
- parse_multi_name_path,
- parse_null_name,
- parse_name_seg
- };
-
- Err(AmlError::AmlInvalidOpCode)
- };
- let (mut chr, len) = sel(&data[starting_index..])?;
- characters.append(&mut chr);
-
- let name_string = String::from_utf8(characters);
-
- match name_string {
- Ok(s) => Ok(AmlParseType {
- val: AmlValue::String(s.clone()),
- len: len + starting_index
- }),
- Err(_) => Err(AmlError::AmlParseError("Namestring - Name is invalid"))
- }
-}
-
-fn parse_null_name(data: &[u8]) -> Result<(Vec, usize), AmlError> {
- parser_opcode!(data, 0x00);
- Ok((vec!(), 1 ))
-}
-
-pub fn parse_name_seg(data: &[u8]) -> Result<(Vec, usize), AmlError> {
- match data[0] {
- 0x41 ... 0x5A | 0x5F => (),
- _ => return Err(AmlError::AmlInvalidOpCode)
- }
-
- match data[1] {
- 0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
- _ => return Err(AmlError::AmlInvalidOpCode)
- }
-
- match data[2] {
- 0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
- _ => return Err(AmlError::AmlInvalidOpCode)
- }
-
- match data[3] {
- 0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
- _ => return Err(AmlError::AmlInvalidOpCode)
- }
-
- let mut name_seg = vec!(data[0], data[1], data[2], data[3]);
- while *(name_seg.last().unwrap()) == 0x5F {
- name_seg.pop();
- }
-
- Ok((name_seg, 4))
-}
-
-fn parse_dual_name_path(data: &[u8]) -> Result<(Vec, usize), AmlError> {
- parser_opcode!(data, 0x2E);
-
- let mut characters: Vec = vec!();
- let mut dual_len: usize = 1;
-
- match parse_name_seg(&data[1..5]) {
- Ok((mut v, len)) => {
- characters.append(&mut v);
- dual_len += len;
- },
- Err(e) => return Err(e)
- }
-
- characters.push(0x2E);
-
- match parse_name_seg(&data[5..9]) {
- Ok((mut v, len)) => {
- characters.append(&mut v);
- dual_len += len;
- },
- Err(e) => return Err(e)
- }
-
- Ok((characters, dual_len))
-}
-
-fn parse_multi_name_path(data: &[u8]) -> Result<(Vec, usize), AmlError> {
- parser_opcode!(data, 0x2F);
-
- let seg_count = data[1];
- if seg_count == 0x00 {
- return Err(AmlError::AmlParseError("MultiName Path - can't have zero name segments"));
- }
-
- let mut current_seg = 0;
- let mut characters: Vec = vec!();
- let mut multi_len: usize = 2;
-
- while current_seg < seg_count {
- match parse_name_seg(&data[(current_seg as usize * 4) + 2 ..]) {
- Ok((mut v, len)) => {
- characters.append(&mut v);
- multi_len += len;
- },
- Err(e) => return Err(e)
- }
-
- characters.push(0x2E);
-
- current_seg += 1;
- }
-
- characters.pop();
-
- Ok((characters, multi_len))
-}
-
-pub fn parse_super_name(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_simple_name,
- parse_type6_opcode,
- parse_debug_obj
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-fn parse_debug_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x31);
-
- Ok(AmlParseType {
- val: AmlValue::DebugObject,
- len: 2
- })
-}
-
-pub fn parse_simple_name(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_name_string,
- parse_arg_obj,
- parse_local_obj
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_target(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- if data[0] == 0x00 {
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1
- })
- } else {
- parse_super_name(data, ctx)
- }
-}
diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs
deleted file mode 100644
index c4a8f922..00000000
--- a/src/acpi/aml/parser.rs
+++ /dev/null
@@ -1,552 +0,0 @@
-use alloc::string::String;
-use alloc::btree_map::BTreeMap;
-use alloc::vec::Vec;
-use alloc::boxed::Box;
-
-use spin::RwLockWriteGuard;
-
-use super::namespace::{ AmlValue, ObjectReference };
-use super::AmlError;
-
-use acpi::ACPI_TABLE;
-
-pub type ParseResult = Result;
-pub type AmlParseType = AmlParseTypeGeneric;
-
-pub struct AmlParseTypeGeneric {
- pub val: T,
- pub len: usize
-}
-
-pub enum ExecutionState {
- EXECUTING,
- CONTINUE,
- BREAK,
- RETURN(AmlValue)
-}
-
-pub struct AmlExecutionContext {
- pub scope: String,
- pub local_vars: [AmlValue; 8],
- pub arg_vars: [AmlValue; 8],
- pub state: ExecutionState,
- pub namespace_delta: Vec,
- pub ctx_id: u64,
- pub sync_level: u8
-}
-
-impl AmlExecutionContext {
- pub fn new(scope: String) -> AmlExecutionContext {
- let mut idptr = ACPI_TABLE.next_ctx.write();
- let id: u64 = *idptr;
-
- *idptr += 1;
-
- AmlExecutionContext {
- scope: scope,
- local_vars: [AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized],
- arg_vars: [AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized,
- AmlValue::Uninitialized],
- state: ExecutionState::EXECUTING,
- namespace_delta: vec!(),
- ctx_id: id,
- sync_level: 0
- }
- }
-
- pub fn wait_for_event(&mut self, event_ptr: AmlValue) -> Result {
- let mut namespace_ptr = self.prelock();
- let namespace = match *namespace_ptr {
- Some(ref mut n) => n,
- None => return Err(AmlError::AmlHardFatal)
- };
-
- let mutex_idx = match event_ptr {
- AmlValue::String(ref s) => s.clone(),
- AmlValue::ObjectReference(ref o) => match *o {
- ObjectReference::Object(ref s) => s.clone(),
- _ => return Err(AmlError::AmlValueError)
- },
- _ => return Err(AmlError::AmlValueError)
- };
-
- let mutex = match namespace.get(&mutex_idx) {
- Some(s) => s.clone(),
- None => return Err(AmlError::AmlValueError)
- };
-
- match mutex {
- AmlValue::Event(count) => {
- if count > 0 {
- namespace.insert(mutex_idx, AmlValue::Event(count - 1));
- return Ok(true);
- }
- },
- _ => return Err(AmlError::AmlValueError)
- }
-
- Ok(false)
- }
-
- pub fn signal_event(&mut self, event_ptr: AmlValue) -> Result<(), AmlError> {
- let mut namespace_ptr = self.prelock();
- let namespace = match *namespace_ptr {
- Some(ref mut n) => n,
- None => return Err(AmlError::AmlHardFatal)
- };
-
-
- let mutex_idx = match event_ptr {
- AmlValue::String(ref s) => s.clone(),
- AmlValue::ObjectReference(ref o) => match *o {
- ObjectReference::Object(ref s) => s.clone(),
- _ => return Err(AmlError::AmlValueError)
- },
- _ => return Err(AmlError::AmlValueError)
- };
-
- let mutex = match namespace.get(&mutex_idx) {
- Some(s) => s.clone(),
- None => return Err(AmlError::AmlValueError)
- };
-
- match mutex {
- AmlValue::Event(count) => {
- namespace.insert(mutex_idx, AmlValue::Event(count + 1));
- },
- _ => return Err(AmlError::AmlValueError)
- }
-
- Ok(())
- }
-
- pub fn release_mutex(&mut self, mutex_ptr: AmlValue) -> Result<(), AmlError> {
- let id = self.ctx_id;
-
- let mut namespace_ptr = self.prelock();
- let namespace = match *namespace_ptr {
- Some(ref mut n) => n,
- None => return Err(AmlError::AmlHardFatal)
- };
-
- let mutex_idx = match mutex_ptr {
- AmlValue::String(ref s) => s.clone(),
- AmlValue::ObjectReference(ref o) => match *o {
- ObjectReference::Object(ref s) => s.clone(),
- _ => return Err(AmlError::AmlValueError)
- },
- _ => return Err(AmlError::AmlValueError)
- };
-
- let mutex = match namespace.get(&mutex_idx) {
- Some(s) => s.clone(),
- None => return Err(AmlError::AmlValueError)
- };
-
- match mutex {
- AmlValue::Mutex((sync_level, owner)) => {
- if let Some(o) = owner {
- if o == id {
- if sync_level == self.sync_level {
- namespace.insert(mutex_idx, AmlValue::Mutex((sync_level, None)));
- return Ok(());
- } else {
- return Err(AmlError::AmlValueError);
- }
- } else {
- return Err(AmlError::AmlHardFatal);
- }
- }
- },
- AmlValue::OperationRegion(ref region) => {
- if let Some(o) = region.accessed_by {
- if o == id {
- let mut new_region = region.clone();
- new_region.accessed_by = None;
-
- namespace.insert(mutex_idx, AmlValue::OperationRegion(new_region));
- return Ok(());
- } else {
- return Err(AmlError::AmlHardFatal);
- }
- }
- },
- _ => return Err(AmlError::AmlValueError)
- }
-
- Ok(())
- }
-
- pub fn acquire_mutex(&mut self, mutex_ptr: AmlValue) -> Result {
- let id = self.ctx_id;
-
- let mut namespace_ptr = self.prelock();
- let namespace = match *namespace_ptr {
- Some(ref mut n) => n,
- None => return Err(AmlError::AmlHardFatal)
- };
- let mutex_idx = match mutex_ptr {
- AmlValue::String(ref s) => s.clone(),
- AmlValue::ObjectReference(ref o) => match *o {
- ObjectReference::Object(ref s) => s.clone(),
- _ => return Err(AmlError::AmlValueError)
- },
- _ => return Err(AmlError::AmlValueError)
- };
-
- let mutex = match namespace.get(&mutex_idx) {
- Some(s) => s.clone(),
- None => return Err(AmlError::AmlValueError)
- };
-
- match mutex {
- AmlValue::Mutex((sync_level, owner)) => {
- if owner == None {
- if sync_level < self.sync_level {
- return Err(AmlError::AmlValueError);
- }
-
- namespace.insert(mutex_idx, AmlValue::Mutex((sync_level, Some(id))));
- self.sync_level = sync_level;
-
- return Ok(true);
- }
- },
- AmlValue::OperationRegion(ref o) => {
- if o.accessed_by == None {
- let mut new_region = o.clone();
- new_region.accessed_by = Some(id);
-
- namespace.insert(mutex_idx, AmlValue::OperationRegion(new_region));
- return Ok(true);
- }
- },
- _ => return Err(AmlError::AmlValueError)
- }
-
- Ok(false)
- }
-
- pub fn add_to_namespace(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> {
- let mut namespace = ACPI_TABLE.namespace.write();
-
- if let Some(ref mut namespace) = *namespace {
- if let Some(obj) = namespace.get(&name) {
- match *obj {
- AmlValue::Uninitialized => (),
- AmlValue::Method(ref m) => {
- if m.term_list.len() != 0 {
- return Err(AmlError::AmlValueError);
- }
- },
- _ => return Err(AmlError::AmlValueError)
- }
- }
-
- self.namespace_delta.push(name.clone());
- namespace.insert(name, value);
-
- Ok(())
- } else {
- Err(AmlError::AmlValueError)
- }
- }
-
- pub fn clean_namespace(&mut self) {
- let mut namespace = ACPI_TABLE.namespace.write();
-
- if let Some(ref mut namespace) = *namespace {
- for k in &self.namespace_delta {
- namespace.remove(k);
- }
- }
- }
-
- pub fn init_arg_vars(&mut self, parameters: Vec) {
- if parameters.len() > 8 {
- return;
- }
-
- let mut cur = 0;
- while cur < parameters.len() {
- self.arg_vars[cur] = parameters[cur].clone();
- cur += 1;
- }
- }
-
- pub fn prelock(&mut self) -> RwLockWriteGuard<'static, Option>> {
- ACPI_TABLE.namespace.write()
- }
-
- fn modify_local_obj(&mut self, local: usize, value: AmlValue) -> Result<(), AmlError> {
- self.local_vars[local] = value.get_as_type(self.local_vars[local].clone())?;
- Ok(())
- }
-
- fn modify_object(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> {
- if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() {
- let coercion_obj = {
- let obj = namespace.get(&name);
-
- if let Some(o) = obj {
- o.clone()
- } else {
- AmlValue::Uninitialized
- }
- };
-
- namespace.insert(name, value.get_as_type(coercion_obj)?);
- Ok(())
- } else {
- Err(AmlError::AmlHardFatal)
- }
- }
-
- fn modify_index_final(&mut self, name: String, value: AmlValue, indices: Vec) -> Result<(), AmlError> {
- if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() {
- let mut obj = if let Some(s) = namespace.get(&name) {
- s.clone()
- } else {
- return Err(AmlError::AmlValueError);
- };
-
- obj = self.modify_index_core(obj, value, indices)?;
-
- namespace.insert(name, obj);
- Ok(())
- } else {
- Err(AmlError::AmlValueError)
- }
- }
-
- fn modify_index_core(&mut self, obj: AmlValue, value: AmlValue, indices: Vec) -> Result {
- match obj {
- AmlValue::String(ref string) => {
- if indices.len() != 1 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut bytes = string.clone().into_bytes();
- bytes[indices[0] as usize] = value.get_as_integer()? as u8;
-
- let string = String::from_utf8(bytes).unwrap();
-
- Ok(AmlValue::String(string))
- },
- AmlValue::Buffer(ref b) => {
- if indices.len() != 1 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut b = b.clone();
- b[indices[0] as usize] = value.get_as_integer()? as u8;
-
- Ok(AmlValue::Buffer(b))
- },
- AmlValue::BufferField(ref b) => {
- if indices.len() != 1 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut idx = indices[0];
- idx += b.index.get_as_integer()?;
-
- let _ = self.modify(AmlValue::ObjectReference(ObjectReference::Index(b.source_buf.clone(), Box::new(AmlValue::Integer(idx.clone())))), value);
-
- Ok(AmlValue::BufferField(b.clone()))
- },
- AmlValue::Package(ref p) => {
- if indices.len() == 0 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut p = p.clone();
-
- if indices.len() == 1 {
- p[indices[0] as usize] = value;
- } else {
- p[indices[0] as usize] = self.modify_index_core(p[indices[0] as usize].clone(), value, indices[1..].to_vec())?;
- }
-
- Ok(AmlValue::Package(p))
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn modify_index(&mut self, name: AmlValue, value: AmlValue, indices: Vec) -> Result<(), AmlError>{
- match name {
- AmlValue::ObjectReference(r) => match r {
- ObjectReference::Object(s) => self.modify_index_final(s, value, indices),
- ObjectReference::Index(c, v) => {
- let mut indices = indices.clone();
- indices.push(v.get_as_integer()?);
-
- self.modify_index(*c, value, indices)
- },
- ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
- ObjectReference::LocalObj(i) => {
- let v = self.local_vars[i as usize].clone();
- self.local_vars[i as usize] = self.modify_index_core(v, value, indices)?;
-
- Ok(())
- }
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn modify(&mut self, name: AmlValue, value: AmlValue) -> Result<(), AmlError> {
- match name {
- AmlValue::ObjectReference(r) => match r {
- ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
- ObjectReference::LocalObj(i) => self.modify_local_obj(i as usize, value),
- ObjectReference::Object(s) => self.modify_object(s, value),
- ObjectReference::Index(c, v) => self.modify_index(*c, value, vec!(v.get_as_integer()?))
- },
- AmlValue::String(s) => self.modify_object(s, value),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- fn copy_local_obj(&mut self, local: usize, value: AmlValue) -> Result<(), AmlError> {
- self.local_vars[local] = value;
- Ok(())
- }
-
- fn copy_object(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> {
- if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() {
- namespace.insert(name, value);
- Ok(())
- } else {
- Err(AmlError::AmlHardFatal)
- }
- }
-
- pub fn copy(&mut self, name: AmlValue, value: AmlValue) -> Result<(), AmlError> {
- match name {
- AmlValue::ObjectReference(r) => match r {
- ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
- ObjectReference::LocalObj(i) => self.copy_local_obj(i as usize, value),
- ObjectReference::Object(s) => self.copy_object(s, value),
- ObjectReference::Index(c, v) => self.modify_index(*c, value, vec!(v.get_as_integer()?))
- },
- AmlValue::String(s) => self.copy_object(s, value),
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- fn get_index_final(&self, name: String, indices: Vec) -> Result {
- if let Some(ref namespace) = *ACPI_TABLE.namespace.read() {
- let obj = if let Some(s) = namespace.get(&name) {
- s.clone()
- } else {
- return Err(AmlError::AmlValueError);
- };
-
- self.get_index_core(obj, indices)
- } else {
- Err(AmlError::AmlValueError)
- }
- }
-
- fn get_index_core(&self, obj: AmlValue, indices: Vec) -> Result {
- match obj {
- AmlValue::String(ref string) => {
- if indices.len() != 1 {
- return Err(AmlError::AmlValueError);
- }
-
- let bytes = string.clone().into_bytes();
- Ok(AmlValue::Integer(bytes[indices[0] as usize] as u64))
- },
- AmlValue::Buffer(ref b) => {
- if indices.len() != 1 {
- return Err(AmlError::AmlValueError);
- }
-
- Ok(AmlValue::Integer(b[indices[0] as usize] as u64))
- },
- AmlValue::BufferField(ref b) => {
- if indices.len() != 1 {
- return Err(AmlError::AmlValueError);
- }
-
- let mut idx = indices[0];
- idx += b.index.get_as_integer()?;
-
- Ok(AmlValue::Integer(b.source_buf.get_as_buffer()?[idx as usize] as u64))
- },
- AmlValue::Package(ref p) => {
- if indices.len() == 0 {
- return Err(AmlError::AmlValueError);
- }
-
- if indices.len() == 1 {
- Ok(p[indices[0] as usize].clone())
- } else {
- self.get_index_core(p[indices[0] as usize].clone(), indices[1..].to_vec())
- }
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get_index(&self, name: AmlValue, indices: Vec) -> Result{
- match name {
- AmlValue::ObjectReference(r) => match r {
- ObjectReference::Object(s) => self.get_index_final(s, indices),
- ObjectReference::Index(c, v) => {
- let mut indices = indices.clone();
- indices.push(v.get_as_integer()?);
-
- self.get_index(*c, indices)
- },
- ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
- ObjectReference::LocalObj(i) => {
- let v = self.local_vars[i as usize].clone();
- self.get_index_core(v, indices)
- }
- },
- _ => Err(AmlError::AmlValueError)
- }
- }
-
- pub fn get(&self, name: AmlValue) -> Result {
- Ok(match name {
- AmlValue::ObjectReference(r) => match r {
- ObjectReference::ArgObj(i) => self.arg_vars[i as usize].clone(),
- ObjectReference::LocalObj(i) => self.local_vars[i as usize].clone(),
- ObjectReference::Object(ref s) => if let Some(ref namespace) = *ACPI_TABLE.namespace.read() {
- if let Some(o) = namespace.get(s) {
- o.clone()
- } else {
- AmlValue::None
- }
- } else { AmlValue::None },
- ObjectReference::Index(c, v) => self.get_index(*c, vec!(v.get_as_integer()?))?,
- },
- AmlValue::String(ref s) => if let Some(ref namespace) = *ACPI_TABLE.namespace.read() {
- if let Some(o) = namespace.get(s) {
- o.clone()
- } else {
- AmlValue::None
- }
- } else { AmlValue::None },
- _ => AmlValue::None
- })
- }
-}
diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs
deleted file mode 100644
index 31a23386..00000000
--- a/src/acpi/aml/parsermacros.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-#[macro_export]
-macro_rules! parser_selector {
- {$data:expr, $ctx:expr, $func:expr} => {
- match $func($data, $ctx) {
- Ok(res) => return Ok(res),
- Err(AmlError::AmlInvalidOpCode) => (),
- Err(e) => return Err(e)
- }
- };
- {$data:expr, $ctx:expr, $func:expr, $($funcs:expr),+} => {
- parser_selector! {$data, $ctx, $func};
- parser_selector! {$data, $ctx, $($funcs),*};
- };
-}
-
-#[macro_export]
-macro_rules! parser_selector_simple {
- {$data:expr, $func:expr} => {
- match $func($data) {
- Ok(res) => return Ok(res),
- Err(AmlError::AmlInvalidOpCode) => (),
- Err(e) => return Err(e)
- }
- };
- {$data:expr, $func:expr, $($funcs:expr),+} => {
- parser_selector_simple! {$data, $func};
- parser_selector_simple! {$data, $($funcs),*};
- };
-}
-
-#[macro_export]
-macro_rules! parser_opcode {
- ($data:expr, $opcode:expr) => {
- if $data[0] != $opcode {
- return Err(AmlError::AmlInvalidOpCode);
- }
- };
- ($data:expr, $opcode:expr, $alternate_opcode:expr) => {
- if $data[0] != $opcode && $data[0] != $alternate_opcode {
- return Err(AmlError::AmlInvalidOpCode);
- }
- };
-}
-
-#[macro_export]
-macro_rules! parser_opcode_extended {
- ($data:expr, $opcode:expr) => {
- if $data[0] != 0x5B || $data[1] != $opcode {
- return Err(AmlError::AmlInvalidOpCode);
- }
- };
-}
diff --git a/src/acpi/aml/pkglength.rs b/src/acpi/aml/pkglength.rs
deleted file mode 100644
index 7b511f9b..00000000
--- a/src/acpi/aml/pkglength.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use super::AmlError;
-
-pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlError> {
- let lead_byte = data[0];
- let count_bytes: usize = (lead_byte >> 6) as usize;
-
- if count_bytes == 0 {
- return Ok(((lead_byte & 0x3F) as usize, 1 as usize));
- }
-
- let upper_two = (lead_byte >> 4) & 0x03;
- if upper_two != 0 {
- return Err(AmlError::AmlParseError("Invalid package length"));
- }
-
- let mut current_byte = 0;
- let mut pkg_len: usize = (lead_byte & 0x0F) as usize;
-
- while current_byte < count_bytes {
- pkg_len += (data[1 + current_byte] as u32 * 16 * (256 as u32).pow(current_byte as u32)) as usize;
- current_byte += 1;
- }
-
- Ok((pkg_len, count_bytes + 1))
-}
diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs
deleted file mode 100644
index cd8e1033..00000000
--- a/src/acpi/aml/termlist.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-use alloc::vec::Vec;
-
-use super::AmlError;
-use super::parser::{ AmlParseType, ParseResult, AmlExecutionContext, ExecutionState };
-use super::namespace::{AmlValue, get_namespace_string};
-use super::namespacemodifier::parse_namespace_modifier;
-use super::namedobj::parse_named_obj;
-use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj};
-use super::type1opcode::parse_type1_opcode;
-use super::type2opcode::parse_type2_opcode;
-use super::namestring::parse_name_string;
-
-pub fn parse_term_list(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let mut current_offset: usize = 0;
-
- while current_offset < data.len() {
- let res = parse_term_obj(&data[current_offset..], ctx)?;
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: data.len()
- })
- }
-
- current_offset += res.len;
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: data.len()
- })
-}
-
-pub fn parse_term_arg(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_local_obj,
- parse_data_obj,
- parse_arg_obj,
- parse_type2_opcode
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_object_list(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let mut current_offset: usize = 0;
-
- while current_offset < data.len() {
- let res = parse_object(&data[current_offset..], ctx)?;
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: data.len()
- })
- }
-
- current_offset += res.len;
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: data.len()
- })
-}
-
-fn parse_object(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_namespace_modifier,
- parse_named_obj
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_method_invocation(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let name = parse_name_string(data, ctx)?;
- let method = ctx.get(name.val.clone())?;
-
- let method = match method {
- AmlValue::None => return Err(AmlError::AmlDeferredLoad),
- _ => method.get_as_method()?
- };
-
- let mut cur = 0;
- let mut params: Vec = vec!();
-
- let mut current_offset = name.len;
-
- while cur < method.arg_count {
- let res = parse_term_arg(&data[current_offset..], ctx)?;
-
- current_offset += res.len;
- cur += 1;
-
- params.push(res.val);
- }
-
- Ok(AmlParseType {
- val: method.execute(get_namespace_string(ctx.scope.clone(), name.val)?, params),
- len: current_offset
- })
-}
-
-fn parse_term_obj(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_namespace_modifier,
- parse_named_obj,
- parse_type1_opcode,
- parse_type2_opcode
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs
deleted file mode 100644
index 2204e9c8..00000000
--- a/src/acpi/aml/type1opcode.rs
+++ /dev/null
@@ -1,472 +0,0 @@
-use super::AmlError;
-use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
-use super::namespace::AmlValue;
-use super::pkglength::parse_pkg_length;
-use super::termlist::{parse_term_arg, parse_term_list};
-use super::namestring::{parse_name_string, parse_super_name};
-
-use time::monotonic;
-
-use acpi::{Sdt, load_table, get_sdt_signature};
-use super::{parse_aml_table, is_aml_table};
-
-pub fn parse_type1_opcode(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_def_break,
- parse_def_breakpoint,
- parse_def_continue,
- parse_def_noop,
- parse_def_fatal,
- parse_def_if_else,
- parse_def_load,
- parse_def_notify,
- parse_def_release,
- parse_def_reset,
- parse_def_signal,
- parse_def_sleep,
- parse_def_stall,
- parse_def_return,
- parse_def_unload,
- parse_def_while
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-fn parse_def_break(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0xA5);
- ctx.state = ExecutionState::BREAK;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 as usize
- })
-}
-
-fn parse_def_breakpoint(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0xCC);
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 as usize
- })
-}
-
-fn parse_def_continue(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x9F);
- ctx.state = ExecutionState::CONTINUE;
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 as usize
- })
-}
-
-fn parse_def_noop(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0xA3);
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 as usize
- })
-}
-
-fn parse_def_fatal(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x32);
-
- let fatal_type = data[2];
- let fatal_code: u16 = (data[3] as u16) + ((data[4] as u16) << 8);
- let fatal_arg = parse_term_arg(&data[5..], ctx)?;
-
- Err(AmlError::AmlFatalError(fatal_type, fatal_code, fatal_arg.val))
-}
-
-fn parse_def_load(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x20);
-
- let name = parse_name_string(&data[2..], ctx)?;
- let ddb_handle_object = parse_super_name(&data[2 + name.len..], ctx)?;
-
- let tbl = ctx.get(name.val)?.get_as_buffer()?;
- let sdt = unsafe { &*(tbl.as_ptr() as *const Sdt) };
-
- if is_aml_table(sdt) {
- load_table(get_sdt_signature(sdt));
- let delta = parse_aml_table(sdt)?;
- let _ = ctx.modify(ddb_handle_object.val, AmlValue::DDBHandle((delta, get_sdt_signature(sdt))));
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + name.len + ddb_handle_object.len
- })
- } else {
- Err(AmlError::AmlValueError)
- }
-}
-
-fn parse_def_notify(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x86);
-
- let object = parse_super_name(&data[1..], ctx)?;
- let value = parse_term_arg(&data[1 + object.len..], ctx)?;
-
- let number = value.val.get_as_integer()? as u8;
-
- match ctx.get(object.val)? {
- AmlValue::Device(d) => {
- if let Some(methods) = d.notify_methods.get(&number) {
- for method in methods {
- method();
- }
- }
- },
- AmlValue::Processor(d) => {
- if let Some(methods) = d.notify_methods.get(&number) {
- for method in methods {
- method();
- }
- }
- },
- AmlValue::ThermalZone(d) => {
- if let Some(methods) = d.notify_methods.get(&number) {
- for method in methods {
- method();
- }
- }
- },
- _ => return Err(AmlError::AmlValueError)
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + object.len + value.len
- })
-}
-
-fn parse_def_release(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x27);
-
- let obj = parse_super_name(&data[2..], ctx)?;
- let _ = ctx.release_mutex(obj.val);
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + obj.len
- })
-}
-
-fn parse_def_reset(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x26);
-
- let object = parse_super_name(&data[2..], ctx)?;
- ctx.get(object.val.clone())?.get_as_event()?;
-
- let _ = ctx.modify(object.val.clone(), AmlValue::Event(0));
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + object.len
- })
-}
-
-fn parse_def_signal(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x24);
- let object = parse_super_name(&data[2..], ctx)?;
-
- ctx.signal_event(object.val)?;
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + object.len
- })
-}
-
-fn parse_def_sleep(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x22);
-
- let time = parse_term_arg(&data[2..], ctx)?;
- let timeout = time.val.get_as_integer()?;
-
- let (seconds, nanoseconds) = monotonic();
- let starting_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- loop {
- let (seconds, nanoseconds) = monotonic();
- let current_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- if current_time_ns - starting_time_ns > timeout as u64 * 1_000_000 {
- break;
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + time.len
- })
-}
-
-fn parse_def_stall(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x21);
-
- let time = parse_term_arg(&data[2..], ctx)?;
- let timeout = time.val.get_as_integer()?;
-
- let (seconds, nanoseconds) = monotonic();
- let starting_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- loop {
- let (seconds, nanoseconds) = monotonic();
- let current_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- if current_time_ns - starting_time_ns > timeout as u64 * 1000 {
- break;
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + time.len
- })
-}
-
-fn parse_def_unload(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x2A);
-
- let object = parse_super_name(&data[2..], ctx)?;
-
- let delta = ctx.get(object.val)?.get_as_ddb_handle()?;
- let mut namespace = ctx.prelock();
-
- if let Some(ref mut ns) = *namespace {
- for o in delta.0 {
- ns.remove(&o);
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 2 + object.len
- })
-}
-
-fn parse_def_if_else(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0xA0);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
- let if_condition = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?;
-
- let (else_length, else_length_len) = if data.len() > 1 + pkg_length && data[1 + pkg_length] == 0xA1 {
- parse_pkg_length(&data[2 + pkg_length..])?
- } else {
- (0 as usize, 0 as usize)
- };
-
- if if_condition.val.get_as_integer()? > 0 {
- parse_term_list(&data[1 + pkg_length_len + if_condition.len .. 1 + pkg_length], ctx)?;
- } else if else_length > 0 {
- parse_term_list(&data[2 + pkg_length + else_length_len .. 2 + pkg_length + else_length], ctx)?;
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + pkg_length + if else_length > 0 { 1 + else_length } else { 0 }
- })
-}
-
-fn parse_def_while(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0xA2);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-
- loop {
- let predicate = parse_term_arg(&data[1 + pkg_length_len..], ctx)?;
- if predicate.val.get_as_integer()? == 0 {
- break;
- }
-
- parse_term_list(&data[1 + pkg_length_len + predicate.len .. 1 + pkg_length], ctx)?;
-
- match ctx.state {
- ExecutionState::EXECUTING => (),
- ExecutionState::BREAK => {
- ctx.state = ExecutionState::EXECUTING;
- break;
- },
- ExecutionState::CONTINUE => ctx.state = ExecutionState::EXECUTING,
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + pkg_length
- })
-}
-
-fn parse_def_return(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0xA4);
-
- let arg_object = parse_term_arg(&data[1..], ctx)?;
- ctx.state = ExecutionState::RETURN(arg_object.val);
-
- Ok(AmlParseType {
- val: AmlValue::None,
- len: 1 + arg_object.len
- })
-}
diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs
deleted file mode 100644
index 9b4e7ef1..00000000
--- a/src/acpi/aml/type2opcode.rs
+++ /dev/null
@@ -1,1779 +0,0 @@
-use alloc::boxed::Box;
-use alloc::string::String;
-use alloc::vec::Vec;
-
-use super::{AmlError, parse_aml_with_scope};
-use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
-use super::namespace::{AmlValue, ObjectReference};
-use super::pkglength::parse_pkg_length;
-use super::termlist::{parse_term_arg, parse_method_invocation};
-use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name};
-use super::dataobj::parse_data_ref_obj;
-
-use time::monotonic;
-use acpi::SDT_POINTERS;
-
-#[derive(Debug, Clone)]
-pub enum MatchOpcode {
- MTR,
- MEQ,
- MLE,
- MLT,
- MGE,
- MGT
-}
-
-pub fn parse_type2_opcode(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_def_increment,
- parse_def_acquire,
- parse_def_wait,
- parse_def_land,
- parse_def_lequal,
- parse_def_lgreater,
- parse_def_lless,
- parse_def_lnot,
- parse_def_lor,
- parse_def_size_of,
- parse_def_store,
- parse_def_subtract,
- parse_def_to_buffer,
- parse_def_to_hex_string,
- parse_def_to_bcd,
- parse_def_to_decimal_string,
- parse_def_to_integer,
- parse_def_to_string,
- parse_def_add,
- parse_def_xor,
- parse_def_shift_left,
- parse_def_shift_right,
- parse_def_mod,
- parse_def_and,
- parse_def_or,
- parse_def_concat_res,
- parse_def_concat,
- parse_def_cond_ref_of,
- parse_def_copy_object,
- parse_def_decrement,
- parse_def_divide,
- parse_def_find_set_left_bit,
- parse_def_find_set_right_bit,
- parse_def_from_bcd,
- parse_def_load_table,
- parse_def_match,
- parse_def_mid,
- parse_def_multiply,
- parse_def_nand,
- parse_def_nor,
- parse_def_not,
- parse_def_timer,
- parse_def_buffer,
- parse_def_package,
- parse_def_var_package,
- parse_def_object_type,
- parse_def_deref_of,
- parse_def_ref_of,
- parse_def_index,
- parse_method_invocation
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_type6_opcode(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_selector! {
- data, ctx,
- parse_def_deref_of,
- parse_def_ref_of,
- parse_def_index,
- parse_method_invocation
- };
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_def_object_type(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x8E);
- parser_selector! {
- data, ctx,
- parse_super_name,
- parse_def_ref_of,
- parse_def_deref_of,
- parse_def_index
- }
-
- Err(AmlError::AmlInvalidOpCode)
-}
-
-pub fn parse_def_package(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: Handle deferred loads in here
- parser_opcode!(data, 0x12);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
- let numelements = data[1 + pkg_length_len] as usize;
- let mut elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], ctx)?.val.get_as_package()?;
-
- if elements.len() > numelements {
- elements = elements[0 .. numelements].to_vec();
- } else if numelements > elements.len() {
- for _ in 0..numelements - elements.len() {
- elements.push(AmlValue::Uninitialized);
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::Package(elements),
- len: 1 + pkg_length
- })
-}
-
-pub fn parse_def_var_package(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: Handle deferred loads in here
- parser_opcode!(data, 0x13);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
- let num_elements = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?;
- let mut elements = parse_package_elements_list(&data[1 + pkg_length_len + num_elements.len ..
- 1 + pkg_length], ctx)?.val.get_as_package()?;
-
- let numelements = num_elements.val.get_as_integer()? as usize;
-
- if elements.len() > numelements {
- elements = elements[0 .. numelements].to_vec();
- } else if numelements > elements.len() {
- for _ in 0..numelements - elements.len() {
- elements.push(AmlValue::Uninitialized);
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::Package(elements),
- len: 1 + pkg_length
- })
-}
-
-fn parse_package_elements_list(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- let mut current_offset: usize = 0;
- let mut elements: Vec = vec!();
-
- while current_offset < data.len() {
- let dro = if let Ok(e) = parse_data_ref_obj(&data[current_offset..], ctx) {
- e
- } else {
- let d = parse_name_string(&data[current_offset..], ctx)?;
- AmlParseType {
- val: AmlValue::ObjectReference(ObjectReference::Object(d.val.get_as_string()?)),
- len: d.len
- }
- };
-
- elements.push(dro.val);
- current_offset += dro.len;
- }
-
- Ok(AmlParseType {
- val: AmlValue::Package(elements),
- len: data.len()
- })
-}
-
-pub fn parse_def_buffer(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x11);
-
- let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
- let buffer_size = parse_term_arg(&data[1 + pkg_length_len..], ctx)?;
- let mut byte_list = data[1 + pkg_length_len + buffer_size.len .. 1 + pkg_length].to_vec().clone();
-
- byte_list.truncate(buffer_size.val.get_as_integer()? as usize);
-
- Ok(AmlParseType {
- val: AmlValue::Buffer(byte_list),
- len: 1 + pkg_length
- })
-}
-
-fn parse_def_ref_of(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x71);
-
- let obj = parse_super_name(&data[1..], ctx)?;
- let res = match obj.val {
- AmlValue::String(ref s) => {
- match ctx.get(AmlValue::String(s.clone()))? {
- AmlValue::None => return Err(AmlError::AmlValueError),
- _ => ObjectReference::Object(s.clone())
- }
- },
- AmlValue::ObjectReference(ref o) => o.clone(),
- _ => return Err(AmlError::AmlValueError)
- };
-
- Ok(AmlParseType {
- val: AmlValue::ObjectReference(res),
- len: 1 + obj.len
- })
-}
-
-fn parse_def_deref_of(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x83);
-
- let obj = parse_term_arg(&data[1..], ctx)?;
- let res = ctx.get(obj.val)?;
-
- match res {
- AmlValue::None => Err(AmlError::AmlValueError),
- _ => Ok(AmlParseType {
- val: res,
- len: 1 + obj.len
- })
- }
-}
-
-fn parse_def_acquire(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x23);
-
- let obj = parse_super_name(&data[1..], ctx)?;
- let timeout = (data[2 + obj.len] as u16) + ((data[3 + obj.len] as u16) << 8);
-
- let (seconds, nanoseconds) = monotonic();
- let starting_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- loop {
- match ctx.acquire_mutex(obj.val.clone()) {
- Err(e) => return Err(e),
- Ok(b) => if b {
- return Ok(AmlParseType {
- val: AmlValue::Integer(0),
- len: 4 + obj.len
- });
- } else if timeout == 0xFFFF {
- // TODO: Brief sleep here
- } else {
- let (seconds, nanoseconds) = monotonic();
- let current_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- if current_time_ns - starting_time_ns > timeout as u64 * 1_000_000 {
- return Ok(AmlParseType {
- val: AmlValue::Integer(1),
- len: 4 + obj.len
- });
- }
- }
- }
- }
-}
-
-fn parse_def_increment(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x75);
-
- let obj = parse_super_name(&data[1..], ctx)?;
-
- let _namespace = ctx.prelock();
- let value = AmlValue::Integer(ctx.get(obj.val.clone())?.get_as_integer()? + 1);
- let _ = ctx.modify(obj.val, value.clone());
-
- Ok(AmlParseType {
- val: value,
- len: 1 + obj.len
- })
-}
-
-fn parse_def_index(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x88);
-
- let obj = parse_term_arg(&data[1..], ctx)?;
- let idx = parse_term_arg(&data[1 + obj.len..], ctx)?;
- let target = parse_target(&data[1 + obj.len + idx.len..], ctx)?;
-
- let reference = AmlValue::ObjectReference(ObjectReference::Index(Box::new(obj.val), Box::new(idx.val)));
- let _ = ctx.modify(target.val, reference.clone());
-
- Ok(AmlParseType {
- val: reference,
- len: 1 + obj.len + idx.len + target.len
- })
-}
-
-fn parse_def_land(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x90);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
-
- let result = if lhs.val.get_as_integer()? > 0 && rhs.val.get_as_integer()? > 0 { 1 } else { 0 };
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(result),
- len: 1 + lhs.len + rhs.len
- })
-}
-
-fn parse_def_lequal(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x93);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
-
- let result = if lhs.val.get_as_integer()? == rhs.val.get_as_integer()? { 1 } else { 0 };
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(result),
- len: 1 + lhs.len + rhs.len
- })
-}
-
-fn parse_def_lgreater(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x94);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
-
- let result = if lhs.val.get_as_integer()? > rhs.val.get_as_integer()? { 1 } else { 0 };
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(result),
- len: 1 + lhs.len + rhs.len
- })
-}
-
-fn parse_def_lless(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x95);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
-
- let result = if lhs.val.get_as_integer()? < rhs.val.get_as_integer()? { 1 } else { 0 };
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(result),
- len: 1 + lhs.len + rhs.len
- })
-}
-
-fn parse_def_lnot(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x92);
-
- let operand = parse_term_arg(&data[1..], ctx)?;
- let result = if operand.val.get_as_integer()? == 0 { 1 } else { 0 };
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(result),
- len: 1 + operand.len
- })
-}
-
-fn parse_def_lor(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x91);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
-
- let result = if lhs.val.get_as_integer()? > 0 || rhs.val.get_as_integer()? > 0 { 1 } else { 0 };
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(result),
- len: 1 + lhs.len + rhs.len
- })
-}
-
-fn parse_def_to_hex_string(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x98);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let res = match operand.val {
- AmlValue::Integer(_) => {
- let result: String = format!("{:X}", operand.val.get_as_integer()?);
- AmlValue::String(result)
- },
- AmlValue::String(s) => AmlValue::String(s),
- AmlValue::Buffer(_) => {
- let mut string: String = String::new();
-
- for b in operand.val.get_as_buffer()? {
- string.push_str(&format!("{:X}", b));
- }
-
- AmlValue::String(string)
- },
- _ => return Err(AmlError::AmlValueError)
- };
-
- let _ = ctx.modify(target.val, res.clone());
-
- Ok(AmlParseType {
- val: res,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_to_buffer(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x96);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let res = AmlValue::Buffer(operand.val.get_as_buffer()?);
- let _ = ctx.modify(target.val, res.clone());
-
- Ok(AmlParseType {
- val: res,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_to_bcd(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x29);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let mut i = operand.val.get_as_integer()?;
- let mut result = 0;
-
- while i != 0 {
- result <<= 4;
- result += i % 10;
- i /= 10;
- }
-
- let result = AmlValue::Integer(result);
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_to_decimal_string(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x97);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
- let res = match operand.val {
- AmlValue::Integer(_) => {
- let result: String = format!("{}", operand.val.get_as_integer()?);
- AmlValue::String(result)
- },
- AmlValue::String(s) => AmlValue::String(s),
- AmlValue::Buffer(_) => {
- let mut string: String = String::new();
-
- for b in operand.val.get_as_buffer()? {
- string.push_str(&format!("{}", b));
- }
-
- AmlValue::String(string)
- },
- _ => return Err(AmlError::AmlValueError)
- };
-
- let _ = ctx.modify(target.val, res.clone());
-
- Ok(AmlParseType {
- val: res,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_to_integer(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x99);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let res = AmlValue::Integer(operand.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, res.clone());
-
- Ok(AmlParseType {
- val: res,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_to_string(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x9C);
-
- let operand = parse_term_arg(&data[1..], ctx)?;
- let length = parse_term_arg(&data[1 + operand.len..], ctx)?;
- let target = parse_target(&data[1 + operand.len + length.len..], ctx)?;
-
- let buf = operand.val.get_as_buffer()?;
- let mut string = match String::from_utf8(buf) {
- Ok(s) => s,
- Err(_) => return Err(AmlError::AmlValueError)
- };
-
- string.truncate(length.val.get_as_integer()? as usize);
- let res = AmlValue::String(string);
-
- let _ = ctx.modify(target.val, res.clone());
-
- Ok(AmlParseType {
- val: res,
- len: 1 + operand.len + length.len + target.len
- })
-}
-
-fn parse_def_subtract(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x74);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? - rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_size_of(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x87);
-
- let name = parse_super_name(&data[1..], ctx)?;
- let obj = ctx.get(name.val)?;
-
- let res = match obj {
- AmlValue::Buffer(ref v) => v.len(),
- AmlValue::String(ref s) => s.len(),
- AmlValue::Package(ref p) => p.len(),
- _ => return Err(AmlError::AmlValueError)
- };
-
- Ok(AmlParseType {
- val: AmlValue::Integer(res as u64),
- len: 1 + name.len
- })
-}
-
-fn parse_def_store(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x70);
-
- let operand = parse_term_arg(&data[1..], ctx)?;
- let target = parse_super_name(&data[1 + operand.len..], ctx)?;
-
- let _ = ctx.modify(target.val.clone(), operand.val);
-
- Ok(AmlParseType {
- val: target.val,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_or(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x7D);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_shift_left(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x79);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_shift_right(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x7A);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? << rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_add(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x72);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? + rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_and(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x7B);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_xor(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x7F);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_concat_res(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x84);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let mut buf1 = lhs.val.get_as_buffer()?.clone();
- let mut buf2 = rhs.val.get_as_buffer()?.clone();
-
- if buf1.len() == 1 || buf2.len() == 1 {
- return Err(AmlError::AmlValueError);
- }
-
- if buf1.len() >= 2 && buf1[buf1.len() - 2] == 0x79 {
- buf1 = buf1[0..buf1.len() - 2].to_vec();
- }
-
- if buf2.len() >= 2 && buf2[buf2.len() - 2] == 0x79 {
- buf2 = buf2[0..buf2.len() - 2].to_vec();
- }
-
- buf1.append(&mut buf2);
- buf1.push(0x79);
-
- let mut checksum: u8 = 0;
- let loopbuf = buf1.clone();
- for b in loopbuf {
- checksum += b;
- }
-
- checksum = (!checksum) + 1;
- buf1.push(checksum);
-
- let res = AmlValue::Buffer(buf1);
- ctx.modify(target.val, res.clone())?;
-
- Ok(AmlParseType {
- val: res,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_wait(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x25);
-
- let obj = parse_super_name(&data[2..], ctx)?;
- let timeout_obj = parse_term_arg(&data[2 + obj.len..], ctx)?;
-
- let timeout = timeout_obj.val.get_as_integer()?;
-
- let (seconds, nanoseconds) = monotonic();
- let starting_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- loop {
- match ctx.wait_for_event(obj.val.clone()) {
- Err(e) => return Err(e),
- Ok(b) => if b {
- return Ok(AmlParseType {
- val: AmlValue::Integer(0),
- len: 2 + obj.len + timeout_obj.len
- })
- } else if timeout >= 0xFFFF {
- // TODO: Brief sleep here
- } else {
- let (seconds, nanoseconds) = monotonic();
- let current_time_ns = nanoseconds + (seconds * 1_000_000_000);
-
- if current_time_ns - starting_time_ns > timeout as u64 * 1_000_000 {
- return Ok(AmlParseType {
- val: AmlValue::Integer(1),
- len: 2 + obj.len + timeout_obj.len
- });
- }
- }
- }
- }
-}
-
-fn parse_def_cond_ref_of(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x12);
-
- let obj = parse_super_name(&data[2..], ctx)?;
- let target = parse_target(&data[2 + obj.len..], ctx)?;
-
- let res = match obj.val {
- AmlValue::String(ref s) => {
- match ctx.get(AmlValue::String(s.clone()))? {
- AmlValue::None => return Ok(AmlParseType {
- val: AmlValue::Integer(0),
- len: 1 + obj.len + target.len
- }),
- _ => ObjectReference::Object(s.clone())
- }
- },
- AmlValue::ObjectReference(ref o) => o.clone(),
- _ => return Err(AmlError::AmlValueError)
- };
-
- let _ = ctx.modify(target.val, AmlValue::ObjectReference(res));
-
- Ok(AmlParseType {
- val: AmlValue::Integer(1),
- len: 1 + obj.len + target.len
- })
-}
-
-fn parse_def_copy_object(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: Compute the result
- // TODO: Store the result
- parser_opcode!(data, 0x9D);
-
- let source = parse_term_arg(&data[1..], ctx)?;
- let destination = parse_simple_name(&data[1 + source.len..], ctx)?;
-
- ctx.copy(destination.val, source.val.clone())?;
-
- Ok(AmlParseType {
- val: source.val,
- len: 1 + source.len + destination.len
- })
-}
-
-fn parse_def_concat(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x73);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = match lhs.val {
- AmlValue::Integer(_i) => {
- let j = AmlValue::Integer(rhs.val.get_as_integer()?);
-
- let mut first = lhs.val.get_as_buffer()?.clone();
- let mut second = j.get_as_buffer()?.clone();
-
- first.append(&mut second);
-
- AmlValue::Buffer(first)
- },
- AmlValue::String(s) => {
- let t = if let Ok(t) = rhs.val.get_as_string() {
- t
- } else {
- rhs.val.get_type_string()
- };
-
- AmlValue::String(format!("{}{}", s, t))
- },
- AmlValue::Buffer(b) => {
- let mut b = b.clone();
- let mut c = if let Ok(c) = rhs.val.get_as_buffer() {
- c.clone()
- } else {
- AmlValue::String(rhs.val.get_type_string()).get_as_buffer()?.clone()
- };
-
- b.append(&mut c);
-
- AmlValue::Buffer(b)
- },
- _ => {
- let first = lhs.val.get_type_string();
- let second = if let Ok(second) = rhs.val.get_as_string() {
- second
- } else {
- rhs.val.get_type_string()
- };
-
- AmlValue::String(format!("{}{}", first, second))
- }
- };
-
- ctx.modify(target.val, result.clone())?;
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_decrement(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x76);
-
- let obj = parse_super_name(&data[1..], ctx)?;
-
- let _namespace = ctx.prelock();
- let value = AmlValue::Integer(ctx.get(obj.val.clone())?.get_as_integer()? - 1);
- let _ = ctx.modify(obj.val, value.clone());
-
- Ok(AmlParseType {
- val: value,
- len: 1 + obj.len
- })
-}
-
-fn parse_def_divide(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x78);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target_remainder = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
- let target_quotient = parse_target(&data[1 + lhs.len + rhs.len + target_remainder.len..], ctx)?;
-
- let numerator = lhs.val.get_as_integer()?;
- let denominator = rhs.val.get_as_integer()?;
-
- let remainder = numerator % denominator;
- let quotient = (numerator - remainder) / denominator;
-
- let _ = ctx.modify(target_remainder.val, AmlValue::Integer(remainder));
- let _ = ctx.modify(target_quotient.val, AmlValue::Integer(quotient));
-
- Ok(AmlParseType {
- val: AmlValue::Integer(quotient),
- len: 1 + lhs.len + rhs.len + target_remainder.len + target_quotient.len
- })
-}
-
-fn parse_def_find_set_left_bit(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x81);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let mut first_bit = 32;
- let mut test = operand.val.get_as_integer()?;
-
- while first_bit > 0{
- if test & 0x8000_0000_0000_0000 > 0 {
- break;
- }
-
- test <<= 1;
- first_bit -= 1;
- }
-
- let result = AmlValue::Integer(first_bit);
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_find_set_right_bit(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x82);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let mut first_bit = 1;
- let mut test = operand.val.get_as_integer()?;
-
- while first_bit <= 32 {
- if test & 1 > 0 {
- break;
- }
-
- test >>= 1;
- first_bit += 1;
- }
-
- if first_bit == 33 {
- first_bit = 0;
- }
-
- let result = AmlValue::Integer(first_bit);
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_load_table(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: Clean up
- parser_opcode_extended!(data, 0x1F);
-
- let signature = parse_term_arg(&data[2..], ctx)?;
- let oem_id = parse_term_arg(&data[2 + signature.len..], ctx)?;
- let oem_table_id = parse_term_arg(&data[2 + signature.len + oem_id.len..], ctx)?;
- let root_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len..], ctx)?;
- let parameter_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len..], ctx)?;
- let parameter_data = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len..], ctx)?;
-
- if let Some(ref ptrs) = *(SDT_POINTERS.read()) {
- let sig_str = unsafe {
- let sig = *(signature.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 4]);
- String::from_utf8(sig.to_vec()).expect("Error converting signature to string")
- };
- let oem_str = unsafe {
- *(oem_id.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 6])
- };
- let oem_table_str = unsafe {
- *(oem_table_id.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 8])
- };
-
- let sdt_signature = (sig_str, oem_str, oem_table_str);
-
- let sdt = ptrs.get(&sdt_signature);
-
- if let Some(sdt) = sdt {
- let hdl = parse_aml_with_scope(sdt, root_path.val.get_as_string()?)?;
- let _ = ctx.modify(parameter_path.val, parameter_data.val);
-
- return Ok(AmlParseType {
- val: AmlValue::DDBHandle((hdl, sdt_signature)),
- len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len
- });
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(0),
- len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len
- })
-}
-
-fn parse_def_match(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x28);
-
- let search_pkg = parse_term_arg(&data[1..], ctx)?;
-
- let first_operation = match data[1 + search_pkg.len] {
- 0 => MatchOpcode::MTR,
- 1 => MatchOpcode::MEQ,
- 2 => MatchOpcode::MLE,
- 3 => MatchOpcode::MLT,
- 4 => MatchOpcode::MGE,
- 5 => MatchOpcode::MGT,
- _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode"))
- };
- let first_operand = parse_term_arg(&data[2 + search_pkg.len..], ctx)?;
-
- let second_operation = match data[2 + search_pkg.len + first_operand.len] {
- 0 => MatchOpcode::MTR,
- 1 => MatchOpcode::MEQ,
- 2 => MatchOpcode::MLE,
- 3 => MatchOpcode::MLT,
- 4 => MatchOpcode::MGE,
- 5 => MatchOpcode::MGT,
- _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode"))
- };
- let second_operand = parse_term_arg(&data[3 + search_pkg.len + first_operand.len..], ctx)?;
-
- let start_index = parse_term_arg(&data[3 + search_pkg.len + first_operand.len + second_operand.len..], ctx)?;
-
- let pkg = search_pkg.val.get_as_package()?;
- let mut idx = start_index.val.get_as_integer()? as usize;
-
- match first_operand.val {
- AmlValue::Integer(i) => {
- let j = second_operand.val.get_as_integer()?;
-
- while idx < pkg.len() {
- let val = if let Ok(v) = pkg[idx].get_as_integer() { v } else { idx += 1; continue; };
- idx += 1;
-
- match first_operation {
- MatchOpcode::MTR => (),
- MatchOpcode::MEQ => if val != i { continue },
- MatchOpcode::MLE => if val > i { continue },
- MatchOpcode::MLT => if val >= i { continue },
- MatchOpcode::MGE => if val < i { continue },
- MatchOpcode::MGT => if val <= i { continue }
- }
-
- match second_operation {
- MatchOpcode::MTR => (),
- MatchOpcode::MEQ => if val != j { continue },
- MatchOpcode::MLE => if val > j { continue },
- MatchOpcode::MLT => if val >= j { continue },
- MatchOpcode::MGE => if val < j { continue },
- MatchOpcode::MGT => if val <= j { continue }
- }
-
- return Ok(AmlParseType {
- val: AmlValue::Integer(idx as u64),
- len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
- })
- }
- },
- AmlValue::String(i) => {
- let j = second_operand.val.get_as_string()?;
-
- while idx < pkg.len() {
- let val = if let Ok(v) = pkg[idx].get_as_string() { v } else { idx += 1; continue; };
- idx += 1;
-
- match first_operation {
- MatchOpcode::MTR => (),
- MatchOpcode::MEQ => if val != i { continue },
- MatchOpcode::MLE => if val > i { continue },
- MatchOpcode::MLT => if val >= i { continue },
- MatchOpcode::MGE => if val < i { continue },
- MatchOpcode::MGT => if val <= i { continue }
- }
-
- match second_operation {
- MatchOpcode::MTR => (),
- MatchOpcode::MEQ => if val != j { continue },
- MatchOpcode::MLE => if val > j { continue },
- MatchOpcode::MLT => if val >= j { continue },
- MatchOpcode::MGE => if val < j { continue },
- MatchOpcode::MGT => if val <= j { continue }
- }
-
- return Ok(AmlParseType {
- val: AmlValue::Integer(idx as u64),
- len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
- })
- }
- },
- _ => {
- let i = first_operand.val.get_as_buffer()?;
- let j = second_operand.val.get_as_buffer()?;
-
- while idx < pkg.len() {
- let val = if let Ok(v) = pkg[idx].get_as_buffer() { v } else { idx += 1; continue; };
- idx += 1;
-
- match first_operation {
- MatchOpcode::MTR => (),
- MatchOpcode::MEQ => if val != i { continue },
- MatchOpcode::MLE => if val > i { continue },
- MatchOpcode::MLT => if val >= i { continue },
- MatchOpcode::MGE => if val < i { continue },
- MatchOpcode::MGT => if val <= i { continue }
- }
-
- match second_operation {
- MatchOpcode::MTR => (),
- MatchOpcode::MEQ => if val != j { continue },
- MatchOpcode::MLE => if val > j { continue },
- MatchOpcode::MLT => if val >= j { continue },
- MatchOpcode::MGE => if val < j { continue },
- MatchOpcode::MGT => if val <= j { continue }
- }
-
- return Ok(AmlParseType {
- val: AmlValue::Integer(idx as u64),
- len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
- })
- }
- }
- }
-
- Ok(AmlParseType {
- val: AmlValue::IntegerConstant(0xFFFF_FFFF_FFFF_FFFF),
- len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
- })
-}
-
-fn parse_def_from_bcd(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x28);
-
- let operand = parse_term_arg(&data[2..], ctx)?;
- let target = parse_target(&data[2 + operand.len..], ctx)?;
-
- let mut i = operand.val.get_as_integer()?;
- let mut result = 0;
-
- while i != 0 {
- if i & 0x0F > 10 {
- return Err(AmlError::AmlValueError);
- }
-
- result *= 10;
- result += i & 0x0F;
- i >>= 4;
- }
-
- let result = AmlValue::Integer(result);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 2 + operand.len + target.len
- })
-}
-
-fn parse_def_mid(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x9E);
-
- let source = parse_term_arg(&data[1..], ctx)?;
- let index = parse_term_arg(&data[1 + source.len..], ctx)?;
- let length = parse_term_arg(&data[1 + source.len + index.len..], ctx)?;
- let target = parse_target(&data[1 + source.len + index.len + length.len..], ctx)?;
-
- let idx = index.val.get_as_integer()? as usize;
- let mut len = length.val.get_as_integer()? as usize;
-
- let result = match source.val {
- AmlValue::String(s) => {
- if idx > s.len() {
- AmlValue::String(String::new())
- } else {
- let mut res = s.clone().split_off(idx);
-
- if len < res.len() {
- res.split_off(len);
- }
-
- AmlValue::String(res)
- }
- },
- _ => {
- // If it isn't a string already, treat it as a buffer. Must perform that check first,
- // as Mid can operate on both strings and buffers, but a string can be cast as a buffer
- // implicitly.
- // Additionally, any type that can be converted to a buffer can also be converted to a
- // string, so no information is lost
- let b = source.val.get_as_buffer()?;
-
- if idx > b.len() {
- AmlValue::Buffer(vec!())
- } else {
- if idx + len > b.len() {
- len = b.len() - idx;
- }
-
- AmlValue::Buffer(b[idx .. idx + len].to_vec())
- }
- }
- };
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + source.len + index.len + length.len + target.len
- })
-}
-
-fn parse_def_mod(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x85);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- if rhs.val.get_as_integer()? == 0 {
- return Err(AmlError::AmlValueError);
- }
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? % rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_multiply(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- // TODO: Handle overflow
- parser_opcode!(data, 0x77);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(lhs.val.get_as_integer()? * rhs.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_nand(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x7C);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(!(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?));
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_nor(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x7E);
-
- let lhs = parse_term_arg(&data[1..], ctx)?;
- let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
- let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
-
- let result = AmlValue::Integer(!(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?));
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + lhs.len + rhs.len + target.len
- })
-}
-
-fn parse_def_not(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode!(data, 0x80);
-
- let operand = parse_term_arg(&data[1..], ctx)?;
- let target = parse_target(&data[1 + operand.len..], ctx)?;
-
- let result = AmlValue::Integer(!operand.val.get_as_integer()?);
-
- let _ = ctx.modify(target.val, result.clone());
-
- Ok(AmlParseType {
- val: result,
- len: 1 + operand.len + target.len
- })
-}
-
-fn parse_def_timer(data: &[u8],
- ctx: &mut AmlExecutionContext) -> ParseResult {
- match ctx.state {
- ExecutionState::EXECUTING => (),
- _ => return Ok(AmlParseType {
- val: AmlValue::None,
- len: 0
- })
- }
-
- parser_opcode_extended!(data, 0x33);
-
- let (seconds, nanoseconds) = monotonic();
- let monotonic_ns = nanoseconds + (seconds * 1_000_000_000);
-
- Ok(AmlParseType {
- val: AmlValue::Integer(monotonic_ns),
- len: 2 as usize
- })
-}
diff --git a/src/acpi/dmar/drhd.rs b/src/acpi/dmar/drhd.rs
deleted file mode 100644
index 494917ef..00000000
--- a/src/acpi/dmar/drhd.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-#[repr(packed)]
-pub struct DrhdFault {
- pub sts: u32,
- pub ctrl: u32,
- pub data: u32,
- pub addr: [u32; 2],
- _rsv: [u64; 2],
- pub log: u64,
-}
-
-#[repr(packed)]
-pub struct DrhdProtectedMemory {
- pub en: u32,
- pub low_base: u32,
- pub low_limit: u32,
- pub high_base: u64,
- pub high_limit: u64,
-}
-
-#[repr(packed)]
-pub struct DrhdInvalidation {
- pub queue_head: u64,
- pub queue_tail: u64,
- pub queue_addr: u64,
- _rsv: u32,
- pub cmpl_sts: u32,
- pub cmpl_ctrl: u32,
- pub cmpl_data: u32,
- pub cmpl_addr: [u32; 2],
-}
-
-#[repr(packed)]
-pub struct DrhdPageRequest {
- pub queue_head: u64,
- pub queue_tail: u64,
- pub queue_addr: u64,
- _rsv: u32,
- pub sts: u32,
- pub ctrl: u32,
- pub data: u32,
- pub addr: [u32; 2],
-}
-
-#[repr(packed)]
-pub struct DrhdMtrrVariable {
- pub base: u64,
- pub mask: u64,
-}
-
-#[repr(packed)]
-pub struct DrhdMtrr {
- pub cap: u64,
- pub def_type: u64,
- pub fixed: [u64; 11],
- pub variable: [DrhdMtrrVariable; 10],
-}
-
-#[repr(packed)]
-pub struct Drhd {
- pub version: u32,
- _rsv: u32,
- pub cap: u64,
- pub ext_cap: u64,
- pub gl_cmd: u32,
- pub gl_sts: u32,
- pub root_table: u64,
- pub ctx_cmd: u64,
- _rsv1: u32,
- pub fault: DrhdFault,
- _rsv2: u32,
- pub pm: DrhdProtectedMemory,
- pub invl: DrhdInvalidation,
- _rsv3: u64,
- pub intr_table: u64,
- pub page_req: DrhdPageRequest,
- pub mtrr: DrhdMtrr,
-}
diff --git a/src/acpi/dmar/mod.rs b/src/acpi/dmar/mod.rs
deleted file mode 100644
index 11687181..00000000
--- a/src/acpi/dmar/mod.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-use core::mem;
-
-use super::sdt::Sdt;
-use self::drhd::Drhd;
-use memory::Frame;
-use paging::{ActivePageTable, PhysicalAddress};
-use paging::entry::EntryFlags;
-
-use super::{find_sdt, load_table, get_sdt_signature};
-
-pub mod drhd;
-
-/// The DMA Remapping Table
-#[derive(Debug)]
-pub struct Dmar {
- sdt: &'static Sdt,
- pub addr_width: u8,
- pub flags: u8,
- _rsv: [u8; 10],
-}
-
-impl Dmar {
- pub fn init(active_table: &mut ActivePageTable) {
- let dmar_sdt = find_sdt("DMAR");
- let dmar = if dmar_sdt.len() == 1 {
- load_table(get_sdt_signature(dmar_sdt[0]));
- Dmar::new(dmar_sdt[0])
- } else {
- println!("Unable to find DMAR");
- return;
- };
-
- if let Some(dmar) = dmar {
- println!(" DMAR: {}: {}", dmar.addr_width, dmar.flags);
-
- for dmar_entry in dmar.iter() {
- println!(" {:?}", dmar_entry);
- match dmar_entry {
- DmarEntry::Drhd(dmar_drhd) => {
- let drhd = dmar_drhd.get(active_table);
-
- println!("VER: {:X}", drhd.version);
- println!("CAP: {:X}", drhd.cap);
- println!("EXT_CAP: {:X}", drhd.ext_cap);
- println!("GCMD: {:X}", drhd.gl_cmd);
- println!("GSTS: {:X}", drhd.gl_sts);
- println!("RT: {:X}", drhd.root_table);
- },
- _ => ()
- }
- }
- }
- }
-
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"DMAR" && sdt.data_len() >= 12 { //Not valid if no local address and flags
- let addr_width = unsafe { *(sdt.data_address() as *const u8) };
- let flags = unsafe { *(sdt.data_address() as *const u8).offset(1) };
- let rsv: [u8; 10] = unsafe { *((sdt.data_address() as *const u8).offset(2) as *const [u8; 10]) };
-
- Some(Dmar {
- sdt: sdt,
- addr_width: addr_width,
- flags: flags,
- _rsv: rsv,
- })
- } else {
- None
- }
- }
-
- pub fn iter(&self) -> DmarIter {
- DmarIter {
- sdt: self.sdt,
- i: 12 // Skip address width and flags
- }
- }
-}
-
-///
-
-/// DMAR DMA Remapping Hardware Unit Definition
-// TODO: Implement iterator on DmarDrhd scope
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarDrhd {
- kind: u16,
- length: u16,
- flags: u8,
- _rsv: u8,
- segment: u16,
- base: u64,
-}
-
-impl DmarDrhd {
- pub fn get(&self, active_table: &mut ActivePageTable) -> &'static mut Drhd {
- let result = active_table.identity_map(Frame::containing_address(PhysicalAddress::new(self.base as usize)), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
- result.flush(active_table);
- unsafe { &mut *(self.base as *mut Drhd) }
- }
-}
-
-/// DMAR Reserved Memory Region Reporting
-// TODO: Implement iterator on DmarRmrr scope
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarRmrr {
- kind: u16,
- length: u16,
- _rsv: u16,
- segment: u16,
- base: u64,
- limit: u64,
-}
-
-/// DMAR Root Port ATS Capability Reporting
-// TODO: Implement iterator on DmarAtsr scope
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarAtsr {
- kind: u16,
- length: u16,
- flags: u8,
- _rsv: u8,
- segment: u16,
-}
-
-/// DMAR Remapping Hardware Static Affinity
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarRhsa {
- kind: u16,
- length: u16,
- _rsv: u32,
- base: u64,
- domain: u32,
-}
-
-/// DMAR ACPI Name-space Device Declaration
-// TODO: Implement iterator on DmarAndd object name
-#[derive(Debug)]
-#[repr(packed)]
-pub struct DmarAndd {
- kind: u16,
- length: u16,
- _rsv: [u8; 3],
- acpi_dev: u8,
-}
-
-/// DMAR Entries
-#[derive(Debug)]
-pub enum DmarEntry {
- Drhd(&'static DmarDrhd),
- InvalidDrhd(usize),
- Rmrr(&'static DmarRmrr),
- InvalidRmrr(usize),
- Atsr(&'static DmarAtsr),
- InvalidAtsr(usize),
- Rhsa(&'static DmarRhsa),
- InvalidRhsa(usize),
- Andd(&'static DmarAndd),
- InvalidAndd(usize),
- Unknown(u16)
-}
-
-pub struct DmarIter {
- sdt: &'static Sdt,
- i: usize
-}
-
-impl Iterator for DmarIter {
- type Item = DmarEntry;
- fn next(&mut self) -> Option {
- if self.i + 4 <= self.sdt.data_len() {
- let entry_type = unsafe { *((self.sdt.data_address() as *const u8).offset(self.i as isize) as *const u16) };
- let entry_len = unsafe { *((self.sdt.data_address() as *const u8).offset(self.i as isize + 2) as *const u16) } as usize;
-
- if self.i + entry_len <= self.sdt.data_len() {
- let item = match entry_type {
- 0 => if entry_len >= mem::size_of::() {
- DmarEntry::Drhd(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarDrhd) })
- } else {
- DmarEntry::InvalidDrhd(entry_len)
- },
- 1 => if entry_len >= mem::size_of::() {
- DmarEntry::Rmrr(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarRmrr) })
- } else {
- DmarEntry::InvalidRmrr(entry_len)
- },
- 2 => if entry_len >= mem::size_of::() {
- DmarEntry::Atsr(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarAtsr) })
- } else {
- DmarEntry::InvalidAtsr(entry_len)
- },
- 3 => if entry_len == mem::size_of::() {
- DmarEntry::Rhsa(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarRhsa) })
- } else {
- DmarEntry::InvalidRhsa(entry_len)
- },
- 4 => if entry_len >= mem::size_of::() {
- DmarEntry::Andd(unsafe { &*((self.sdt.data_address() + self.i) as *const DmarAndd) })
- } else {
- DmarEntry::InvalidAndd(entry_len)
- },
- _ => DmarEntry::Unknown(entry_type)
- };
-
- self.i += entry_len;
-
- Some(item)
- } else {
- None
- }
- } else {
- None
- }
- }
-}
diff --git a/src/acpi/fadt.rs b/src/acpi/fadt.rs
deleted file mode 100644
index c7be82ab..00000000
--- a/src/acpi/fadt.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-use core::{mem, ptr};
-
-use super::sdt::Sdt;
-use super::{ACPI_TABLE, SDT_POINTERS, get_sdt, find_sdt, get_sdt_signature, load_table};
-
-use paging::ActivePageTable;
-
-#[repr(packed)]
-#[derive(Debug)]
-pub struct Fadt {
- pub header: Sdt,
- pub firmware_ctrl: u32,
- pub dsdt: u32,
-
- // field used in ACPI 1.0; no longer in use, for compatibility only
- reserved: u8,
-
- pub preferred_power_managament: u8,
- pub sci_interrupt: u16,
- pub smi_command_port: u32,
- pub acpi_enable: u8,
- pub acpi_disable: u8,
- pub s4_bios_req: u8,
- pub pstate_control: u8,
- pub pm1a_event_block: u32,
- pub pm1b_event_block: u32,
- pub pm1a_control_block: u32,
- pub pm1b_control_block: u32,
- pub pm2_control_block: u32,
- pub pm_timer_block: u32,
- pub gpe0_block: u32,
- pub gpe1_block: u32,
- pub pm1_event_length: u8,
- pub pm1_control_length: u8,
- pub pm2_control_length: u8,
- pub pm_timer_length: u8,
- pub gpe0_ength: u8,
- pub gpe1_length: u8,
- pub gpe1_base: u8,
- pub c_state_control: u8,
- pub worst_c2_latency: u16,
- pub worst_c3_latency: u16,
- pub flush_size: u16,
- pub flush_stride: u16,
- pub duty_offset: u8,
- pub duty_width: u8,
- pub day_alarm: u8,
- pub month_alarm: u8,
- pub century: u8,
-
- // reserved in ACPI 1.0; used since ACPI 2.0+
- pub boot_architecture_flags: u16,
-
- reserved2: u8,
- pub flags: u32,
-}
-
-/* ACPI 2 structure
-#[repr(packed)]
-#[derive(Clone, Copy, Debug, Default)]
-pub struct GenericAddressStructure {
- address_space: u8,
- bit_width: u8,
- bit_offset: u8,
- access_size: u8,
- address: u64,
-}
-
-{
- // 12 byte structure; see below for details
- pub reset_reg: GenericAddressStructure,
-
- pub reset_value: u8,
- reserved3: [u8; 3],
-
- // 64bit pointers - Available on ACPI 2.0+
- pub x_firmware_control: u64,
- pub x_dsdt: u64,
-
- pub x_pm1a_event_block: GenericAddressStructure,
- pub x_pm1b_event_block: GenericAddressStructure,
- pub x_pm1a_control_block: GenericAddressStructure,
- pub x_pm1b_control_block: GenericAddressStructure,
- pub x_pm2_control_block: GenericAddressStructure,
- pub x_pm_timer_block: GenericAddressStructure,
- pub x_gpe0_block: GenericAddressStructure,
- pub x_gpe1_block: GenericAddressStructure,
-}
-*/
-
-impl Fadt {
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"FACP" && sdt.length as usize >= mem::size_of::() {
- Some(unsafe { ptr::read((sdt as *const Sdt) as *const Fadt) })
- } else {
- None
- }
- }
-
- pub fn init(active_table: &mut ActivePageTable) {
- let fadt_sdt = find_sdt("FACP");
- let fadt = if fadt_sdt.len() == 1 {
- load_table(get_sdt_signature(fadt_sdt[0]));
- Fadt::new(fadt_sdt[0])
- } else {
- println!("Unable to find FADT");
- return;
- };
-
- if let Some(fadt) = fadt {
- println!(" FACP: {:X}", fadt.dsdt);
-
- let dsdt_sdt = get_sdt(fadt.dsdt as usize, active_table);
-
- let signature = get_sdt_signature(dsdt_sdt);
- if let Some(ref mut ptrs) = *(SDT_POINTERS.write()) {
- ptrs.insert(signature, dsdt_sdt);
- }
-
- let mut fadt_t = ACPI_TABLE.fadt.write();
- *fadt_t = Some(fadt);
- }
- }
-}
diff --git a/src/acpi/gtdt.rs b/src/acpi/gtdt.rs
new file mode 100644
index 00000000..218c942c
--- /dev/null
+++ b/src/acpi/gtdt.rs
@@ -0,0 +1,68 @@
+use alloc::boxed::Box;
+use core::mem;
+
+use super::{find_sdt, sdt::Sdt};
+use crate::{
+ device::generic_timer::GenericTimer,
+ dtb::irqchip::{register_irq, IRQ_CHIP},
+};
+
+#[derive(Clone, Copy, Debug)]
+#[repr(C, packed)]
+pub struct Gtdt {
+ pub header: Sdt,
+ pub cnt_control_base: u64,
+ _reserved: u32,
+ pub secure_el1_timer_gsiv: u32,
+ pub secure_el1_timer_flags: u32,
+ pub non_secure_el1_timer_gsiv: u32,
+ pub non_secure_el1_timer_flags: u32,
+ pub virtual_el1_timer_gsiv: u32,
+ pub virtual_el1_timer_flags: u32,
+ pub el2_timer_gsiv: u32,
+ pub el2_timer_flags: u32,
+ pub cnt_read_base: u64,
+ pub platform_timer_count: u32,
+ pub platform_timer_offset: u32,
+ /*TODO: we don't need these yet, and they cause short tables to fail parsing
+ pub virtual_el2_timer_gsiv: u32,
+ pub virtual_el2_timer_flags: u32,
+ */
+ //TODO: platform timer structure (at platform timer offset, with platform timer count)
+}
+
+impl Gtdt {
+ pub fn init() {
+ let gtdt_sdt = find_sdt("GTDT");
+ let gtdt = if gtdt_sdt.len() == 1 {
+ match Gtdt::new(gtdt_sdt[0]) {
+ Some(gtdt) => gtdt,
+ None => {
+ log::warn!("Failed to parse GTDT");
+ return;
+ }
+ }
+ } else {
+ log::warn!("Unable to find GTDT");
+ return;
+ };
+
+ let gsiv = gtdt.non_secure_el1_timer_gsiv;
+ log::info!("generic_timer gsiv = {}", gsiv);
+ let mut timer = GenericTimer {
+ clk_freq: 0,
+ reload_count: 0,
+ };
+ timer.init();
+ register_irq(gsiv, Box::new(timer));
+ unsafe { IRQ_CHIP.irq_enable(gsiv as u32) };
+ }
+
+ pub fn new(sdt: &'static Sdt) -> Option<&'static Gtdt> {
+ if &sdt.signature == b"GTDT" && sdt.length as usize >= mem::size_of::() {
+ Some(unsafe { &*((sdt as *const Sdt) as *const Gtdt) })
+ } else {
+ None
+ }
+ }
+}
diff --git a/src/acpi/hpet.rs b/src/acpi/hpet.rs
index 73d15be3..c3c05c45 100644
--- a/src/acpi/hpet.rs
+++ b/src/acpi/hpet.rs
@@ -1,26 +1,13 @@
use core::{mem, ptr};
-use core::intrinsics::{volatile_load, volatile_store};
-
-use memory::Frame;
-use paging::{ActivePageTable, PhysicalAddress, Page, VirtualAddress};
-use paging::entry::EntryFlags;
-
-use super::sdt::Sdt;
-use super::{ACPI_TABLE, find_sdt, load_table, get_sdt_signature};
-
-#[repr(packed)]
-#[derive(Clone, Copy, Debug, Default)]
-pub struct GenericAddressStructure {
- address_space: u8,
- bit_width: u8,
- bit_offset: u8,
- access_size: u8,
- pub address: u64,
-}
+use core::ptr::{read_volatile, write_volatile};
+
+use crate::memory::{map_device_memory, PhysicalAddress, PAGE_SIZE};
-#[repr(packed)]
-#[derive(Debug)]
+use super::{find_sdt, sdt::Sdt, GenericAddressStructure, ACPI_TABLE};
+
+#[repr(C, packed)]
+#[derive(Clone, Copy, Debug)]
pub struct Hpet {
pub header: Sdt,
@@ -32,15 +19,14 @@ pub struct Hpet {
pub hpet_number: u8,
pub min_periodic_clk_tick: u16,
- pub oem_attribute: u8
+ pub oem_attribute: u8,
}
impl Hpet {
- pub fn init(active_table: &mut ActivePageTable) {
+ pub fn init() {
let hpet_sdt = find_sdt("HPET");
let hpet = if hpet_sdt.len() == 1 {
- load_table(get_sdt_signature(hpet_sdt[0]));
- Hpet::new(hpet_sdt[0], active_table)
+ Hpet::new(hpet_sdt[0])
} else {
println!("Unable to find HPET");
return;
@@ -54,30 +40,82 @@ impl Hpet {
}
}
- pub fn new(sdt: &'static Sdt, active_table: &mut ActivePageTable) -> Option {
+ pub fn new(sdt: &'static Sdt) -> Option {
if &sdt.signature == b"HPET" && sdt.length as usize >= mem::size_of::() {
let s = unsafe { ptr::read((sdt as *const Sdt) as *const Hpet) };
- unsafe { s.base_address.init(active_table) };
- Some(s)
+ if s.base_address.address_space == 0 {
+ unsafe { s.map() };
+ Some(s)
+ } else {
+ log::warn!(
+ "HPET has unsupported address space {}",
+ s.base_address.address_space
+ );
+ None
+ }
} else {
None
}
}
}
-impl GenericAddressStructure {
- pub unsafe fn init(&self, active_table: &mut ActivePageTable) {
- let page = Page::containing_address(VirtualAddress::new(self.address as usize));
- let frame = Frame::containing_address(PhysicalAddress::new(self.address as usize));
- let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
- result.flush(active_table);
+//TODO: x86 use assumes only one HPET and only one GenericAddressStructure
+#[cfg(target_arch = "x86")]
+impl Hpet {
+ pub unsafe fn map(&self) {
+ use crate::{
+ memory::{Frame, KernelMapper},
+ paging::{entry::EntryFlags, Page, VirtualAddress},
+ };
+ use rmm::PageFlags;
+
+ let frame = Frame::containing(PhysicalAddress::new(self.base_address.address as usize));
+ let page = Page::containing_address(VirtualAddress::new(crate::HPET_OFFSET));
+
+ KernelMapper::lock()
+ .get_mut()
+ .expect(
+ "KernelMapper locked re-entrant while mapping memory for GenericAddressStructure",
+ )
+ .map_phys(
+ page.start_address(),
+ frame.base(),
+ PageFlags::new()
+ .write(true)
+ .custom_flag(EntryFlags::NO_CACHE.bits(), true),
+ )
+ .expect("failed to map memory for GenericAddressStructure")
+ .flush();
+ }
+
+ pub unsafe fn read_u64(&self, offset: usize) -> u64 {
+ read_volatile((crate::HPET_OFFSET + offset) as *const u64)
+ }
+
+ pub unsafe fn write_u64(&mut self, offset: usize, value: u64) {
+ write_volatile((crate::HPET_OFFSET + offset) as *mut u64, value);
+ }
+}
+
+#[cfg(not(target_arch = "x86"))]
+impl Hpet {
+ pub unsafe fn map(&self) {
+ map_device_memory(
+ PhysicalAddress::new(self.base_address.address as usize),
+ PAGE_SIZE,
+ );
}
- pub unsafe fn read_u64(&self, offset: usize) -> u64{
- volatile_load((self.address as usize + offset) as *const u64)
+ pub unsafe fn read_u64(&self, offset: usize) -> u64 {
+ read_volatile(
+ (self.base_address.address as usize + offset + crate::PHYS_OFFSET) as *const u64,
+ )
}
pub unsafe fn write_u64(&mut self, offset: usize, value: u64) {
- volatile_store((self.address as usize + offset) as *mut u64, value);
+ write_volatile(
+ (self.base_address.address as usize + offset + crate::PHYS_OFFSET) as *mut u64,
+ value,
+ );
}
}
diff --git a/src/acpi/madt.rs b/src/acpi/madt.rs
deleted file mode 100644
index e95c5193..00000000
--- a/src/acpi/madt.rs
+++ /dev/null
@@ -1,262 +0,0 @@
-use core::mem;
-
-use memory::{allocate_frames, Frame};
-use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
-use paging::entry::EntryFlags;
-
-use super::sdt::Sdt;
-use super::{AP_STARTUP, TRAMPOLINE, find_sdt, load_table, get_sdt_signature};
-
-use core::intrinsics::{atomic_load, atomic_store};
-use core::sync::atomic::Ordering;
-
-use device::local_apic::LOCAL_APIC;
-use interrupt;
-use start::{kstart_ap, CPU_COUNT, AP_READY};
-
-/// The Multiple APIC Descriptor Table
-#[derive(Debug)]
-pub struct Madt {
- sdt: &'static Sdt,
- pub local_address: u32,
- pub flags: u32
-}
-
-impl Madt {
- pub fn init(active_table: &mut ActivePageTable) {
- let madt_sdt = find_sdt("APIC");
- let madt = if madt_sdt.len() == 1 {
- load_table(get_sdt_signature(madt_sdt[0]));
- Madt::new(madt_sdt[0])
- } else {
- println!("Unable to find MADT");
- return;
- };
-
- if let Some(madt) = madt {
- println!(" APIC: {:>08X}: {}", madt.local_address, madt.flags);
-
- let local_apic = unsafe { &mut LOCAL_APIC };
- let me = local_apic.id() as u8;
-
- if local_apic.x2 {
- println!(" X2APIC {}", me);
- } else {
- println!(" XAPIC {}: {:>08X}", me, local_apic.address);
- }
-
- if cfg!(feature = "multi_core") {
- let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE));
- let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
-
- // Map trampoline
- let result = active_table.map_to(trampoline_page, trampoline_frame, EntryFlags::PRESENT | EntryFlags::WRITABLE);
- result.flush(active_table);
-
- for madt_entry in madt.iter() {
- println!(" {:?}", madt_entry);
- match madt_entry {
- MadtEntry::LocalApic(ap_local_apic) => if ap_local_apic.id == me {
- println!(" This is my local APIC");
- } else {
- if ap_local_apic.flags & 1 == 1 {
- // Increase CPU ID
- CPU_COUNT.fetch_add(1, Ordering::SeqCst);
-
- // Allocate a stack
- let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET;
- let stack_end = stack_start + 64 * 4096;
-
- let ap_ready = TRAMPOLINE as *mut u64;
- let ap_cpu_id = unsafe { ap_ready.offset(1) };
- let ap_page_table = unsafe { ap_ready.offset(2) };
- let ap_stack_start = unsafe { ap_ready.offset(3) };
- let ap_stack_end = unsafe { ap_ready.offset(4) };
- let ap_code = unsafe { ap_ready.offset(5) };
-
- // Set the ap_ready to 0, volatile
- unsafe { atomic_store(ap_ready, 0) };
- unsafe { atomic_store(ap_cpu_id, ap_local_apic.id as u64) };
- unsafe { atomic_store(ap_page_table, active_table.address() as u64) };
- unsafe { atomic_store(ap_stack_start, stack_start as u64) };
- unsafe { atomic_store(ap_stack_end, stack_end as u64) };
- unsafe { atomic_store(ap_code, kstart_ap as u64) };
- AP_READY.store(false, Ordering::SeqCst);
-
- print!(" AP {}:", ap_local_apic.id);
-
- // Send INIT IPI
- {
- let mut icr = 0x4500;
- if local_apic.x2 {
- icr |= (ap_local_apic.id as u64) << 32;
- } else {
- icr |= (ap_local_apic.id as u64) << 56;
- }
- print!(" IPI...");
- local_apic.set_icr(icr);
- }
-
- // Send START IPI
- {
- //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
- let ap_segment = (AP_STARTUP >> 12) & 0xFF;
- let mut icr = 0x4600 | ap_segment as u64;
-
- if local_apic.x2 {
- icr |= (ap_local_apic.id as u64) << 32;
- } else {
- icr |= (ap_local_apic.id as u64) << 56;
- }
-
- print!(" SIPI...");
- local_apic.set_icr(icr);
- }
-
- // Wait for trampoline ready
- print!(" Wait...");
- while unsafe { atomic_load(ap_ready) } == 0 {
- interrupt::pause();
- }
- print!(" Trampoline...");
- while ! AP_READY.load(Ordering::SeqCst) {
- interrupt::pause();
- }
- println!(" Ready");
-
- active_table.flush_all();
- } else {
- println!(" CPU Disabled");
- }
- },
- _ => ()
- }
- }
-
- // Unmap trampoline
- let (result, _frame) = active_table.unmap_return(trampoline_page, false);
- result.flush(active_table);
- }
- }
- }
-
- pub fn new(sdt: &'static Sdt) -> Option {
- if &sdt.signature == b"APIC" && sdt.data_len() >= 8 { //Not valid if no local address and flags
- let local_address = unsafe { *(sdt.data_address() as *const u32) };
- let flags = unsafe { *(sdt.data_address() as *const u32).offset(1) };
-
- Some(Madt {
- sdt: sdt,
- local_address: local_address,
- flags: flags
- })
- } else {
- None
- }
- }
-
- pub fn iter(&self) -> MadtIter {
- MadtIter {
- sdt: self.sdt,
- i: 8 // Skip local controller address and flags
- }
- }
-}
-
-///
-
-/// MADT Local APIC
-#[derive(Debug)]
-#[repr(packed)]
-pub struct MadtLocalApic {
- /// Processor ID
- pub processor: u8,
- /// Local APIC ID
- pub id: u8,
- /// Flags. 1 means that the processor is enabled
- pub flags: u32
-}
-
-/// MADT I/O APIC
-#[derive(Debug)]
-#[repr(packed)]
-pub struct MadtIoApic {
- /// I/O APIC ID
- pub id: u8,
- /// reserved
- reserved: u8,
- /// I/O APIC address
- pub address: u32,
- /// Global system interrupt base
- pub gsi_base: u32
-}
-
-/// MADT Interrupt Source Override
-#[derive(Debug)]
-#[repr(packed)]
-pub struct MadtIntSrcOverride {
- /// Bus Source
- pub bus_source: u8,
- /// IRQ Source
- pub irq_source: u8,
- /// Global system interrupt base
- pub gsi_base: u32,
- /// Flags
- pub flags: u16
-}
-
-/// MADT Entries
-#[derive(Debug)]
-pub enum MadtEntry {
- LocalApic(&'static MadtLocalApic),
- InvalidLocalApic(usize),
- IoApic(&'static MadtIoApic),
- InvalidIoApic(usize),
- IntSrcOverride(&'static MadtIntSrcOverride),
- InvalidIntSrcOverride(usize),
- Unknown(u8)
-}
-
-pub struct MadtIter {
- sdt: &'static Sdt,
- i: usize
-}
-
-impl Iterator for MadtIter {
- type Item = MadtEntry;
- fn next(&mut self) -> Option {
- if self.i + 1 < self.sdt.data_len() {
- let entry_type = unsafe { *(self.sdt.data_address() as *const u8).offset(self.i as isize) };
- let entry_len = unsafe { *(self.sdt.data_address() as *const u8).offset(self.i as isize + 1) } as usize;
-
- if self.i + entry_len <= self.sdt.data_len() {
- let item = match entry_type {
- 0 => if entry_len == mem::size_of::() + 2 {
- MadtEntry::LocalApic(unsafe { &*((self.sdt.data_address() + self.i + 2) as *const MadtLocalApic) })
- } else {
- MadtEntry::InvalidLocalApic(entry_len)
- },
- 1 => if entry_len == mem::size_of::() + 2 {
- MadtEntry::IoApic(unsafe { &*((self.sdt.data_address() + self.i + 2) as *const MadtIoApic) })
- } else {
- MadtEntry::InvalidIoApic(entry_len)
- },
- 2 => if entry_len == mem::size_of::() + 2 {
- MadtEntry::IntSrcOverride(unsafe { &*((self.sdt.data_address() + self.i + 2) as *const MadtIntSrcOverride) })
- } else {
- MadtEntry::InvalidIntSrcOverride(entry_len)
- },
- _ => MadtEntry::Unknown(entry_type)
- };
-
- self.i += entry_len;
-
- Some(item)
- } else {
- None
- }
- } else {
- None
- }
- }
-}
diff --git a/src/acpi/madt/arch/aarch64.rs b/src/acpi/madt/arch/aarch64.rs
new file mode 100644
index 00000000..dc460b08
--- /dev/null
+++ b/src/acpi/madt/arch/aarch64.rs
@@ -0,0 +1,97 @@
+use alloc::{boxed::Box, vec::Vec};
+
+use super::{Madt, MadtEntry};
+use crate::{
+ device::irqchip::{
+ gic::{GenericInterruptController, GicCpuIf, GicDistIf},
+ gicv3::{GicV3, GicV3CpuIf},
+ },
+ dtb::irqchip::{IrqChipItem, IRQ_CHIP},
+ memory::{map_device_memory, PhysicalAddress, PAGE_SIZE},
+};
+
+pub(super) fn init(madt: Madt) {
+ let mut gicd_opt = None;
+ let mut giccs = Vec::new();
+ for madt_entry in madt.iter() {
+ println!(" {:#x?}", madt_entry);
+ match madt_entry {
+ MadtEntry::Gicc(gicc) => {
+ giccs.push(gicc);
+ }
+ MadtEntry::Gicd(gicd) => {
+ if gicd_opt.is_some() {
+ log::warn!("Only one GICD should be present on a system, ignoring this one");
+ } else {
+ gicd_opt = Some(gicd);
+ }
+ }
+ _ => {}
+ }
+ }
+ let Some(gicd) = gicd_opt else {
+ log::warn!("No GICD found");
+ return;
+ };
+ let mut gic_dist_if = GicDistIf::default();
+ unsafe {
+ let phys = PhysicalAddress::new(gicd.physical_base_address as usize);
+ let virt = map_device_memory(phys, PAGE_SIZE);
+ gic_dist_if.init(virt.data());
+ };
+ log::info!("{:#x?}", gic_dist_if);
+ match gicd.gic_version {
+ 1 | 2 => {
+ for gicc in giccs {
+ let mut gic_cpu_if = GicCpuIf::default();
+ unsafe {
+ let phys = PhysicalAddress::new(gicc.physical_base_address as usize);
+ let virt = map_device_memory(phys, PAGE_SIZE);
+ gic_cpu_if.init(virt.data())
+ };
+ log::info!("{:#x?}", gic_cpu_if);
+ let gic = GenericInterruptController {
+ gic_dist_if,
+ gic_cpu_if,
+ irq_range: (0, 0),
+ };
+ let chip = IrqChipItem {
+ phandle: 0,
+ parents: Vec::new(),
+ children: Vec::new(),
+ ic: Box::new(gic),
+ };
+ unsafe { IRQ_CHIP.irq_chip_list.chips.push(chip) };
+ //TODO: support more GICCs
+ break;
+ }
+ }
+ 3 => {
+ for gicc in giccs {
+ let mut gic_cpu_if = GicV3CpuIf;
+ unsafe { gic_cpu_if.init() };
+ log::info!("{:#x?}", gic_cpu_if);
+ let gic = GicV3 {
+ gic_dist_if,
+ gic_cpu_if,
+ //TODO: get GICRs
+ gicrs: Vec::new(),
+ irq_range: (0, 0),
+ };
+ let chip = IrqChipItem {
+ phandle: 0,
+ parents: Vec::new(),
+ children: Vec::new(),
+ ic: Box::new(gic),
+ };
+ unsafe { IRQ_CHIP.irq_chip_list.chips.push(chip) };
+ //TODO: support more GICCs
+ break;
+ }
+ }
+ _ => {
+ log::warn!("unsupported GIC version {}", gicd.gic_version);
+ }
+ }
+ unsafe { IRQ_CHIP.init(None) };
+}
diff --git a/src/acpi/madt/arch/other.rs b/src/acpi/madt/arch/other.rs
new file mode 100644
index 00000000..cf9440be
--- /dev/null
+++ b/src/acpi/madt/arch/other.rs
@@ -0,0 +1,9 @@
+use super::Madt;
+
+pub(super) fn init(madt: Madt) {
+ for madt_entry in madt.iter() {
+ println!(" {:#x?}", madt_entry);
+ }
+
+ log::warn!("MADT not yet handled on this platform");
+}
diff --git a/src/acpi/madt/arch/x86.rs b/src/acpi/madt/arch/x86.rs
new file mode 100644
index 00000000..a8121c68
--- /dev/null
+++ b/src/acpi/madt/arch/x86.rs
@@ -0,0 +1,160 @@
+use core::sync::atomic::{AtomicU8, Ordering};
+
+use crate::{
+ device::local_apic::the_local_apic,
+ interrupt,
+ memory::{allocate_p2frame, Frame, KernelMapper},
+ paging::{Page, PageFlags, PhysicalAddress, RmmA, RmmArch, VirtualAddress, PAGE_SIZE},
+ start::{kstart_ap, AP_READY, CPU_COUNT},
+};
+
+use super::{Madt, MadtEntry};
+
+const TRAMPOLINE: usize = 0x8000;
+static TRAMPOLINE_DATA: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/trampoline"));
+
+pub(super) fn init(madt: Madt) {
+ let local_apic = unsafe { the_local_apic() };
+ let me = local_apic.id() as u8;
+
+ if local_apic.x2 {
+ println!(" X2APIC {}", me);
+ } else {
+ println!(" XAPIC {}: {:>08X}", me, local_apic.address);
+ }
+
+ if cfg!(feature = "multi_core") {
+ // Map trampoline
+ let trampoline_frame = Frame::containing(PhysicalAddress::new(TRAMPOLINE));
+ let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
+ let (result, page_table_physaddr) = unsafe {
+ //TODO: do not have writable and executable!
+ let mut mapper = KernelMapper::lock();
+
+ let result = mapper
+ .get_mut()
+ .expect("expected kernel page table not to be recursively locked while initializing MADT")
+ .map_phys(trampoline_page.start_address(), trampoline_frame.base(), PageFlags::new().execute(true).write(true))
+ .expect("failed to map trampoline");
+
+ (result, mapper.table().phys().data())
+ };
+ result.flush();
+
+ // Write trampoline, make sure TRAMPOLINE page is free for use
+ for i in 0..TRAMPOLINE_DATA.len() {
+ unsafe {
+ (*((TRAMPOLINE as *mut u8).add(i) as *const AtomicU8))
+ .store(TRAMPOLINE_DATA[i], Ordering::SeqCst);
+ }
+ }
+
+ for madt_entry in madt.iter() {
+ println!(" {:x?}", madt_entry);
+ match madt_entry {
+ MadtEntry::LocalApic(ap_local_apic) => {
+ if ap_local_apic.id == me {
+ println!(" This is my local APIC");
+ } else {
+ if ap_local_apic.flags & 1 == 1 {
+ // Increase CPU ID
+ CPU_COUNT.fetch_add(1, Ordering::SeqCst);
+
+ // Allocate a stack
+ let stack_start = allocate_p2frame(4)
+ .expect("no more frames in acpi stack_start")
+ .base()
+ .data()
+ + crate::PHYS_OFFSET;
+ let stack_end = stack_start + (PAGE_SIZE << 4);
+
+ let ap_ready = (TRAMPOLINE + 8) as *mut u64;
+ let ap_cpu_id = unsafe { ap_ready.add(1) };
+ let ap_page_table = unsafe { ap_ready.add(2) };
+ let ap_stack_start = unsafe { ap_ready.add(3) };
+ let ap_stack_end = unsafe { ap_ready.add(4) };
+ let ap_code = unsafe { ap_ready.add(5) };
+
+ // Set the ap_ready to 0, volatile
+ unsafe {
+ ap_ready.write(0);
+ ap_cpu_id.write(ap_local_apic.processor.into());
+ ap_page_table.write(page_table_physaddr as u64);
+ ap_stack_start.write(stack_start as u64);
+ ap_stack_end.write(stack_end as u64);
+ ap_code.write(kstart_ap as u64);
+
+ // TODO: Is this necessary (this fence)?
+ core::arch::asm!("");
+ };
+ AP_READY.store(false, Ordering::SeqCst);
+
+ print!(
+ " AP {} APIC {}:",
+ ap_local_apic.processor, ap_local_apic.id
+ );
+
+ // Send INIT IPI
+ {
+ let mut icr = 0x4500;
+ if local_apic.x2 {
+ icr |= (ap_local_apic.id as u64) << 32;
+ } else {
+ icr |= (ap_local_apic.id as u64) << 56;
+ }
+ print!(" IPI...");
+ local_apic.set_icr(icr);
+ }
+
+ // Send START IPI
+ {
+ //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
+ let ap_segment = (TRAMPOLINE >> 12) & 0xFF;
+ let mut icr = 0x4600 | ap_segment as u64;
+
+ if local_apic.x2 {
+ icr |= (ap_local_apic.id as u64) << 32;
+ } else {
+ icr |= (ap_local_apic.id as u64) << 56;
+ }
+
+ print!(" SIPI...");
+ local_apic.set_icr(icr);
+ }
+
+ // Wait for trampoline ready
+ print!(" Wait...");
+ while unsafe { (*ap_ready.cast::()).load(Ordering::SeqCst) }
+ == 0
+ {
+ interrupt::pause();
+ }
+ print!(" Trampoline...");
+ while !AP_READY.load(Ordering::SeqCst) {
+ interrupt::pause();
+ }
+ println!(" Ready");
+
+ unsafe {
+ RmmA::invalidate_all();
+ }
+ } else {
+ println!(" CPU Disabled");
+ }
+ }
+ }
+ _ => (),
+ }
+ }
+
+ // Unmap trampoline
+ let (_frame, _, flush) = unsafe {
+ KernelMapper::lock()
+ .get_mut()
+ .expect("expected kernel page table not to be recursively locked while initializing MADT")
+ .unmap_phys(trampoline_page.start_address(), true)
+ .expect("failed to unmap trampoline page")
+ };
+ flush.flush();
+ }
+}
diff --git a/src/acpi/madt/mod.rs b/src/acpi/madt/mod.rs
new file mode 100644
index 00000000..53e57f79
--- /dev/null
+++ b/src/acpi/madt/mod.rs
@@ -0,0 +1,244 @@
+use core::{cell::SyncUnsafeCell, mem};
+
+use super::{find_sdt, sdt::Sdt};
+
+/// The Multiple APIC Descriptor Table
+#[derive(Clone, Copy, Debug)]
+pub struct Madt {
+ sdt: &'static Sdt,
+ pub local_address: u32,
+ pub flags: u32,
+}
+
+#[cfg(target_arch = "aarch64")]
+#[path = "arch/aarch64.rs"]
+mod arch;
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+#[path = "arch/x86.rs"]
+mod arch;
+
+#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
+#[path = "arch/other.rs"]
+mod arch;
+
+static MADT: SyncUnsafeCell