diff --git a/.cargo/config.toml b/.cargo/config.toml
index cc0571f..5d2f920 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -3,4 +3,3 @@ runner = "ostool cargo-test"
 
 [build]
 target = "aarch64-unknown-none"
-
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3dbb838..1ffc805 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -16,15 +16,21 @@ jobs:
       run: sudo apt update && sudo apt install qemu-system -y 
     - name: Install libudev-dev
       run: sudo apt update && sudo apt install libudev-dev -y
-    - name: Install cargo-binutils
-      run: cargo install cargo-binutils
-    - name: Install ostool
-      run: cargo install ostool
-
     - name: Install toolchain
       run: rustup show
     - name: Check rust version
       run: rustc --version --verbose
+
+    - uses: Swatinem/rust-cache@v2
+      with:
+          workspaces: "."
+
+    - name: Install cargo-binutils
+      run: cargo install cargo-binutils
+    - name: Install ostool
+      run: cargo install ostool
+    - name: Add Target
+      run: rustup target add aarch64-unknown-none
     - name: Check code format
       run: cargo fmt --all -- --check
 
@@ -62,7 +68,7 @@ jobs:
     - name: Test sparreal-macros
       if: ${{ always() }}
       working-directory: crates/sparreal-macros
-      run: cargo test
+      run: cargo test --target x86_64-unknown-linux-gnu
 
     - name: Test page-table-arm
       if: ${{ always() }}
diff --git a/.gitignore b/.gitignore
index 49cba62..33f7630 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,2 @@
 /target
-/*.log
 .project*
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index e69de29..0000000
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 35410ca..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# 默认忽略的文件
-/shelf/
-/workspace.xml
-# 基于编辑器的 HTTP 客户端请求
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
deleted file mode 100644
index 54f1838..0000000
--- a/.idea/deployment.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
-    <serverData>
-      <paths name="Remote Host (1cb00ee0-ef68-4e12-9ae6-73b43003e4c6)">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-      <paths name="t113">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-    </serverData>
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/editor.xml b/.idea/editor.xml
deleted file mode 100644
index 7b63cd0..0000000
--- a/.idea/editor.xml
+++ /dev/null
@@ -1,588 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="BackendCodeEditorSettings">
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Windows_0020Form_0020Designer_0020generated_0020code/@EntryIndexedValue" value="Windows Form Designer generated code" type="string" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Windows_0020Form_0020Designer_0020generated_0020code/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Component_0020Designer_0020generated_0020code/@EntryIndexedValue" value="Component Designer generated code" type="string" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Component_0020Designer_0020generated_0020code/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Designer_0020generated_0020code/@EntryIndexedValue" value="Designer generated code" type="string" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Designer_0020generated_0020code/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Web_0020Form_0020Designer_0020generated_0020code/@EntryIndexedValue" value="Web Form Designer generated code" type="string" />
-    <option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Web_0020Form_0020Designer_0020generated_0020code/@EntryIndexRemoved" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
-    <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexedValue" value="WARNING" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexedValue" value="HINT" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexRemoved" />
-    <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexRemoved" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 42846c7..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/sparreal-os.iml" filepath="$PROJECT_DIR$/.idea/sparreal-os.iml" />
-    </modules>
-  </component>
-</project>
\ No newline at end of file
diff --git a/.idea/sparreal-os.iml b/.idea/sparreal-os.iml
deleted file mode 100644
index f875314..0000000
--- a/.idea/sparreal-os.iml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="CPP_MODULE" version="4">
-  <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/app/helloworld/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/arm-gic/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/arm-pl011/examples" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/arm-pl011/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/driver-interface/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/flat_device_tree/examples" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/flat_device_tree/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/page-table-interface/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/page-table/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/sparreal-build/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/sparreal-kernel/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/sparreal-macros/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/sparreal-rt/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/xtask/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/app/simple_test/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/app/simple_test/tests" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/bare-test-macros/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/bare-test/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/page-table-arm/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/crates/page-table-arm/tests" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="" vcs="Git" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 7428ce8..405bd9d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -4,31 +4,19 @@
     // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
     "version": "0.2.0",
     "configurations": [
-        {
-            "type": "lldb",
-            "request": "launch",
-            "name": "xtask",
-            "cargo": {
-                "args": [
-                    "build",
-                    "-p",
-                    "xtask"
-                ]
-            },
-            "args": ["elf", "kernel/hal/bsp/aarch64/raspi4.toml"]
-        },
         // lldb 不支持 riscv,需要用此配置调试
         {
             "type": "cppdbg",
-            "name": "KDebug Riscv",
+            "name": "KDebug cppdbg",
             "request": "launch",
             "miDebuggerServerAddress": "localhost:1234",
-            "program": "${workspaceFolder}/target/riscv64gc-unknown-none-elf/debug/kernel",
-            "miDebuggerPath": "gdb-multiarch.exe",
+            "program": "${workspaceFolder}/target/kernel.elf",
+            "miDebuggerPath": "gdb-multiarch",
             "cwd": "${workspaceRoot}",
+            "preLaunchTask": "qemu debug"
         },
         {
-            "name": "KDebug",
+            "name": "KDebug lldb",
             "type": "lldb",
             "request": "custom",
             "initCommands": [
@@ -39,7 +27,8 @@
             ],
             "processCreateCommands": [
                 "gdb-remote localhost:1234" // Connect to the GDB Server
-            ]
+            ],
+            "preLaunchTask": "qemu debug"
         }
     ]
 }
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 4c70df0..08ef4fe 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,6 +1,6 @@
 {
     "rust-analyzer.cargo.allTargets": false,
-    "rust-analyzer.checkOnSave": false,
+    "rust-analyzer.checkOnSave": true,
     "rust-analyzer.check.command": "clippy",
     "lldb.displayFormat": "auto",
     "lldb.dereferencePointers": true,
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 081b1fa..ce60521 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,12 +1,33 @@
 {
-    // See https://go.microsoft.com/fwlink/?LinkId=733558
-    // for the documentation about the tasks.json format
     "version": "2.0.0",
     "tasks": [
         {
-            "label": "qemu debug",
             "type": "shell",
-            "command": "cargo xtask -d"
+            "label": "qemu debug",
+            "command": "ostool",
+            "args": [
+                "run",
+                "qemu",
+                "-d"
+            ],
+            
+            "options": {
+                "cwd": "${workspaceFolder}",
+            },
+            "problemMatcher": {
+                "base": "$rustc",
+                "background": {
+                    "activeOnStart": true,
+                    "beginsPattern": "^.*",
+                    "endsPattern": "^qemu-system.*"
+                }
+            },
+            "group": {
+                "kind": "test",
+                "isDefault": true
+            },
+            "detail": "断点调试 test 测试用例",
+            "isBackground": true,
         }
     ]
 }
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index bad733c..bbc13be 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,6 +11,26 @@ dependencies = [
  "tock-registers",
 ]
 
+[[package]]
+name = "abi-singleton"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbdf894742ece5360a74aa8278c42e0f305aa9f7c35d43ebc9cceca105f7e434"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "ansi_rgb"
 version = "0.2.0"
@@ -20,6 +40,62 @@ dependencies = [
  "rgb",
 ]
 
+[[package]]
+name = "anstream"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+dependencies = [
+ "anstyle",
+ "once_cell",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+
 [[package]]
 name = "arm-gic-driver"
 version = "0.3.1"
@@ -46,6 +122,21 @@ dependencies = [
  "tock-registers",
 ]
 
+[[package]]
+name = "arm_pl031"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13696b1c2b59992f4223e0ae5bb173c81c63039367ca90eee845346ad2a13421"
+dependencies = [
+ "chrono",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+
 [[package]]
 name = "autocfg"
 version = "1.4.0"
@@ -54,17 +145,18 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "bare-test"
-version = "0.2.0"
+version = "0.3.1"
 dependencies = [
  "bare-test-macros",
  "log",
+ "sparreal-kernel",
  "sparreal-macros",
  "sparreal-rt",
 ]
 
 [[package]]
 name = "bare-test-macros"
-version = "0.0.1"
+version = "0.2.0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -73,9 +165,9 @@ dependencies = [
 
 [[package]]
 name = "bitflags"
-version = "2.6.0"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
 
 [[package]]
 name = "buddy_system_allocator"
@@ -86,11 +178,36 @@ dependencies = [
  "spin",
 ]
 
+[[package]]
+name = "byte-unit"
+version = "5.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174"
+dependencies = [
+ "rust_decimal",
+ "utf8-width",
+]
+
 [[package]]
 name = "bytemuck"
-version = "1.20.0"
+version = "1.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
+
+[[package]]
+name = "chrono"
+version = "0.4.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "colorchoice"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
 
 [[package]]
 name = "dma-api"
@@ -100,10 +217,11 @@ checksum = "13029088ff130c8eb6a35ff20410ebed5f6750507681bf3d90f74ba97032a407"
 
 [[package]]
 name = "driver-interface"
-version = "0.0.1"
+version = "0.2.0"
 dependencies = [
  "embedded-io",
  "futures",
+ "log",
 ]
 
 [[package]]
@@ -133,11 +251,34 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "env_filter"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
+dependencies = [
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.11.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "env_filter",
+ "humantime",
+ "log",
+]
+
 [[package]]
 name = "fdt-parser"
-version = "0.4.2"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5234fbedee2700b63a66aca1c368f2ae09a9632b55015e6a4e91af20fab12bf5"
+checksum = "0deb230715aa771c49f2eda04e5532a34acccbf31335885d9bd4e3cebee8dac0"
 
 [[package]]
 name = "futures"
@@ -205,9 +346,31 @@ name = "helloworld"
 version = "0.1.0"
 dependencies = [
  "log",
+ "sparreal-kernel",
  "sparreal-rt",
 ]
 
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+dependencies = [
+ "spin",
+]
+
 [[package]]
 name = "lock_api"
 version = "0.4.12"
@@ -220,9 +383,15 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.22"
+version = "0.4.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
 name = "memory_addr"
@@ -230,6 +399,15 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6f769efcf10b9dfb4c913bebb409cda77b1a3f072b249bf5465e250bcb30eb49"
 
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "once_cell"
 version = "1.20.2"
@@ -242,23 +420,31 @@ version = "0.1.0"
 dependencies = [
  "aarch64-cpu",
  "bitflags",
+ "env_logger",
+ "log",
 ]
 
 [[package]]
 name = "page-table-generic"
-version = "0.2.3"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7021c5181b020f777dfd4b0ae239d2f4954323c88c810e657a8f9ab8c475b68"
+checksum = "734d342878ce1fd65c53078b17bc30adfb22e753c1bbe8f205d818837e9410f8"
 dependencies = [
  "bitflags",
  "log",
 ]
 
+[[package]]
+name = "pasts"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efcd36303871fb977a47dabc9af736c75c492bb32a92fa26262b2741531e97ce"
+
 [[package]]
 name = "pin-project-lite"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
 
 [[package]]
 name = "pin-utils"
@@ -268,22 +454,51 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.37"
+version = "1.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
 dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
 [[package]]
 name = "rgb"
 version = "0.8.50"
@@ -293,6 +508,16 @@ dependencies = [
  "bytemuck",
 ]
 
+[[package]]
+name = "rust_decimal"
+version = "1.36.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555"
+dependencies = [
+ "arrayvec",
+ "num-traits",
+]
+
 [[package]]
 name = "scopeguard"
 version = "1.2.0"
@@ -301,7 +526,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 [[package]]
 name = "simple_test"
-version = "0.1.0"
+version = "0.6.2"
 dependencies = [
  "bare-test",
  "bare-test-macros",
@@ -310,24 +535,32 @@ dependencies = [
 
 [[package]]
 name = "sparreal-kernel"
-version = "0.1.7"
+version = "0.6.2"
 dependencies = [
  "ansi_rgb",
+ "anyhow",
  "buddy_system_allocator",
+ "byte-unit",
+ "dma-api",
  "driver-interface",
  "fdt-parser",
+ "lazy_static",
  "lock_api",
  "log",
+ "memory_addr",
  "page-table-generic",
+ "pasts",
  "rgb",
  "sparreal-macros",
- "spin_on",
+ "spin",
+ "thiserror",
 ]
 
 [[package]]
 name = "sparreal-macros"
-version = "0.0.5"
+version = "0.6.2"
 dependencies = [
+ "abi-singleton",
  "proc-macro2",
  "quote",
  "syn",
@@ -335,19 +568,18 @@ dependencies = [
 
 [[package]]
 name = "sparreal-rt"
-version = "0.2.0"
+version = "0.6.2"
 dependencies = [
  "aarch64-cpu",
  "arm-gic-driver",
  "arm-pl011-rs",
+ "arm_pl031",
  "bitflags",
+ "buddy_system_allocator",
  "dma-api",
- "driver-interface",
- "embedded-io",
  "fdt-parser",
  "futures",
  "log",
- "memory_addr",
  "page-table-arm",
  "page-table-generic",
  "sparreal-kernel",
@@ -375,15 +607,35 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.90"
+version = "2.0.96"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
+checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-ident",
 ]
 
+[[package]]
+name = "thiserror"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "tock-registers"
 version = "0.9.0"
@@ -395,3 +647,88 @@ name = "unicode-ident"
 version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+
+[[package]]
+name = "utf8-width"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/Cargo.toml b/Cargo.toml
index 6387d14..1d16e6b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,38 +1,17 @@
 [workspace]
-resolver = "2"
-members = ["app/helloworld", "app/simple_test", "crates/*"]
+resolver = "3"
+members = ["app/*", "crates/*"]
+
+[workspace.package]
+version = "0.6.2"
+edition = "2024"
 
 [workspace.dependencies]
-embedded-hal = "1.0"
-nb = "1.1"
-embedded-hal-nb = "1.0"
-embedded-hal-async = "1.0"
-embedded-io = "0.6.1"
-log = { version = "0.4" }
-colored = "2.1"
-clap = { version = "4.5" }
-ansi_rgb = { version = "0.2" }
-rgb = "0.8.47"
-memory_addr = "0.3"
-toml = "0.8"
-serde = { default-features = false, version = "1", features = [
-    "alloc",
-    "derive",
-] }
-tock-registers = "0.9"
-goblin = "0.9"
-lock_api = "0.4"
-futures = { version = "0.3", default-features = false }
-sparreal-kernel = { path = "crates/sparreal-kernel" }
 sparreal-rt = { path = "crates/sparreal-rt" }
 sparreal-macros = { path = "crates/sparreal-macros" }
+sparreal-kernel = { path = "crates/sparreal-kernel" }
 page-table-arm = { path = "crates/page-table-arm" }
 driver-interface = { path = "crates/driver-interface" }
 bare-test = { path = "crates/bare-test" }
 bare-test-macros = { path = "crates/bare-test-macros" }
-arm-gic-driver = "0.3"
-arm-pl011-rs = "0.2"
-
-[workspace.package]
-version = "0.1.0"
-edition = "2021"
+log = "0.4"
diff --git a/app/helloworld/Cargo.toml b/app/helloworld/Cargo.toml
index 3ad36ba..6496f23 100644
--- a/app/helloworld/Cargo.toml
+++ b/app/helloworld/Cargo.toml
@@ -1,8 +1,9 @@
 [package]
 name = "helloworld"
 version = "0.1.0"
-edition = "2021"
+edition.workspace = true
 
 [dependencies]
-sparreal-rt = { workspace = true, features = ["early-print"]}
+sparreal-rt = { workspace = true, features = ["early-print"] }
+sparreal-kernel = { workspace = true }
 log = { workspace = true }
diff --git a/app/helloworld/src/main.rs b/app/helloworld/src/main.rs
index 1a4418c..1de8794 100644
--- a/app/helloworld/src/main.rs
+++ b/app/helloworld/src/main.rs
@@ -1,22 +1,40 @@
 #![no_std]
 #![no_main]
+extern crate alloc;
+
+use core::time::Duration;
 
 use alloc::string::ToString;
 use log::info;
+use sparreal_kernel::{
+    task::{self, TaskConfig},
+    time::{self, spin_delay},
+};
+use sparreal_rt::prelude::*;
 
-extern crate alloc;
-extern crate sparreal_rt;
-
-#[sparreal_rt::entry]
+#[entry]
 fn main() {
-    info!("hello world");
-    let s = "hello world".to_string();
-    let st = s.as_str();
+    info!("Hello, world!");
+
+    time::after(Duration::from_secs(1), || {
+        info!("Timer callback");
+        // shutdown();
+    });
 
-    // unsafe {
-    // let a = *(0xffff_ffff_ffff_ffff as *const u8);
-    // sparreal_rt::println!("{:x}", a);
-    // }
+    task::spawn_with_config(
+        || {
+            info!("task2");
+        },
+        TaskConfig {
+            name: "task2".to_string(),
+            priority: 0,
+            stack_size: 0x1000 * 4,
+        },
+    )
+    .unwrap();
 
-    assert_eq!(st, "hello world");
+    loop {
+        spin_delay(Duration::from_secs(1));
+        info!("123");
+    }
 }
diff --git a/app/simple_test/Cargo.toml b/app/simple_test/Cargo.toml
index 7babf7b..3f22d08 100644
--- a/app/simple_test/Cargo.toml
+++ b/app/simple_test/Cargo.toml
@@ -9,3 +9,8 @@ log = { workspace = true }
 
 [build-dependencies]
 bare-test-macros = { workspace = true }
+
+
+[[test]]
+name = "test1"
+harness = false
diff --git a/app/simple_test/tests/test1.rs b/app/simple_test/tests/test1.rs
index 6b7eecf..93c9914 100644
--- a/app/simple_test/tests/test1.rs
+++ b/app/simple_test/tests/test1.rs
@@ -1,51 +1,19 @@
 #![no_std]
 #![no_main]
-#![feature(custom_test_frameworks)]
-#![test_runner(bare_test::test_runner)]
-#![reexport_test_harness_main = "test_main"]
+#![feature(used_with_arg)]
 
-bare_test::test_setup!();
+#[bare_test::tests]
+mod tests {
 
-use bare_test::{driver::device_tree::get_device_tree, mem::mmu::iomap, println};
+    use bare_test::*;
+    use globals::{PlatformInfoKind, global_val};
 
-#[test_case]
-fn it_works2() {
-    // non-panic assert_eq!
-    macro_rules! assert_eq {
-        ($left:expr, $right:expr $(,)?) => {
-            if $left != $right { ::log::error!("{} ≠ {}", $left, $right); }
+    #[test]
+    fn test2() {
+        let _fdt = match &global_val().platform_info {
+            PlatformInfoKind::DeviceTree(fdt) => fdt.get(),
         };
-        ($left:expr, $right:expr, $($arg:tt)+) => {
-            if $left != $right {
-                ::log::error!("{} ≠ {}", $left, $right);
-                ::log::error!($($arg)+);
-            }
-        };
-    }
 
-    println!("test2... ");
-    assert_eq!(1, 2, "Not eq on purpose.");
-}
-
-#[test_case]
-#[allow(clippy::eq_op)]
-fn it_works1() {
-    println!("test1... ");
-    assert_eq!(1, 1);
-}
-
-#[test_case]
-fn test_uart() {
-    // map uart data register for using.
-    let uart_data_reg = iomap(0x9000000.into(), 0x1000);
-
-    let _fdt = get_device_tree().unwrap();
-
-    // write to uart, then it will be print to the screen.
-    unsafe {
-        uart_data_reg.write_volatile(b'A');
-        uart_data_reg.write_volatile(b'\n');
+        assert_eq!(2 + 2, 4)
     }
-
-    println!("uart test passed!");
 }
diff --git a/crates/bare-test-macros/Cargo.toml b/crates/bare-test-macros/Cargo.toml
index 34c6c6f..1b3b81f 100644
--- a/crates/bare-test-macros/Cargo.toml
+++ b/crates/bare-test-macros/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "bare-test-macros"
-version = "0.0.1"
+version = "0.2.0"
 edition = "2021"
 license = "MIT"
 description = "macros for bare-test"
diff --git a/crates/bare-test-macros/src/lib.rs b/crates/bare-test-macros/src/lib.rs
index d5f473d..2322045 100644
--- a/crates/bare-test-macros/src/lib.rs
+++ b/crates/bare-test-macros/src/lib.rs
@@ -6,38 +6,88 @@ extern crate proc_macro2;
 extern crate syn;
 
 use proc_macro::TokenStream;
+use syn::{parse, spanned::Spanned, Item, ItemMod};
 
-/// Setup the test entry point.
-/// # Example
-///
-///```rust
-///#![no_std]
-///#![no_main]
-///#![feature(custom_test_frameworks)]
-///#![test_runner(bare_test::test_runner)]
-///#![reexport_test_harness_main = "test_main"]
-///
-///bare_test::test_setup!();
-///```
 #[proc_macro]
-pub fn test_setup(_input: TokenStream) -> TokenStream {
+pub fn build_test_setup(_input: TokenStream) -> TokenStream {
     quote! {
-
-    #[bare_test::entry]
-    fn main() {
-        test_main();
+    println!("cargo::rustc-link-arg-tests=-Ttest_case_link.ld");
+    println!("cargo::rustc-link-arg-tests=-no-pie");
+    println!("cargo::rustc-link-arg-tests=-znostart-stop-gc");
     }
+    .into()
+}
 
+#[proc_macro_attribute]
+pub fn tests(args: TokenStream, input: TokenStream) -> TokenStream {
+    match tests_impl(args, input) {
+        Ok(tokens) => tokens,
+        Err(e) => e.to_compile_error().into(),
     }
-    .into()
 }
 
-#[proc_macro]
-pub fn build_test_setup(_input: TokenStream) -> TokenStream {
-    quote! {
-    println!("cargo::rustc-link-arg-tests=-Tlink.x");
-    println!("cargo::rustc-link-arg-tests=-no-pie");
-    println!("cargo::rustc-link-arg-tests=-znostart-stop-gc");
+fn tests_impl(_args: TokenStream, input: TokenStream) -> Result<TokenStream, parse::Error> {
+    let krate = format_ident!("bare_test");
+    let module: ItemMod = syn::parse(input)?;
+
+    let ident = &module.ident;
+
+    let mut untouched_tokens = vec![];
+    let mut test_functions = vec![];
+    let span = module.span();
+
+    let items = &module
+        .content
+        .ok_or(parse::Error::new(
+            span,
+            "module must be inline (e.g. `mod foo {}`)",
+        ))?
+        .1;
+
+    for item in items {
+        match item {
+            Item::Fn(f) => {
+                if f.attrs.iter().any(|attr| attr.path().is_ident("test")) {
+                    let f_name = &f.sig.ident;
+                    let _f_name = format_ident!("__{}", f.sig.ident);
+                    let block = &f.block;
+                    let static_name = format_ident!("__TEST_{}", f_name.to_string().to_uppercase());
+                    let f_name_str = f_name.to_string();
+
+                    test_functions.push(quote! {
+                        #[test]
+                        fn #f_name() {
+                            #_f_name()
+                        }
+
+                        fn #_f_name() {
+                            #block
+                        }
+
+                        #[used(linker)]
+                        #[unsafe(link_section = ".test_case")]
+                        static #static_name: #krate::TestCase = #krate::TestCase {
+                            name: #f_name_str,
+                            test_fn: #_f_name,
+                        };
+                    });
+                } else {
+                    untouched_tokens.push(item);
+                }
+            }
+            _ => {
+                untouched_tokens.push(item);
+            }
+        }
     }
-    .into()
+
+    Ok(quote!(
+        #[cfg(test)]
+        mod #ident{
+            #(#untouched_tokens)*
+            #(#test_functions)*
+
+        }
+    )
+    .into())
 }
diff --git a/crates/bare-test/Cargo.toml b/crates/bare-test/Cargo.toml
index d83b9de..bee9ec5 100644
--- a/crates/bare-test/Cargo.toml
+++ b/crates/bare-test/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "bare-test"
-version = "0.2.0"
+version = "0.3.1"
 authors = ["Zhourui <zrufo747@outlook.com>"]
 edition = "2021"
 repository = "https://github.com/qclic/sparreal-os/tree/main/crates/bare-test"
@@ -10,10 +10,13 @@ keywords = ["test", "case", "testing", "testcase", "unittest"]
 categories = ["development-tools", "development-tools::testing"]
 
 [features]
-build = []
+default = ["rt"]
+# 使用 `sparreal-rt` 作为运行时
+rt = ["dep:sparreal-rt"]
 
 [dependencies]
-sparreal-rt = { version = "0.2", path = "../sparreal-rt" }
-sparreal-macros = { version = "0.0.5", path = "../sparreal-macros" }
-bare-test-macros = { version = "0.0.1", path = "../bare-test-macros" }
+sparreal-rt = { version = "0.6", path = "../sparreal-rt", optional = true }
+sparreal-kernel = { version = "0.6", path = "../sparreal-kernel" }
+sparreal-macros = { version = "0.6", path = "../sparreal-macros" }
+bare-test-macros = { version = "0.2", path = "../bare-test-macros" }
 log = { version = "0.4" }
diff --git a/crates/bare-test/README.md b/crates/bare-test/README.md
index f3cdea9..ccf5085 100644
--- a/crates/bare-test/README.md
+++ b/crates/bare-test/README.md
@@ -23,60 +23,50 @@ A test framework for testing the bare metal.
 
     ```toml
     [dev-dependencies]
-    bare-test = "0.0.1"
+    bare-test = "0.2"
 
     [build-dependencies]
-    sparreal-macros = "0.0.1"
+    bare-test-macros = "0.2"
+
+    [[test]]
+    name = "test"
+    harness = false
     ```
 
 4. setup `build.rs`.
 
     ```rust
     fn main() {
-        sparreal_macros::build_test_setup!();
+        bare_test_macros::build_test_setup!();
     }
     ```
 
-5. new `tests` dir and add `tests.rs`.
+5. new `tests` dir and add `test.rs`.
 
     ```rust
     #![no_std]
     #![no_main]
-    #![feature(custom_test_frameworks)]
-    #![test_runner(bare_test::test_runner)]
-    #![reexport_test_harness_main = "test_main"]
+    #![feature(used_with_arg)]
 
-    extern crate bare_test;
+    #[bare_test::tests]
+    mod tests {
 
-    #[bare_test::entry]
-    fn main() {
-        test_main();
-    }
-
-    use bare_test::println;
-    #[test_case]
-    fn it_not_works() {
-        println!("test2... ");
-        assert_eq!(1, 2);
-    }
-    #[test_case]
-    fn it_works1() {
-        println!("test1... ");
-        assert_eq!(1, 1);
-    }
-    #[test_case]
-    fn test_uart(){
-        // map uart data register for using.
-        let uart_data_reg = iomap(0x9000000.into(), 0x1000);
-
-        // write to uart, then it will be print to the screen.
-        unsafe{
-            uart_data_reg.write_volatile(b'A');
-            uart_data_reg.write_volatile(b'\n');
+        #[test]
+        fn it_works() {
+            assert_eq!(2 + 2, 4)
         }
 
-        println!("uart test passed!");
+        #[test]
+        fn test2() {
+            assert_eq!(2 + 2, 4)
+        }
     }
     ```
 
-6. run `cargo test --test tests --  --show-output`.
+6. run `cargo test --test test --  --show-output`.
+
+7. for uboot board test:
+
+```sh
+cargo test --test tests --  --show-output --uboot
+```
diff --git a/crates/bare-test/build.rs b/crates/bare-test/build.rs
new file mode 100644
index 0000000..ea53461
--- /dev/null
+++ b/crates/bare-test/build.rs
@@ -0,0 +1,11 @@
+use std::{fs, path::PathBuf};
+
+fn main() {
+    let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
+    let link = "test_case_link.ld";
+
+    let _ = fs::copy("link.ld", out_dir.join(link));
+
+    println!("cargo:rustc-link-search={}", out_dir.display());
+    println!("cargo:rerun-if-changed=test_case_link.ld");
+}
diff --git a/crates/bare-test/link.ld b/crates/bare-test/link.ld
new file mode 100644
index 0000000..d7c9cac
--- /dev/null
+++ b/crates/bare-test/link.ld
@@ -0,0 +1,14 @@
+INCLUDE link.x
+
+SECTIONS
+{
+    .test_case : ALIGN(4)
+    {
+        _stest_case = .;
+        *(.test_case)
+        *(.test_case.*)
+        _etest_case = .;
+    }
+    /* 其他段定义 */
+}
+INSERT AFTER .rodata;
\ No newline at end of file
diff --git a/crates/bare-test/src/lib.rs b/crates/bare-test/src/lib.rs
index 664807f..7a231e5 100644
--- a/crates/bare-test/src/lib.rs
+++ b/crates/bare-test/src/lib.rs
@@ -1,26 +1,51 @@
 #![no_std]
 
 extern crate alloc;
-#[cfg(not(feature = "build"))]
+extern crate sparreal_kernel;
+
+#[cfg(feature = "rt")]
 extern crate sparreal_rt;
 
-#[cfg(not(feature = "build"))]
-pub use sparreal_rt::*;
+use core::ptr::slice_from_raw_parts;
+
+pub use bare_test_macros::tests;
+pub use sparreal_kernel::prelude::*;
+pub use sparreal_kernel::*;
+
+mod test_case;
+
+#[sparreal_macros::entry]
+fn main() -> ! {
+    println!("begin test");
 
-pub use bare_test_macros::test_setup;
+    for test in test_case_list() {
+        println!("Run test: {}", test.name);
 
-#[cfg(feature = "build")]
-pub use sparreal_macros::build_test_setup;
+        (test.test_fn)();
 
-#[cfg(not(feature = "build"))]
-pub fn test_runner(tests: &[&dyn Fn()]) {
-    pub use sparreal_rt::println;
-    println!("Running {} tests", tests.len());
-    for (i, test) in tests.iter().enumerate() {
-        println!("[test {} start]", i);
-        test();
-        println!("[test {} passed]", i);
+        println!("test {} passed", test.name);
     }
+
     println!("All tests passed");
-    shutdown()
+}
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct TestCase {
+    pub name: &'static str,
+    pub test_fn: fn(),
+}
+
+fn test_case_list() -> test_case::Iter<'static> {
+    unsafe extern "C" {
+        fn _stest_case();
+        fn _etest_case();
+    }
+
+    let data = _stest_case as usize as *const u8;
+    let len = _etest_case as usize - _stest_case as usize;
+
+    let list = test_case::ListRef::from_raw(unsafe { &*slice_from_raw_parts(data, len) });
+
+    list.iter()
 }
diff --git a/crates/bare-test/src/test_case.rs b/crates/bare-test/src/test_case.rs
new file mode 100644
index 0000000..ad41f4d
--- /dev/null
+++ b/crates/bare-test/src/test_case.rs
@@ -0,0 +1,53 @@
+use core::ptr::slice_from_raw_parts;
+
+use crate::TestCase;
+
+#[repr(C)]
+pub struct ListRef {
+    data: *const u8,
+    len: usize,
+}
+
+impl ListRef {
+    pub fn from_raw(data: &'static [u8]) -> Self {
+        Self {
+            data: data.as_ptr() as _,
+            len: data.len(),
+        }
+    }
+
+    pub fn iter(&self) -> Iter<'static> {
+        Iter::new(unsafe { core::slice::from_raw_parts(self.data, self.len) })
+    }
+}
+
+pub struct Iter<'a> {
+    data: &'a [u8],
+    iter: usize,
+}
+
+impl<'a> Iter<'a> {
+    pub fn new(data: &'a [u8]) -> Self {
+        Iter { data, iter: 0 }
+    }
+}
+
+impl Iterator for Iter<'_> {
+    type Item = TestCase;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.data.is_empty() {
+            return None;
+        }
+
+        let slice = unsafe {
+            &*slice_from_raw_parts(
+                self.data.as_ptr() as *const TestCase,
+                self.data.len() / size_of::<TestCase>(),
+            )
+        };
+        let out = slice.get(self.iter).cloned();
+        self.iter += 1;
+        out
+    }
+}
diff --git a/crates/driver-interface/Cargo.toml b/crates/driver-interface/Cargo.toml
index 83fcd0a..ff9d17b 100644
--- a/crates/driver-interface/Cargo.toml
+++ b/crates/driver-interface/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "driver-interface"
-version = "0.0.1"
+version = "0.2.0"
 authors = ["Zhourui <zrufo747@outlook.com>"]
 edition = "2021"
 repository = "https://github.com/qclic/sparreal-os"
@@ -12,3 +12,4 @@ categories = ["embedded", "no-std"]
 [dependencies]
 futures = { version = "0.3", default-features = false, features = ["alloc"] }
 embedded-io = "0.6"
+log = "0.4"
diff --git a/crates/driver-interface/src/_macro.rs b/crates/driver-interface/src/_macro.rs
new file mode 100644
index 0000000..50c9464
--- /dev/null
+++ b/crates/driver-interface/src/_macro.rs
@@ -0,0 +1,30 @@
+#[macro_export]
+macro_rules! custom_type {
+    ($name:ident, $target:ty, $debug: expr) => {
+        #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+        #[repr(transparent)]
+        pub struct $name($target);
+
+        impl From<$target> for $name {
+            fn from(value: $target) -> Self {
+                Self(value)
+            }
+        }
+
+        impl From<$name> for $target {
+            fn from(value: $name) -> Self {
+                value.0
+            }
+        }
+
+        impl Debug for $name {
+            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+                write!(f, $debug, self.0)
+            }
+        }
+    };
+
+    ($name:ident, $target:ty) => {
+        $crate::custom_type!($name, $target, "{:?}")
+    };
+}
diff --git a/crates/driver-interface/src/err.rs b/crates/driver-interface/src/err.rs
new file mode 100644
index 0000000..809019b
--- /dev/null
+++ b/crates/driver-interface/src/err.rs
@@ -0,0 +1,6 @@
+#[derive(Debug)]
+pub enum DriverError {
+    NotSupported,
+}
+
+pub type DriverResult<T> = core::result::Result<T, DriverError>;
diff --git a/crates/driver-interface/src/interrupt_controller.rs b/crates/driver-interface/src/interrupt_controller.rs
new file mode 100644
index 0000000..a9db348
--- /dev/null
+++ b/crates/driver-interface/src/interrupt_controller.rs
@@ -0,0 +1,43 @@
+use core::{error::Error, fmt::Debug};
+
+use crate::{custom_type, DriverGeneric, RegAddress};
+use alloc::{boxed::Box, vec::Vec};
+
+custom_type!(IrqId, usize, "{:#x}");
+custom_type!(CpuId, usize, "{:#x}");
+
+pub type Hardware = Box<dyn Interface>;
+pub type ProbeFn = fn(regs: Vec<RegAddress>) -> Hardware;
+pub type HardwareCPU = Box<dyn InterfaceCPU>;
+
+pub trait InterfaceCPU: Send {
+    fn get_and_acknowledge_interrupt(&mut self) -> Option<IrqId>;
+    fn end_interrupt(&mut self, irq: IrqId);
+    fn irq_enable(&mut self, irq: IrqId);
+    fn irq_disable(&mut self, irq: IrqId);
+    fn set_priority(&mut self, irq: IrqId, priority: usize);
+    fn set_trigger(&mut self, irq: IrqId, triger: Trigger);
+    fn set_bind_cpu(&mut self, irq: IrqId, cpu_list: &[CpuId]);
+    fn parse_fdt_config(&self, prop_interrupts: &[u32]) -> Result<IrqConfig, Box<dyn Error>>;
+    fn irq_pin_to_id(&self, pin: usize) -> Result<IrqId, Box<dyn Error>>;
+}
+
+pub trait Interface: DriverGeneric {
+    fn current_cpu_setup(&self) -> HardwareCPU;
+}
+
+/// The trigger configuration for an interrupt.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Trigger {
+    EdgeBoth,
+    EdgeRising,
+    EdgeFailling,
+    LevelHigh,
+    LevelLow,
+}
+
+#[derive(Debug, Clone)]
+pub struct IrqConfig {
+    pub irq: IrqId,
+    pub trigger: Trigger,
+}
diff --git a/crates/driver-interface/src/io/mod.rs b/crates/driver-interface/src/io/mod.rs
deleted file mode 100644
index 3337104..0000000
--- a/crates/driver-interface/src/io/mod.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use core::fmt;
-
-use alloc::boxed::Box;
-
-pub type IOError = embedded_io::ErrorKind;
-pub type IOResult<T = ()> = Result<T, IOError>;
-
-pub type BoxWrite = Box<dyn Write>;
-
-pub trait Write: Send + Sync {
-    // Required methods
-    fn write(&mut self, buf: &[u8]) -> IOResult<usize>;
-    fn flush(&mut self) -> IOResult;
-
-    /// Write an entire buffer into this writer.
-    ///
-    /// This function calls `write()` in a loop until exactly `buf.len()` bytes have
-    /// been written, blocking if needed.
-    ///
-    /// If you are using [`WriteReady`] to avoid blocking, you should not use this function.
-    /// `WriteReady::write_ready()` returning true only guarantees the first call to `write()` will
-    /// not block, so this function may still block in subsequent calls.
-    ///
-    /// This function will panic if `write()` returns `Ok(0)`.
-    fn write_all(&mut self, mut buf: &[u8]) -> IOResult {
-        while !buf.is_empty() {
-            match self.write(buf) {
-                Ok(0) => panic!("write() returned Ok(0)"),
-                Ok(n) => buf = &buf[n..],
-                Err(e) => return Err(e),
-            }
-        }
-        Ok(())
-    }
-}
-
-impl fmt::Write for dyn Write {
-    fn write_str(&mut self, s: &str) -> fmt::Result {
-        self.write_all(s.as_bytes()).map_err(|_| fmt::Error)
-    }
-}
diff --git a/crates/driver-interface/src/irq.rs b/crates/driver-interface/src/irq.rs
deleted file mode 100644
index 8c7c3f2..0000000
--- a/crates/driver-interface/src/irq.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-use alloc::boxed::Box;
-
-pub use crate::IrqProbeConfig;
-
-pub trait Driver: super::DriverGeneric {
-    fn get_and_acknowledge_interrupt(&self) -> Option<usize>;
-    fn end_interrupt(&self, irq: usize);
-    fn irq_max_size(&self) -> usize;
-    fn irq_enable(&mut self, irq: usize);
-    fn irq_disable(&mut self, irq: usize);
-    fn current_cpu_setup(&self);
-    fn set_priority(&mut self, irq: usize, priority: usize);
-    fn set_trigger(&mut self, irq: usize, triger: Trigger);
-    fn set_bind_cpu(&mut self, irq: usize, cpu_list: &[u64]);
-    fn fdt_parse_config(&self, prop_interupt: &[usize]) -> IrqProbeConfig;
-}
-
-pub type BoxDriver = Box<dyn Driver>;
-
-/// The trigger configuration for an interrupt.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Trigger {
-    EdgeBoth,
-    EdgeRising,
-    EdgeFailling,
-    LevelHigh,
-    LevelLow,
-}
diff --git a/crates/driver-interface/src/lib.rs b/crates/driver-interface/src/lib.rs
index f80c697..cfe7b17 100644
--- a/crates/driver-interface/src/lib.rs
+++ b/crates/driver-interface/src/lib.rs
@@ -1,111 +1,26 @@
-#![no_std]
-
-use core::{fmt::Display, ptr::NonNull};
-
-use alloc::{
-    string::{String, ToString},
-    sync::Arc,
-    vec::Vec,
-};
+#![cfg_attr(not(test), no_std)]
 
 extern crate alloc;
 
-pub use futures::future::BoxFuture;
-use futures::future::LocalBoxFuture;
-use irq::Trigger;
+use alloc::string::String;
 
-pub mod io;
-pub mod irq;
+pub(crate) mod _macro;
+pub mod interrupt_controller;
+mod register;
 pub mod timer;
-pub mod uart;
-
-pub type DriverResult<T = ()> = Result<T, DriverError>;
-
-pub trait DriverGeneric: Send + Sync + 'static {}
-
-#[derive(Clone)]
-pub struct Register {
-    pub name: String,
-    pub compatible: Vec<&'static str>,
-    pub kind: DriverKind,
-    pub probe: Arc<dyn Probe>,
-}
-impl Register {
-    pub fn new(
-        name: &str,
-        compatible: Vec<&'static str>,
-        kind: DriverKind,
-        probe: impl Probe,
-    ) -> Self {
-        Register {
-            name: name.to_string(),
-            compatible,
-            kind,
-            probe: Arc::new(probe),
-        }
-    }
-
-    pub fn compatible_matched(&self, compatible: &str) -> bool {
-        self.compatible.contains(&compatible)
-    }
-}
-
-#[derive(Default, Clone)]
-pub struct ProbeConfig {
-    pub id: DeviceId,
-    pub reg: Vec<NonNull<u8>>,
-    pub irq: Vec<IrqProbeConfig>,
-    pub clock_freq: Vec<u64>,
-}
-
-#[derive(Clone)]
-pub struct IrqProbeConfig {
-    pub irq: usize,
-    pub trigger: Trigger,
-}
-
-pub trait Probe: Send + Sync + 'static {
-    fn probe<'a>(&self, config: ProbeConfig) -> LocalBoxFuture<'a, DriverResult<DriverSpecific>>;
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub enum DriverKind {
-    InteruptChip,
-    Uart,
-    Timer,
-}
-
-pub enum DriverSpecific {
-    Uart(uart::BoxDriver),
-    InteruptChip(irq::BoxDriver),
-    Timer(timer::BoxDriver),
-}
-
-#[derive(Debug)]
-pub enum DriverError {
-    Init(String),
-    NotFound,
-    NoMemory,
-}
-
-#[repr(transparent)]
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct DeviceId(u64);
-
-impl From<DeviceId> for u64 {
-    fn from(val: DeviceId) -> Self {
-        val.0
-    }
-}
+pub use register::*;
+pub(crate) mod err;
+pub use err::DriverError;
+pub use err::DriverResult;
+pub use interrupt_controller::IrqConfig;
 
-impl From<u64> for DeviceId {
-    fn from(value: u64) -> Self {
-        Self(value)
-    }
+pub trait DriverGeneric: Send {
+    fn open(&mut self) -> Result<(), String>;
+    fn close(&mut self) -> Result<(), String>;
 }
 
-impl Display for DeviceId {
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "{}", self.0)
-    }
+#[derive(Debug, Clone, Copy)]
+pub struct RegAddress {
+    pub addr: usize,
+    pub size: Option<usize>,
 }
diff --git a/crates/driver-interface/src/register.rs b/crates/driver-interface/src/register.rs
new file mode 100644
index 0000000..985f688
--- /dev/null
+++ b/crates/driver-interface/src/register.rs
@@ -0,0 +1,39 @@
+use crate::{interrupt_controller, timer};
+
+#[repr(C)]
+#[derive(Clone)]
+pub struct DriverRegister {
+    pub name: &'static str,
+    pub compatibles: &'static [&'static str],
+    pub probe: ProbeFnKind,
+}
+
+unsafe impl Send for DriverRegister {}
+unsafe impl Sync for DriverRegister {}
+
+#[derive(Clone)]
+pub enum ProbeFnKind {
+    InterruptController(interrupt_controller::ProbeFn),
+    Timer(timer::ProbeFn),
+}
+
+#[repr(C)]
+pub struct DriverRegisterListRef {
+    data: *const u8,
+    len: usize,
+}
+
+impl DriverRegisterListRef {
+    pub fn from_raw(data: &'static [u8]) -> Self {
+        Self {
+            data: data.as_ptr(),
+            len: data.len(),
+        }
+    }
+
+    pub fn as_slice(&self) -> &[DriverRegister] {
+        unsafe {
+            core::slice::from_raw_parts(self.data as _, self.len / size_of::<DriverRegister>())
+        }
+    }
+}
diff --git a/crates/driver-interface/src/timer.rs b/crates/driver-interface/src/timer.rs
deleted file mode 100644
index 7536fa8..0000000
--- a/crates/driver-interface/src/timer.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use alloc::boxed::Box;
-
-pub trait Driver: super::DriverGeneric {
-    fn set_interval(&mut self, ticks: u64);
-    fn current_ticks(&self) -> u64;
-    fn tick_hz(&self) -> u64;
-    fn set_enable(&mut self, enable: bool);
-    fn set_irq_enable(&mut self, enable: bool);
-    fn read_irq_status(&self) -> bool;
-    fn irq_num(&self) -> u64;
-}
-
-pub type BoxDriver = Box<dyn Driver>;
diff --git a/crates/driver-interface/src/timer/mod.rs b/crates/driver-interface/src/timer/mod.rs
new file mode 100644
index 0000000..e54f213
--- /dev/null
+++ b/crates/driver-interface/src/timer/mod.rs
@@ -0,0 +1,120 @@
+use core::{
+    sync::atomic::{fence, Ordering},
+    time::Duration,
+};
+
+use crate::{interrupt_controller::IrqConfig, DriverGeneric};
+use alloc::{boxed::Box, vec::Vec};
+
+mod queue;
+
+pub type Hardware = Box<dyn Interface>;
+pub type ProbeFn = fn(Vec<IrqConfig>) -> Hardware;
+pub type HardwareCPU = Box<dyn InterfaceCPU>;
+const NANO_PER_SEC: u128 = 1_000_000_000;
+
+pub trait Interface: Send {
+    fn get_current_cpu(&mut self) -> Box<dyn InterfaceCPU>;
+}
+
+pub trait InterfaceCPU: DriverGeneric + Sync {
+    fn set_timeval(&mut self, ticks: u64);
+    fn current_ticks(&self) -> u64;
+    fn tick_hz(&self) -> u64;
+    fn set_irq_enable(&mut self, enable: bool);
+    fn get_irq_status(&self) -> bool;
+    fn irq(&self) -> IrqConfig;
+}
+
+pub struct Timer {
+    timer: HardwareCPU,
+    q: queue::Queue,
+}
+
+unsafe impl Sync for Timer {}
+
+impl Timer {
+    pub fn new(timer: HardwareCPU) -> Self {
+        Self {
+            timer,
+            q: queue::Queue::new(),
+        }
+    }
+
+    pub fn enable(&mut self) {
+        let _ = self.timer.open();
+    }
+
+    pub fn since_boot(&self) -> Duration {
+        self.tick_to_duration(self.timer.current_ticks())
+    }
+
+    pub fn after(&mut self, duration: Duration, callback: impl Fn() + 'static) {
+        let ticks = self.duration_to_tick(duration);
+
+        let event = queue::Event {
+            interval: None,
+            at_tick: self.timer.current_ticks() + ticks,
+            callback: Box::new(callback),
+            called: false,
+        };
+
+        self.add_event(event);
+    }
+
+    pub fn every(&mut self, duration: Duration, callback: impl Fn() + 'static) {
+        let ticks = self.duration_to_tick(duration);
+
+        let event = queue::Event {
+            interval: Some(ticks),
+            at_tick: self.timer.current_ticks() + ticks,
+            callback: Box::new(callback),
+            called: false,
+        };
+
+        self.add_event(event);
+    }
+
+    fn add_event(&mut self, event: queue::Event) {
+        self.timer.set_irq_enable(false);
+        fence(Ordering::SeqCst);
+
+        let next_tick = self.q.add_and_next_tick(event);
+        let v = next_tick - self.timer.current_ticks();
+        self.timer.set_timeval(v);
+
+        fence(Ordering::SeqCst);
+        self.timer.set_irq_enable(true);
+    }
+
+    pub fn handle_irq(&mut self) {
+        while let Some(event) = self.q.pop(self.timer.current_ticks()) {
+            (event.callback)();
+        }
+
+        match self.q.next_tick() {
+            Some(next_tick) => {
+                self.timer.set_timeval(next_tick);
+            }
+            None => {
+                self.timer.set_irq_enable(false);
+            }
+        }
+    }
+
+    pub fn set_irq_enable(&mut self, enable: bool) {
+        self.timer.set_irq_enable(enable);
+    }
+
+    fn tick_to_duration(&self, tick: u64) -> Duration {
+        Duration::from_nanos((tick as u128 * NANO_PER_SEC / self.timer.tick_hz() as u128) as _)
+    }
+
+    fn duration_to_tick(&self, duration: Duration) -> u64 {
+        (duration.as_nanos() * self.timer.tick_hz() as u128 / NANO_PER_SEC) as _
+    }
+
+    pub fn irq(&self) -> IrqConfig {
+        self.timer.irq()
+    }
+}
diff --git a/crates/driver-interface/src/timer/queue.rs b/crates/driver-interface/src/timer/queue.rs
new file mode 100644
index 0000000..125150d
--- /dev/null
+++ b/crates/driver-interface/src/timer/queue.rs
@@ -0,0 +1,65 @@
+use alloc::{boxed::Box, vec::Vec};
+use core::fmt::Debug;
+
+#[derive(Debug)]
+pub struct Queue {
+    events: Vec<Event>,
+}
+
+pub struct Event {
+    pub at_tick: u64,
+    pub interval: Option<u64>,
+    pub called: bool,
+    pub callback: Box<dyn Fn()>,
+}
+
+impl Debug for Event {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("Event")
+            .field("at_tick", &self.at_tick)
+            .field("interval", &self.interval)
+            .field("called", &self.called)
+            .finish()
+    }
+}
+
+impl Queue {
+    pub fn new() -> Self {
+        Self { events: Vec::new() }
+    }
+
+    pub fn add_and_next_tick(&mut self, event: Event) -> u64 {
+        self.events.retain(|e| !e.called);
+        self.events.push(event);
+        self.events.sort_by(|a, b| a.at_tick.cmp(&b.at_tick));
+        self.events[0].at_tick
+    }
+
+    pub fn next_tick(&self) -> Option<u64> {
+        for e in self.events.iter() {
+            if e.called {
+                continue;
+            }
+
+            return Some(e.at_tick);
+        }
+        None
+    }
+
+    pub fn pop(&mut self, now: u64) -> Option<&Event> {
+        for e in self.events.iter_mut() {
+            if e.called {
+                continue;
+            }
+            if e.at_tick <= now {
+                if let Some(interval) = e.interval {
+                    e.at_tick += interval;
+                } else {
+                    e.called = true;
+                }
+                return Some(e);
+            }
+        }
+        None
+    }
+}
diff --git a/crates/driver-interface/src/uart.rs b/crates/driver-interface/src/uart.rs
deleted file mode 100644
index d0e3d3b..0000000
--- a/crates/driver-interface/src/uart.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use core::ptr::NonNull;
-
-use alloc::boxed::Box;
-
-use crate::io;
-
-pub trait Driver: super::DriverGeneric + io::Write {}
-
-pub type BoxDriver = Box<dyn Driver>;
-
-/// Word length.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum DataBits {
-    Bits5,
-    Bits6,
-    Bits7,
-    Bits8,
-}
-
-/// Parity bit.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum Parity {
-    None,
-    Even,
-    Odd,
-}
-
-/// Stop bits.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum StopBits {
-    #[doc = "1 stop bit"]
-    STOP1,
-    #[doc = "2 stop bits"]
-    STOP2,
-}
-
-pub struct Config {
-    pub reg: NonNull<u8>,
-    pub baud_rate: u32,
-    pub clock_freq: u64,
-    pub data_bits: DataBits,
-    pub stop_bits: StopBits,
-    pub parity: Parity,
-}
diff --git a/crates/page-table-arm/Cargo.toml b/crates/page-table-arm/Cargo.toml
index a389e93..07db62a 100644
--- a/crates/page-table-arm/Cargo.toml
+++ b/crates/page-table-arm/Cargo.toml
@@ -2,7 +2,7 @@
 name = "page-table-arm"
 description = "A library of arm page table"
 version = "0.1.0"
-edition = "2021"
+edition = "2024"
 authors = ["周睿 <zrufo747@outlook.com>"]
 repository = "https://github.com/qclic/sparreal-os/tree/main/crates/page-table-arm"
 documentation = "https://docs.rs/page-table-arm"
@@ -12,4 +12,9 @@ categories = ["no-std"]
 
 [dependencies]
 bitflags = "2.6"
+log = "0.4"
 aarch64-cpu = "10.0.0"
+
+
+[dev-dependencies]
+env_logger = "0.11.5"
diff --git a/crates/page-table-arm/src/pte64.rs b/crates/page-table-arm/src/pte64.rs
index 0fe59db..81a87a3 100644
--- a/crates/page-table-arm/src/pte64.rs
+++ b/crates/page-table-arm/src/pte64.rs
@@ -1,5 +1,4 @@
 use crate::{MAIRKind, MAIRSetting};
-#[cfg(target_arch = "aarch64")]
 use aarch64_cpu::registers::*;
 
 pub struct MAIRDefault;
@@ -7,9 +6,9 @@ pub struct MAIRDefault;
 impl MAIRDefault {
     #[cfg(target_arch = "aarch64")]
     pub const fn mair_value() -> u64 {
-        // Device-nGnRE memory
+        // Device-nGnRnE memory
         use aarch64_cpu::registers::*;
-        let attr0 = MAIR_EL1::Attr0_Device::nonGathering_nonReordering_EarlyWriteAck.value;
+        let attr0 = MAIR_EL1::Attr0_Device::nonGathering_nonReordering_noEarlyWriteAck.value;
         // Normal memory
         let attr1 = MAIR_EL1::Attr1_Normal_Inner::WriteBack_NonTransient_ReadWriteAlloc.value
             | MAIR_EL1::Attr1_Normal_Outer::WriteBack_NonTransient_ReadWriteAlloc.value;
diff --git a/crates/sparreal-kernel/Cargo.toml b/crates/sparreal-kernel/Cargo.toml
index ab7fde8..ad2d6d8 100644
--- a/crates/sparreal-kernel/Cargo.toml
+++ b/crates/sparreal-kernel/Cargo.toml
@@ -1,9 +1,9 @@
 [package]
 name = "sparreal-kernel"
-version = "0.1.7"
+version.workspace = true
 authors = ["周睿 <zrufo747@outlook.com>"]
-edition = "2021"
-repository = "https://github.com/qclic/sparreal-os"
+edition = "2024"
+repository = "https://github.com/ZR233/sparreal-os"
 license = "MPL-2.0"
 description = "Sparreal OS kernel"
 keywords = ["os"]
@@ -16,14 +16,18 @@ mmu = []
 [dependencies]
 log = "0.4"
 buddy_system_allocator = "0.11"
-sparreal-macros = { version = "0.0.5", path = "../sparreal-macros" }
-# memory_addr = "0.3"
-page-table-generic = { version = "0.2" }
+sparreal-macros = { version = "0.6", path = "../sparreal-macros" }
+driver-interface = { version = "0.2", path = "../driver-interface" }
+memory_addr = "0.3"
+page-table-generic = { version = "0.3" }
 fdt-parser = "0.4"
 lock_api = "0.4"
-driver-interface = { version = "0.0.1", path = "../driver-interface" }
-# pasts = { version = "0.14", default-features = false }
+pasts = { version = "0.14", default-features = false }
 ansi_rgb = "0.2"
 rgb = "0.8.47"
-# embedded-hal-async = "1.0"
-spin_on = "0.1"
+spin = "0.9"
+anyhow = { version = "1.0", default-features = false }
+byte-unit = { version = "5.1", features = ["byte"], default-features = false }
+lazy_static = { version = "1.5", features = ["spin_no_std"] }
+thiserror = { version = "2", default-features = false }
+dma-api = "0.2"
\ No newline at end of file
diff --git a/crates/sparreal-kernel/src/__export.rs b/crates/sparreal-kernel/src/__export.rs
index 8a836e3..5334268 100644
--- a/crates/sparreal-kernel/src/__export.rs
+++ b/crates/sparreal-kernel/src/__export.rs
@@ -1 +1 @@
-pub use crate::stdout::{debug_hex, early_print_str, print};
+pub use crate::io::print::print;
diff --git a/crates/sparreal-kernel/src/async_std/mod.rs b/crates/sparreal-kernel/src/async_std/mod.rs
new file mode 100644
index 0000000..077885d
--- /dev/null
+++ b/crates/sparreal-kernel/src/async_std/mod.rs
@@ -0,0 +1 @@
+pub mod time;
diff --git a/crates/sparreal-kernel/src/async_std/time.rs b/crates/sparreal-kernel/src/async_std/time.rs
new file mode 100644
index 0000000..04f5c05
--- /dev/null
+++ b/crates/sparreal-kernel/src/async_std/time.rs
@@ -0,0 +1,31 @@
+use core::time::Duration;
+
+use crate::time::since_boot;
+
+pub fn sleep(duration: Duration) -> FutureSleep {
+    let now = since_boot();
+    FutureSleep {
+        wake_at: now + duration,
+    }
+}
+
+pub struct FutureSleep {
+    wake_at: Duration,
+}
+
+impl Future for FutureSleep {
+    type Output = ();
+
+    fn poll(
+        self: core::pin::Pin<&mut Self>,
+        cx: &mut core::task::Context<'_>,
+    ) -> core::task::Poll<Self::Output> {
+        let now = since_boot();
+        if now >= self.wake_at {
+            core::task::Poll::Ready(())
+        } else {
+            cx.waker().wake_by_ref();
+            core::task::Poll::Pending
+        }
+    }
+}
diff --git a/crates/sparreal-kernel/src/boot/debug.rs b/crates/sparreal-kernel/src/boot/debug.rs
new file mode 100644
index 0000000..2c4b531
--- /dev/null
+++ b/crates/sparreal-kernel/src/boot/debug.rs
@@ -0,0 +1,22 @@
+use core::fmt::Write;
+
+use crate::platform_if::PlatformImpl;
+
+pub struct DebugWriter;
+
+impl Write for DebugWriter {
+    fn write_str(&mut self, s: &str) -> core::fmt::Result {
+        write_str(s);
+        Ok(())
+    }
+}
+pub fn write_str(s: &str) {
+    s.bytes().for_each(|ch| {
+        PlatformImpl::debug_put(ch);
+    });
+}
+
+pub fn print(args: core::fmt::Arguments) {
+    let mut writer = DebugWriter;
+    let _ = writer.write_fmt(args);
+}
diff --git a/crates/sparreal-kernel/src/boot/mmu.rs b/crates/sparreal-kernel/src/boot/mmu.rs
new file mode 100644
index 0000000..ec801d0
--- /dev/null
+++ b/crates/sparreal-kernel/src/boot/mmu.rs
@@ -0,0 +1,45 @@
+use core::sync::atomic::{Ordering, fence};
+
+use super::{__start, print_info};
+use crate::{
+    globals::global_val,
+    io::print::*,
+    mem::{mmu::*, set_va_offset_now},
+    platform::PlatformInfoKind,
+    platform_if::MMUImpl,
+};
+
+pub fn start(
+    va_offset: usize,
+    platform_info: PlatformInfoKind,
+    rsv_memory: &[BootMemoryRegion],
+) -> Result<(), &'static str> {
+    early_dbgln("Booting up");
+
+    crate::mem::set_va_offset(va_offset);
+    unsafe { crate::globals::setup(platform_info)? };
+
+    print_info();
+
+    let table = new_boot_table(rsv_memory)?;
+
+    fence(Ordering::SeqCst);
+
+    set_user_table(table);
+    set_kernel_table(table);
+
+    flush_tlb_all();
+
+    fence(Ordering::SeqCst);
+
+    let jump_to = __start as usize + va_offset;
+    let stack_top = global_val().kstack_top.as_usize() + va_offset;
+    unsafe { set_va_offset_now(va_offset) };
+
+    early_dbg("Jump to __start: ");
+    early_dbg_hex(jump_to as _);
+    early_dbg(", stack top: ");
+    early_dbg_hexln(stack_top as _);
+
+    MMUImpl::enable_mmu(stack_top, jump_to)
+}
diff --git a/crates/sparreal-kernel/src/boot/mod.rs b/crates/sparreal-kernel/src/boot/mod.rs
new file mode 100644
index 0000000..2f7b5e0
--- /dev/null
+++ b/crates/sparreal-kernel/src/boot/mod.rs
@@ -0,0 +1,110 @@
+#![allow(unused)]
+
+use ansi_rgb::{Foreground, orange};
+use log::LevelFilter;
+
+use crate::{
+    driver_manager,
+    globals::{self, global_val},
+    io::{self, print::*},
+    irq,
+    logger::KLogger,
+    mem::{self, VirtAddr, region, va_offset},
+    platform::{self, app_main, module_registers, platform_name, shutdown},
+    platform_if::*,
+    println, task, time,
+};
+
+pub mod debug;
+
+#[cfg(feature = "mmu")]
+mod mmu;
+
+#[cfg(feature = "mmu")]
+pub use mmu::start;
+
+#[repr(align(0x10))]
+pub extern "C" fn __start() -> ! {
+    early_dbgln("Relocate success.");
+
+    io::print::stdout_use_debug();
+
+    mem::init_heap();
+
+    print_start_msg();
+
+    let _ = log::set_logger(&KLogger);
+    log::set_max_level(LevelFilter::Trace);
+
+    PlatformImpl::on_boot_success();
+
+    mem::init_page_and_memory();
+
+    unsafe { globals::setup_percpu() };
+
+    driver_manager::register_drivers(&module_registers());
+
+    irq::init_main_cpu();
+
+    time::init_main_cpu();
+
+    irq::enable_all();
+
+    task::init();
+
+    app_main();
+
+    shutdown()
+}
+
+fn print_info() {
+    early_dbg("va: ");
+    early_dbg_hexln(va_offset() as _);
+
+    let regions = crate::platform_if::PlatformImpl::kernel_regions();
+
+    early_dbg_mem("kernel.text", regions.text.as_slice());
+    early_dbg_mem("kernel.data", regions.data.as_slice());
+    early_dbg_mem("kernel.bss ", regions.bss.as_slice());
+}
+
+macro_rules! print_pair {
+    ($name:expr, $($arg:tt)*) => {
+        $crate::print!("{:<30}: {}\r\n", $name, format_args!($($arg)*));
+    };
+}
+
+fn print_start_msg() {
+    println!("{}", LOGO.fg(orange()));
+
+    print_pair!("Version", env!("CARGO_PKG_VERSION"));
+    print_pair!("Platfrom", "{}", platform_name());
+    print_pair!("Kernel Base", "{:p}", region::text().as_ptr());
+
+    let size =
+        region::bss().as_ptr_range().end as usize - region::text().as_ptr_range().start as usize;
+
+    print_pair!("Kernel Size", "{:#}", byte_unit::Byte::from_u64(size as _));
+    print_pair!(
+        "Kernel Stack Top",
+        "{}",
+        VirtAddr::from(global_val().kstack_top)
+    );
+
+    print_pair!("Start CPU", "{:?}", platform::cpu_id());
+
+    if let Some(debug) = global_val().platform_info.debugcon() {
+        if let Some(c) = debug.compatibles().next() {
+            print_pair!("Debug Serial", "{}", c);
+        }
+    }
+}
+
+static LOGO: &str = r#"
+     _____                                         __
+    / ___/ ____   ____ _ _____ _____ ___   ____ _ / /
+    \__ \ / __ \ / __ `// ___// ___// _ \ / __ `// / 
+   ___/ // /_/ // /_/ // /   / /   /  __// /_/ // /  
+  /____// .___/ \__,_//_/   /_/    \___/ \__,_//_/   
+       /_/                                           
+"#;
diff --git a/crates/sparreal-kernel/src/driver/container.rs b/crates/sparreal-kernel/src/driver/container.rs
deleted file mode 100644
index a665820..0000000
--- a/crates/sparreal-kernel/src/driver/container.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-use super::{
-    device_id_by_node_name, device_tree::get_device_tree, DeviceId, DriverIrqChip, DriverTimer,
-    DriverUart,
-};
-
-use crate::{driver::device_tree::FDTExtend as _, sync::RwLock};
-use alloc::{
-    collections::{btree_map::BTreeMap, btree_set::BTreeSet},
-    string::{String, ToString},
-    vec::Vec,
-};
-use driver_interface::{DriverKind, DriverSpecific, ProbeConfig, Register};
-use log::{error, info};
-
-pub(super) static CONTAINER: Container = Container::new();
-
-type ContainerKind<T> = RwLock<BTreeMap<DeviceId, T>>;
-
-const fn new_kind<T>() -> ContainerKind<T> {
-    RwLock::new(BTreeMap::new())
-}
-
-pub(super) struct Container {
-    pub(super) registers: RwLock<BTreeMap<String, Register>>,
-    probed: RwLock<BTreeSet<DeviceId>>,
-    pub(super) uart: ContainerKind<DriverUart>,
-    pub(super) irq_chip: ContainerKind<DriverIrqChip>,
-    pub(super) timer: ContainerKind<DriverTimer>,
-}
-
-impl Container {
-    const fn new() -> Self {
-        Self {
-            registers: RwLock::new(BTreeMap::new()),
-            probed: RwLock::new(BTreeSet::new()),
-            uart: new_kind(),
-            irq_chip: new_kind(),
-            timer: new_kind(),
-        }
-    }
-
-    pub fn add_driver(&self, id: DeviceId, name: String, spec: DriverSpecific) {
-        macro_rules! add_to {
-            ($driver:expr,$field:ident) => {
-                let d = $crate::driver::DriverCommon::new(id.clone(), name, $driver);
-                self.$field.write().insert(id, d.into());
-            };
-        }
-
-        match spec {
-            DriverSpecific::Uart(driver) => {
-                add_to!(driver, uart);
-            }
-            DriverSpecific::InteruptChip(driver) => {
-                add_to!(driver, irq_chip);
-            }
-            DriverSpecific::Timer(driver) => {
-                add_to!(driver, timer);
-            }
-        }
-    }
-}
-pub fn add_driver<N: ToString>(id: DeviceId, name: N, spec: DriverSpecific) {
-    CONTAINER.add_driver(id, name.to_string(), spec);
-}
-
-pub async fn probe_by_register(register: Register) -> Option<()> {
-    let fdt = get_device_tree()?;
-    let node = fdt.find_compatible(&register.compatible).next()?;
-
-    let config = node.probe_config();
-
-    probe(config, register).await;
-    Some(())
-}
-
-pub async fn probe_by_node(node: fdt_parser::Node<'_>) -> Option<()> {
-    let id = device_id_by_node_name(node.name);
-
-    if is_probed(&id) {
-        return Some(());
-    }
-
-    let caps = node.compatibles().collect::<Vec<_>>();
-    let register = register_by_compatible(&caps)?;
-    let config = node.probe_config();
-
-    probe(config, register).await;
-    Some(())
-}
-
-pub(crate) fn is_probed(id: &DeviceId) -> bool {
-    CONTAINER.probed.read().contains(id)
-}
-
-pub async fn probe(config: ProbeConfig, register: Register) -> Option<()> {
-    let id = config.id;
-    if is_probed(&id) {
-        return None;
-    }
-    info!("[{}]Probe driver [{}]", id, register.name);
-    for irq in &config.irq {
-        info!("[{}]    Irq: {}, triger {:?}", id, irq.irq, irq.trigger);
-    }
-
-    let kind = register
-        .probe
-        .probe(config)
-        .await
-        .inspect_err(|e| error!("{:?}", e))
-        .ok()?;
-    info!("[{}]Probe success!", id);
-
-    CONTAINER.probed.write().insert(id);
-
-    add_driver(id, register.name, kind);
-    Some(())
-}
-
-pub fn uart_list() -> Vec<DriverUart> {
-    let g = CONTAINER.uart.read();
-    g.values().cloned().collect()
-}
-
-pub fn uart_by_id(id: DeviceId) -> Option<DriverUart> {
-    CONTAINER.uart.read().get(&id).cloned()
-}
-
-pub fn irq_chip_list() -> Vec<DriverIrqChip> {
-    let g = CONTAINER.irq_chip.read();
-    g.values().cloned().collect()
-}
-pub fn irq_chip_by_id_or_first(id: DeviceId) -> Option<DriverIrqChip> {
-    let g = CONTAINER.irq_chip.read();
-    g.get(&id).or_else(|| g.values().next()).cloned()
-}
-
-pub fn irq_by_id(id: DeviceId) -> Option<DriverIrqChip> {
-    CONTAINER.irq_chip.read().get(&id).cloned()
-}
-
-pub fn register_append(registers: impl IntoIterator<Item = Register>) {
-    let mut c = CONTAINER.registers.write();
-    for reg in registers {
-        for cap in &reg.compatible {
-            c.insert(cap.to_string(), reg.clone());
-        }
-    }
-}
-
-pub fn register_by_compatible(compatible: &[&str]) -> Option<Register> {
-    let c = CONTAINER.registers.read();
-    for cap in compatible {
-        if let Some(reg) = c.get(*cap) {
-            return Some(reg.clone());
-        }
-    }
-    None
-}
-
-pub fn register_by_kind(kind: DriverKind) -> Vec<Register> {
-    let c = CONTAINER.registers.read();
-    c.values().filter(|one| one.kind == kind).cloned().collect()
-}
-
-pub fn register_all() -> Vec<Register> {
-    let c = CONTAINER.registers.read();
-    c.values().cloned().collect()
-}
diff --git a/crates/sparreal-kernel/src/driver/device_tree/mod.rs b/crates/sparreal-kernel/src/driver/device_tree/mod.rs
deleted file mode 100644
index fc4f6a1..0000000
--- a/crates/sparreal-kernel/src/driver/device_tree/mod.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use core::ptr::NonNull;
-
-use alloc::{vec, vec::Vec};
-use driver_interface::ProbeConfig;
-
-use super::{device_id_by_node_name, irq_by_id};
-
-// #[link_section = ".data.boot"]
-static mut DTB_ADDR: Option<NonNull<u8>> = None;
-
-pub(crate) unsafe fn set_dtb_addr(addr: Option<NonNull<u8>>) {
-    DTB_ADDR = addr;
-}
-
-pub fn get_device_tree<'a>() -> Option<fdt_parser::Fdt<'a>> {
-    unsafe {
-        let dtb_addr = DTB_ADDR?;
-        fdt_parser::Fdt::from_ptr(dtb_addr).ok()
-    }
-}
-pub trait FDTExtend {
-    fn interrupt_list(&self) -> Vec<Vec<usize>>;
-    fn probe_config(&self) -> ProbeConfig;
-    fn find_clock(&self) -> Vec<u64>;
-}
-
-impl FDTExtend for fdt_parser::Node<'_> {
-    fn interrupt_list(&self) -> Vec<Vec<usize>> {
-        let mut ret = Vec::new();
-        let info = match self.interrupts() {
-            Some(i) => i,
-            None => return Vec::new(),
-        };
-        for itr in info {
-            let elem = itr.map(|o| o as usize).collect::<Vec<_>>();
-            ret.push(elem);
-        }
-        ret
-    }
-
-    fn probe_config(&self) -> ProbeConfig {
-        let mut config = ProbeConfig {
-            id: device_id_by_node_name(self.name),
-            ..Default::default()
-        };
-
-        if let Some(regs) = self.reg() {
-            for reg in regs {
-                #[cfg(feature = "mmu")]
-                let reg_base = crate::mem::mmu::iomap(
-                    (reg.address as usize).into(),
-                    reg.size.unwrap_or(0x1000),
-                );
-                #[cfg(not(feature = "mmu"))]
-                let reg_base = NonNull::new(reg.address as usize as _).unwrap();
-                config.reg.push(reg_base);
-            }
-        }
-
-        let irq_origin = self.interrupt_list();
-
-        if let Some(itr_node) = self.interrupt_parent() {
-            let id = device_id_by_node_name(itr_node.node.name);
-            if let Some(irq) = irq_by_id(id) {
-                let g = irq.spec.read();
-
-                for elem in irq_origin {
-                    config.irq.push(g.fdt_parse_config(&elem));
-                }
-            }
-        }
-
-        config.clock_freq = self.find_clock();
-
-        config
-    }
-
-    fn find_clock(&self) -> Vec<u64> {
-        if let Some(clk) = self.clock_frequency() {
-            vec![clk as _]
-        } else {
-            let mut out = Vec::new();
-            for clk in self.clocks() {
-                if let Some(freq) = clk.node.clock_frequency() {
-                    out.push(freq as _);
-                }
-            }
-
-            out
-        }
-    }
-}
diff --git a/crates/sparreal-kernel/src/driver/id.rs b/crates/sparreal-kernel/src/driver/id.rs
deleted file mode 100644
index 87df120..0000000
--- a/crates/sparreal-kernel/src/driver/id.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use crate::sync::RwLock;
-use alloc::{
-    collections::btree_map::BTreeMap,
-    string::{String, ToString},
-};
-
-pub use driver_interface::DeviceId;
-
-static MANAGER: RwLock<IdManager> = RwLock::new(IdManager::new());
-
-pub fn device_id_by_node_name(name: &str) -> DeviceId {
-    MANAGER.write().id_by_node_name(name)
-}
-pub fn device_id_next() -> DeviceId {
-    let mut g = MANAGER.write();
-    g.id_iter += 1;
-    g.id_iter.into()
-}
-
-struct IdManager {
-    id_iter: u64,
-    node_name_id_map: BTreeMap<String, DeviceId>,
-}
-
-impl IdManager {
-    const fn new() -> Self {
-        Self {
-            id_iter: 0,
-            node_name_id_map: BTreeMap::new(),
-        }
-    }
-
-    pub fn id_by_node_name(&mut self, name: &str) -> DeviceId {
-        *self
-            .node_name_id_map
-            .entry(name.to_string())
-            .or_insert_with(|| {
-                self.id_iter += 1;
-                self.id_iter.into()
-            })
-    }
-}
diff --git a/crates/sparreal-kernel/src/driver/irq.rs b/crates/sparreal-kernel/src/driver/irq.rs
deleted file mode 100644
index 3f8b55a..0000000
--- a/crates/sparreal-kernel/src/driver/irq.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-pub use driver_interface::irq::*;
-use driver_interface::DriverKind;
-use log::info;
-
-use crate::{platform, struct_driver};
-
-use super::{irq_chip_list, probe_by_register, register_by_kind};
-
-pub(super) async fn init_irq() {
-    for reg in register_by_kind(DriverKind::InteruptChip) {
-        let _ = probe_by_register(reg).await;
-    }
-
-    for chip in irq_chip_list() {
-        info!("CPU {} IRQ init", unsafe { platform::cpu_id_display() });
-        chip.spec.read().current_cpu_setup();
-        info!("IRQ chip init success!");
-    }
-}
-
-struct_driver!(DriverIrqChip, BoxDriver);
diff --git a/crates/sparreal-kernel/src/driver/mod.rs b/crates/sparreal-kernel/src/driver/mod.rs
deleted file mode 100644
index 07ede87..0000000
--- a/crates/sparreal-kernel/src/driver/mod.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use core::{
-    fmt::Display,
-    ptr::{slice_from_raw_parts, slice_from_raw_parts_mut, NonNull},
-};
-
-use alloc::{
-    string::{String, ToString},
-    sync::{Arc, Weak},
-    vec::Vec,
-};
-use device_tree::{get_device_tree, FDTExtend};
-use fdt_parser::Fdt;
-use irq::init_irq;
-use log::info;
-
-use crate::{
-    stdout::{set_stdout, UartWrite},
-    sync::RwLock,
-};
-
-mod container;
-pub mod device_tree;
-mod id;
-mod irq;
-mod timer;
-
-pub use container::*;
-pub use driver_interface::uart;
-pub use id::*;
-pub use irq::DriverIrqChip;
-pub use timer::DriverTimer;
-
-pub async fn init() {
-    init_irq().await;
-    init_stdout().await;
-    info!("Stdout ok!");
-
-    init_all().await;
-}
-
-pub type DriverArc<T> = Arc<RwLock<T>>;
-pub type DriverWeak<T> = Weak<RwLock<T>>;
-
-#[derive(Debug, Clone)]
-pub struct DriverDescriptor {
-    pub id: DeviceId,
-    pub name: String,
-}
-
-#[derive(Clone)]
-pub(crate) struct DriverCommon<T> {
-    pub desc: DriverDescriptor,
-    pub spec: DriverArc<T>,
-}
-impl<T> DriverCommon<T> {
-    pub fn new<N: ToString>(id: DeviceId, name: N, spec: T) -> DriverCommon<T> {
-        Self {
-            desc: DriverDescriptor {
-                id,
-                name: name.to_string(),
-            },
-            spec: Arc::new(RwLock::new(spec)),
-        }
-    }
-}
-
-impl Display for DriverDescriptor {
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "Driver({}) {}", self.id, self.name)
-    }
-}
-
-#[macro_export(local_inner_macros)]
-macro_rules! struct_driver {
-    ($name:ident, $spec:ty) => {
-        #[derive(Clone)]
-        pub struct $name {
-            pub desc: $crate::driver::DriverDescriptor,
-            pub spec: $crate::driver::DriverArc<$spec>,
-        }
-        impl From<$crate::driver::DriverCommon<$spec>> for $name {
-            fn from(value: $crate::driver::DriverCommon<$spec>) -> Self {
-                Self {
-                    desc: value.desc,
-                    spec: value.spec,
-                }
-            }
-        }
-    };
-}
-
-pub unsafe fn move_dtb(src: *const u8, mut dst: NonNull<u8>) -> Option<&'static [u8]> {
-    let fdt = Fdt::from_ptr(NonNull::new_unchecked(src as usize as _)).ok()?;
-    let size = fdt.total_size();
-    let dest = &mut *slice_from_raw_parts_mut(dst.as_mut(), size);
-    let src = &*slice_from_raw_parts(src, size);
-    dest.copy_from_slice(src);
-    Some(dest)
-}
-
-async fn init_stdout() -> Option<()> {
-    let fdt = get_device_tree()?;
-    let chosen = fdt.chosen()?;
-    let stdout = chosen.stdout()?;
-    let node = stdout.node;
-    let caps = node.compatibles().collect::<Vec<_>>();
-
-    let register = register_by_compatible(&caps)?;
-    let config = node.probe_config();
-    let id = config.id;
-    probe(config, register).await?;
-
-    let driver = uart_by_id(id)?;
-
-    let stdout = UartWrite::new(&driver.spec);
-
-    set_stdout(stdout);
-
-    Some(())
-}
-
-async fn init_all() {
-    if let Some(fdt) = get_device_tree() {
-        for node in fdt
-            .all_nodes()
-            .filter(|node| !node.name.contains("memory@"))
-        {
-            probe_by_node(node).await;
-        }
-    }
-}
-
-struct_driver!(DriverUart, uart::BoxDriver);
diff --git a/crates/sparreal-kernel/src/driver/timer.rs b/crates/sparreal-kernel/src/driver/timer.rs
deleted file mode 100644
index 3f0ef8f..0000000
--- a/crates/sparreal-kernel/src/driver/timer.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use core::time::Duration;
-
-use alloc::vec::Vec;
-pub use driver_interface::timer::*;
-
-use crate::{
-    irq::{irq_set_handle, IrqHandle},
-    struct_driver,
-};
-
-use super::CONTAINER;
-
-struct_driver!(DriverTimer, BoxDriver);
-
-#[allow(unused)]
-pub fn list() -> Vec<DriverTimer> {
-    let g = CONTAINER.timer.read();
-    g.values().cloned().collect()
-}
-
-impl DriverTimer {
-    pub fn once_shot(&self, duration: Duration, callback: impl Fn() + 'static) {
-        let mut timer = self.spec.write();
-        let irq = timer.irq_num() as usize;
-        let t = self.clone();
-
-        irq_set_handle(irq, self.desc.id, move |_| {
-            let mut timer = t.spec.write();
-            if timer.read_irq_status() {
-                callback();
-                timer.set_irq_enable(false);
-                IrqHandle::Handled
-            } else {
-                IrqHandle::None
-            }
-        });
-        let ticks = timer.tick_hz() as f64 * duration.as_secs_f64();
-        timer.set_interval(ticks as _);
-        timer.set_enable(true);
-        timer.set_irq_enable(true);
-    }
-}
diff --git a/crates/sparreal-kernel/src/driver_manager/device/descriptor.rs b/crates/sparreal-kernel/src/driver_manager/device/descriptor.rs
new file mode 100644
index 0000000..8f62960
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/device/descriptor.rs
@@ -0,0 +1,28 @@
+use alloc::string::String;
+use core::fmt::Debug;
+
+use super::irq::IrqInfo;
+
+custom_id!(DeviceId, u64);
+custom_id!(DriverId, u64);
+
+#[derive(Default, Debug, Clone)]
+pub struct Descriptor {
+    pub device_id: DeviceId,
+    pub driver_id: DriverId,
+    pub name: String,
+    pub irq: Option<IrqInfo>,
+}
+
+macro_rules! impl_driver_id_for {
+    ($t:ty) => {
+        impl From<$t> for DriverId {
+            fn from(value: $t) -> Self {
+                Self(value as _)
+            }
+        }
+    };
+}
+
+impl_driver_id_for!(usize);
+impl_driver_id_for!(u32);
diff --git a/crates/sparreal-kernel/src/driver_manager/device/irq.rs b/crates/sparreal-kernel/src/driver_manager/device/irq.rs
new file mode 100644
index 0000000..2fde8be
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/device/irq.rs
@@ -0,0 +1,81 @@
+use core::ptr::NonNull;
+
+use alloc::{
+    collections::btree_map::BTreeMap,
+    format,
+    string::{String, ToString},
+    vec::Vec,
+};
+pub use driver_interface::interrupt_controller::Hardware;
+use driver_interface::{DriverRegister, ProbeFnKind, RegAddress, interrupt_controller::IrqConfig};
+use fdt_parser::Fdt;
+
+use super::{super::device::Descriptor, Device, DriverId};
+
+pub fn init_by_fdt(
+    registers: &[DriverRegister],
+    fdt_addr: NonNull<u8>,
+) -> Result<Vec<Device<Hardware>>, String> {
+    let fdt = Fdt::from_ptr(fdt_addr).map_err(|e| format!("{e:?}"))?;
+    let mut out = Vec::with_capacity(registers.len());
+    for r in registers {
+        if let ProbeFnKind::InterruptController(probe) = r.probe {
+            let compa = r
+                .compatibles
+                .iter()
+                .filter_map(|e| if e.is_empty() { None } else { Some(*e) })
+                .collect::<Vec<_>>();
+            for node in fdt.find_compatible(&compa) {
+                let reg = node
+                    .reg()
+                    .ok_or(format!("[{}] has no reg", node.name))?
+                    .map(|reg| RegAddress {
+                        addr: reg.address as _,
+                        size: reg.size,
+                    })
+                    .collect();
+                let mut irq = probe(reg);
+                irq.open()?;
+                let dev = Device::new(
+                    Descriptor {
+                        driver_id: node.phandle().unwrap().as_usize().into(),
+                        name: r.name.to_string(),
+                        ..Default::default()
+                    },
+                    irq,
+                );
+
+                out.push(dev);
+            }
+        }
+    }
+    Ok(out)
+}
+
+pub struct Container(BTreeMap<DriverId, Device<Hardware>>);
+
+impl Container {
+    pub const fn new() -> Self {
+        Self(BTreeMap::new())
+    }
+
+    pub(crate) fn set(&mut self, dev: Device<Hardware>) {
+        self.0.insert(dev.descriptor.driver_id, dev);
+    }
+
+    pub(crate) fn set_list(&mut self, dev_list: Vec<Device<Hardware>>) {
+        for dev in dev_list {
+            self.set(dev);
+        }
+    }
+
+    pub fn list(&self) -> Vec<&Device<Hardware>> {
+        self.0.values().collect()
+    }
+}
+
+#[derive(Default, Debug, Clone)]
+pub struct IrqInfo {
+    pub irq_parent: DriverId,
+    pub cfgs: Vec<IrqConfig>,
+}
diff --git a/crates/sparreal-kernel/src/driver_manager/device/mod.rs b/crates/sparreal-kernel/src/driver_manager/device/mod.rs
new file mode 100644
index 0000000..8064c7b
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/device/mod.rs
@@ -0,0 +1,119 @@
+use alloc::{
+    string::{String, ToString},
+    sync::Arc,
+};
+use core::{
+    cell::UnsafeCell,
+    fmt::Debug,
+    ops::{Deref, DerefMut},
+};
+
+mod descriptor;
+pub mod irq;
+pub mod timer;
+
+pub use descriptor::*;
+use spin::Mutex;
+
+use super::DriverError;
+
+#[derive(Clone)]
+pub struct Device<T> {
+    pub descriptor: Descriptor,
+    lock: Arc<Mutex<Lock>>,
+    data: Arc<UnsafeCell<T>>,
+}
+
+unsafe impl<T> Send for Device<T> {}
+
+impl<T> Debug for Device<T> {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("Device")
+            .field("device_id", &self.descriptor.device_id)
+            .field("driver_id", &self.descriptor.driver_id)
+            .field("name", &self.descriptor.name)
+            .field("irq_configs", &self.descriptor.irq)
+            .finish()
+    }
+}
+
+struct Lock {
+    who_using: Option<String>,
+}
+
+impl<T> Device<T> {
+    pub fn new(descriptor: Descriptor, data: T) -> Self {
+        Device {
+            descriptor,
+            data: Arc::new(UnsafeCell::new(data)),
+            lock: Arc::new(Mutex::new(Lock { who_using: None })),
+        }
+    }
+
+    pub fn try_use_by(&self, who: impl ToString) -> Result<BorrowGuard<T>, DriverError> {
+        let descriptor = self.descriptor.clone();
+        let lock = self.lock.clone();
+        let mut g = self.lock.lock();
+        if let Some(ref who) = g.who_using {
+            return Err(DriverError::UsedByOthers(who.to_string()));
+        }
+        g.who_using = Some(who.to_string());
+        let data = self.data.clone();
+        Ok(BorrowGuard {
+            lock,
+            descriptor,
+            data,
+        })
+    }
+
+    pub fn spin_try_use(&self, who: impl ToString) -> BorrowGuard<T> {
+        loop {
+            if let Ok(g) = self.try_use_by(who.to_string()) {
+                return g;
+            }
+        }
+    }
+
+    /// 强制获取设备
+    ///
+    /// # Safety
+    /// 一般用于中断处理中
+    pub unsafe fn force_use(&self) -> *mut T {
+        self.data.get()
+    }
+}
+
+impl<T: Sync> Deref for Device<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*self.data.get() }
+    }
+}
+
+pub struct BorrowGuard<T> {
+    pub descriptor: Descriptor,
+    lock: Arc<Mutex<Lock>>,
+    data: Arc<UnsafeCell<T>>,
+}
+
+impl<T> Deref for BorrowGuard<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*self.data.get() }
+    }
+}
+
+impl<T> DerefMut for BorrowGuard<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe { &mut *self.data.get() }
+    }
+}
+
+impl<T> Drop for BorrowGuard<T> {
+    fn drop(&mut self) {
+        let mut g = self.lock.lock();
+        g.who_using = None;
+    }
+}
diff --git a/crates/sparreal-kernel/src/driver_manager/device/timer/mod.rs b/crates/sparreal-kernel/src/driver_manager/device/timer/mod.rs
new file mode 100644
index 0000000..1cc4472
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/device/timer/mod.rs
@@ -0,0 +1,79 @@
+use core::ptr::NonNull;
+
+use alloc::{
+    format,
+    string::{String, ToString},
+    vec::Vec,
+};
+use driver_interface::{DriverRegister, ProbeFnKind, timer::*};
+use fdt_parser::Fdt;
+use log::debug;
+
+use crate::prelude::GetIrqConfig;
+
+use super::{Descriptor, Device};
+
+pub struct Container {
+    data: Option<Device<Hardware>>,
+}
+
+impl Container {
+    pub const fn new() -> Self {
+        Self { data: None }
+    }
+
+    pub fn set(&mut self, device: Device<Hardware>) {
+        self.data = Some(device);
+    }
+
+    pub fn get_cpu_timer(&self) -> Option<Device<Timer>> {
+        if let Some(device) = self.data.as_ref() {
+            loop {
+                if let Ok(mut d) = device.try_use_by("cpu") {
+                    let p = d.get_current_cpu();
+                    let mut desc = d.descriptor.clone();
+                    desc.device_id = Default::default();
+                    return Some(Device::new(desc, Timer::new(p)));
+                }
+            }
+        }
+
+        None
+    }
+}
+
+pub fn init_by_fdt(
+    registers: &[DriverRegister],
+    fdt_addr: NonNull<u8>,
+) -> Result<Device<Hardware>, String> {
+    let fdt = Fdt::from_ptr(fdt_addr).map_err(|e| format!("{e:?}"))?;
+    for r in registers {
+        if let ProbeFnKind::Timer(probe) = r.probe {
+            let compa = r
+                .compatibles
+                .iter()
+                .filter_map(|e| if e.is_empty() { None } else { Some(*e) })
+                .collect::<Vec<_>>();
+            for node in fdt.find_compatible(&compa) {
+                let irq = match node.irq_info() {
+                    Some(irq) => irq,
+                    None => continue,
+                };
+
+                let timer = probe(irq.cfgs.clone());
+                debug!("[{}] ok", r.name);
+                let dev = Device::new(
+                    Descriptor {
+                        name: r.name.to_string(),
+                        irq: Some(irq),
+                        ..Default::default()
+                    },
+                    timer,
+                );
+
+                return Ok(dev);
+            }
+        }
+    }
+    Err("No timer found".into())
+}
diff --git a/crates/sparreal-kernel/src/driver_manager/err.rs b/crates/sparreal-kernel/src/driver_manager/err.rs
new file mode 100644
index 0000000..662c6d9
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/err.rs
@@ -0,0 +1,8 @@
+use alloc::string::String;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum DriverError {
+    #[error("Already used by `{0}`")]
+    UsedByOthers(String),
+}
diff --git a/crates/sparreal-kernel/src/driver_manager/id.rs b/crates/sparreal-kernel/src/driver_manager/id.rs
new file mode 100644
index 0000000..194bf28
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/id.rs
@@ -0,0 +1,25 @@
+macro_rules! custom_id {
+    ($name:ident, $target:ty) => {
+        #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+        #[repr(transparent)]
+        pub struct $name($target);
+
+        impl From<$target> for $name {
+            fn from(value: $target) -> Self {
+                Self(value)
+            }
+        }
+
+        impl From<$name> for $target {
+            fn from(value: $name) -> Self {
+                value.0
+            }
+        }
+
+        impl Debug for $name {
+            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+                write!(f, "{:?}", self.0)
+            }
+        }
+    };
+}
diff --git a/crates/sparreal-kernel/src/driver_manager/mod.rs b/crates/sparreal-kernel/src/driver_manager/mod.rs
new file mode 100644
index 0000000..572b317
--- /dev/null
+++ b/crates/sparreal-kernel/src/driver_manager/mod.rs
@@ -0,0 +1,78 @@
+use alloc::{string::String, vec::Vec};
+use core::ptr::NonNull;
+use device::{
+    BorrowGuard,
+    irq::{self},
+    timer,
+};
+use log::warn;
+
+pub use driver_interface::DriverRegister;
+use driver_interface::interrupt_controller;
+use spin::{Mutex, MutexGuard};
+
+#[macro_use]
+mod id;
+
+pub mod device;
+mod err;
+
+pub use err::*;
+
+static MANAGER: Mutex<DeviceManager> = Mutex::new(DeviceManager::new());
+
+pub struct DeviceManager {
+    registers: Vec<DriverRegister>,
+    pub irq_chip: device::irq::Container,
+    pub timer: device::timer::Container,
+}
+
+impl DeviceManager {
+    const fn new() -> Self {
+        Self {
+            registers: Vec::new(),
+            irq_chip: device::irq::Container::new(),
+            timer: device::timer::Container::new(),
+        }
+    }
+}
+
+pub fn init_irq_chips_by_fdt(fdt_addr: NonNull<u8>) -> Result<(), String> {
+    let dev_list = irq::init_by_fdt(&registers(), fdt_addr)?;
+    manager().irq_chip.set_list(dev_list);
+    Ok(())
+}
+
+pub fn init_timer_by_fdt(fdt_addr: NonNull<u8>) -> Result<(), String> {
+    let timer = timer::init_by_fdt(&registers(), fdt_addr)?;
+    manager().timer.set(timer);
+    Ok(())
+}
+
+pub fn manager() -> MutexGuard<'static, DeviceManager> {
+    MANAGER.lock()
+}
+
+pub fn register_drivers(drivers: &[DriverRegister]) {
+    manager().registers.extend(drivers.iter().cloned());
+}
+
+fn registers() -> Vec<DriverRegister> {
+    manager().registers.clone()
+}
+
+pub fn use_irq_chips_by(who: &str) -> Vec<BorrowGuard<interrupt_controller::Hardware>> {
+    manager()
+        .irq_chip
+        .list()
+        .into_iter()
+        .map(|v| v.try_use_by(who))
+        .filter_map(|d| match d {
+            Ok(v) => Some(v),
+            Err(e) => {
+                warn!("{}", e);
+                None
+            }
+        })
+        .collect()
+}
diff --git a/crates/sparreal-kernel/src/executor/mod.rs b/crates/sparreal-kernel/src/executor/mod.rs
deleted file mode 100644
index 6d7bf51..0000000
--- a/crates/sparreal-kernel/src/executor/mod.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// use core::hint::spin_loop;
-// use core::ptr;
-// use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
-
-// use pasts::prelude::*;
-
-// pub fn init_exeutor() {
-//     unsafe {
-//         EXECUTOR = Some(Executor::default());
-//     }
-// }
-
-// fn executor() -> &'static Executor {
-//     unsafe { EXECUTOR.as_ref().unwrap() }
-// }
-
-// pub fn block_on(f: impl Future<Output = ()> + 'static) {
-//     Executor::default().block_on(f);
-// }
-
-// pub fn spawn_boxed(f: impl Future<Output = ()> + 'static) {
-//     executor().spawn_boxed(f)
-// }
-
-// static VTABLE: RawWakerVTable = RawWakerVTable::new(
-//     |_| RawWaker::new(ptr::null(), &VTABLE),
-//     |_| {},
-//     |_| {},
-//     |_| {},
-// );
-
-// pub fn block_on<F: Future>(mut fut: F) -> F::Output {
-//     // safety: we don't move the future after this line.
-//     let mut fut = unsafe { Pin::new_unchecked(&mut fut) };
-
-//     let raw_waker = RawWaker::new(ptr::null(), &VTABLE);
-//     let waker = unsafe { Waker::from_raw(raw_waker) };
-//     let mut cx = Context::from_waker(&waker);
-//     loop {
-//         if let Poll::Ready(res) = fut.as_mut().poll(&mut cx) {
-//             return res;
-//         }
-//         spin_loop();
-//     }
-// }
diff --git a/crates/sparreal-kernel/src/fdt.rs b/crates/sparreal-kernel/src/fdt.rs
deleted file mode 100644
index 472ce2d..0000000
--- a/crates/sparreal-kernel/src/fdt.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-pub use fdt_parser::*;
-
-use crate::driver::device_tree::get_device_tree;
-
-pub fn device_tree<'a>() -> Option<Fdt<'a>> {
-    get_device_tree()
-}
diff --git a/crates/sparreal-kernel/src/globals/mod.rs b/crates/sparreal-kernel/src/globals/mod.rs
new file mode 100644
index 0000000..287e360
--- /dev/null
+++ b/crates/sparreal-kernel/src/globals/mod.rs
@@ -0,0 +1,137 @@
+#![allow(unused)]
+
+use core::{
+    cell::UnsafeCell,
+    ops::Range,
+    sync::atomic::{AtomicBool, Ordering},
+};
+
+use alloc::collections::btree_map::BTreeMap;
+use driver_interface::interrupt_controller::CpuId;
+use percpu::PerCPU;
+
+pub use crate::platform::PlatformInfoKind;
+use crate::{
+    mem::PhysAddr,
+    platform::{self, cpu_list},
+};
+
+mod percpu;
+
+pub struct GlobalVal {
+    pub platform_info: PlatformInfoKind,
+    pub kstack_top: PhysAddr,
+    pub main_memory: Range<PhysAddr>,
+    percpu: BTreeMap<CpuId, percpu::PerCPU>,
+}
+
+struct LazyGlobal {
+    g_ok: AtomicBool,
+    cpu_ok: AtomicBool,
+    g: UnsafeCell<Option<GlobalVal>>,
+}
+
+unsafe impl Sync for LazyGlobal {}
+
+static GLOBAL: LazyGlobal = LazyGlobal::new();
+
+pub fn global_val() -> &'static GlobalVal {
+    global_val_meybeuninit().expect("GlobalVal is not init!")
+}
+
+pub fn global_val_meybeuninit() -> Option<&'static GlobalVal> {
+    if !GLOBAL.g_ok.load(Ordering::SeqCst) {
+        return None;
+    }
+    Some(unsafe { (*GLOBAL.g.get()).as_ref().unwrap() })
+}
+
+impl LazyGlobal {
+    const fn new() -> Self {
+        Self {
+            g_ok: AtomicBool::new(false),
+            cpu_ok: AtomicBool::new(false),
+            g: UnsafeCell::new(None),
+        }
+    }
+}
+
+/// 修改全局变量
+///
+/// # Safty
+/// 只能在其他CPU启动前调用
+pub(crate) unsafe fn edit(f: impl FnOnce(&mut GlobalVal)) {
+    unsafe {
+        let global = (*GLOBAL.g.get()).as_mut().unwrap();
+        f(global);
+    }
+}
+
+unsafe fn get_mut() -> &'static mut GlobalVal {
+    unsafe { (*GLOBAL.g.get()).as_mut().unwrap() }
+}
+
+/// # Safty
+/// 只能在其他CPU启动前调用
+pub(crate) unsafe fn setup(platform_info: PlatformInfoKind) -> Result<(), &'static str> {
+    let main_memory = platform_info
+        .main_memory()
+        .ok_or("No memory in platform info")?;
+
+    let g = GlobalVal {
+        platform_info,
+        kstack_top: main_memory.end,
+        main_memory,
+        percpu: Default::default(),
+    };
+
+    unsafe {
+        GLOBAL.g.get().write(Some(g));
+        GLOBAL.g_ok.store(true, Ordering::SeqCst);
+
+        match &mut get_mut().platform_info {
+            PlatformInfoKind::DeviceTree(fdt) => {
+                fdt.setup()?;
+            }
+        }
+    }
+    Ok(())
+}
+
+/// #Safty
+/// 需要在内存初始化完成之后调用
+pub(crate) unsafe fn setup_percpu() {
+    let cpus = cpu_list();
+    let g = unsafe { get_mut() };
+    for cpu in cpus {
+        let percpu = PerCPU::default();
+        g.percpu.insert(cpu.cpu_id, percpu);
+    }
+    GLOBAL.cpu_ok.store(true, Ordering::SeqCst);
+}
+
+pub(crate) fn cpu_global() -> &'static PerCPU {
+    cpu_global_meybeuninit().expect("CPU global is not init!")
+}
+
+pub(crate) fn cpu_global_meybeuninit() -> Option<&'static PerCPU> {
+    if !GLOBAL.cpu_ok.load(Ordering::SeqCst) {
+        return None;
+    }
+
+    let g = unsafe { get_mut() };
+    Some(g.percpu.get(&platform::cpu_id()).unwrap())
+}
+
+pub(crate) unsafe fn cpu_global_mut() -> &'static mut PerCPU {
+    unsafe { cpu_global_mut_meybeunint().expect("CPU global is not init!") }
+}
+
+pub(crate) unsafe fn cpu_global_mut_meybeunint() -> Option<&'static mut PerCPU> {
+    if !GLOBAL.cpu_ok.load(Ordering::SeqCst) {
+        return None;
+    }
+
+    let g = unsafe { get_mut() };
+    Some(g.percpu.get_mut(&platform::cpu_id()).unwrap())
+}
diff --git a/crates/sparreal-kernel/src/globals/percpu.rs b/crates/sparreal-kernel/src/globals/percpu.rs
new file mode 100644
index 0000000..4946693
--- /dev/null
+++ b/crates/sparreal-kernel/src/globals/percpu.rs
@@ -0,0 +1,7 @@
+use crate::{irq, time::TimerData};
+
+#[derive(Default)]
+pub struct PerCPU {
+    pub irq_chips: irq::CpuIrqChips,
+    pub timer: TimerData,
+}
diff --git a/crates/sparreal-kernel/src/io/mod.rs b/crates/sparreal-kernel/src/io/mod.rs
new file mode 100644
index 0000000..f6380ae
--- /dev/null
+++ b/crates/sparreal-kernel/src/io/mod.rs
@@ -0,0 +1 @@
+pub mod print;
diff --git a/crates/sparreal-kernel/src/io/print.rs b/crates/sparreal-kernel/src/io/print.rs
new file mode 100644
index 0000000..2d665e6
--- /dev/null
+++ b/crates/sparreal-kernel/src/io/print.rs
@@ -0,0 +1,76 @@
+use core::fmt;
+
+use alloc::boxed::Box;
+use spin::Mutex;
+
+use crate::{boot::debug, platform_if::PlatformImpl};
+
+static STDOUT: Mutex<Option<Box<dyn fmt::Write + Send>>> = Mutex::new(None);
+
+pub fn stdout_use_debug() {
+    *STDOUT.lock() = Some(Box::new(debug::DebugWriter {}));
+}
+
+pub fn print(args: fmt::Arguments<'_>) {
+    let mut g = STDOUT.lock();
+
+    if let Some(ref mut writer) = *g {
+        let _ = writer.write_fmt(args);
+    }
+}
+
+pub fn early_dbg(s: &str) {
+    for c in s.bytes() {
+        PlatformImpl::debug_put(c);
+    }
+}
+
+pub fn early_dbgln(s: &str) {
+    early_dbg(s);
+    early_dbg("\r\n");
+}
+
+pub fn early_dbg_hexln(v: u64) {
+    early_dbg_hex(v);
+    early_dbg("\r\n");
+}
+pub fn early_dbg_mem(name: &str, mem: &[u8]) {
+    let range = mem.as_ptr_range();
+    early_dbg_range(name, (range.start as usize)..(range.end as usize));
+}
+pub fn early_dbg_range(name: &str, range: core::ops::Range<usize>) {
+    early_dbg(name);
+    early_dbg(": [");
+    early_dbg_hex(range.start as _);
+    early_dbg(", ");
+    early_dbg_hex(range.end as _);
+    early_dbg(")\r\n");
+}
+
+pub fn early_dbg_hex(v: u64) {
+    const HEX_BUF_SIZE: usize = 20; // 最大长度,包括前缀"0x"和数字
+    let mut hex_buf: [u8; HEX_BUF_SIZE] = [b'0'; HEX_BUF_SIZE];
+    let mut n = v;
+    early_dbg("0x");
+
+    if n == 0 {
+        early_dbg("0");
+        return;
+    }
+    let mut i = 0;
+    while n > 0 {
+        let digit = n & 0xf;
+        let ch = if digit < 10 {
+            b'0' + digit as u8
+        } else {
+            b'a' + (digit - 10) as u8
+        };
+        n >>= 4; // 右移四位
+        hex_buf[i] = ch;
+        i += 1;
+    }
+    let s = &hex_buf[..i];
+    for ch in s.iter().rev() {
+        PlatformImpl::debug_put(*ch);
+    }
+}
diff --git a/crates/sparreal-kernel/src/irq/mod.rs b/crates/sparreal-kernel/src/irq/mod.rs
index 550d3d2..44d6935 100644
--- a/crates/sparreal-kernel/src/irq/mod.rs
+++ b/crates/sparreal-kernel/src/irq/mod.rs
@@ -1,148 +1,242 @@
-use alloc::{collections::btree_map::BTreeMap, sync::Arc, vec::Vec};
-use driver_interface::{irq::Trigger, DeviceId};
-use log::{debug, info, warn};
+use core::{cell::UnsafeCell, error::Error};
+
+use alloc::{boxed::Box, collections::btree_map::BTreeMap, vec::Vec};
+use driver_interface::interrupt_controller::*;
+use log::{debug, error, warn};
+use spin::Mutex;
 
 use crate::{
-    driver::{irq_chip_by_id_or_first, irq_chip_list, DriverIrqChip},
-    platform,
-    sync::RwLock,
+    driver_manager::{
+        self,
+        device::{Device, DriverId},
+    },
+    globals::{self, cpu_global, global_val},
+    platform::{self},
+    platform_if::PlatformImpl,
 };
+pub use driver_manager::device::irq::IrqInfo;
 
-type Handler = Arc<dyn Fn(usize) -> IrqHandle>;
+#[derive(Default)]
+pub struct CpuIrqChips(BTreeMap<DriverId, Chip>);
 
-static IRQ_VECTOR: RwLock<Vector> = RwLock::new(Vector::new());
+pub type IrqHandler = dyn Fn(IrqId) -> IrqHandleResult;
 
-struct VectorPerIrq(BTreeMap<DeviceId, Handler>);
-struct VectorPerCpu(BTreeMap<usize, VectorPerIrq>);
-struct Vector(BTreeMap<usize, VectorPerCpu>);
+pub struct Chip {
+    device: Device<HardwareCPU>,
+    mutex: Mutex<()>,
+    handlers: UnsafeCell<BTreeMap<IrqId, Box<IrqHandler>>>,
+}
 
-unsafe impl Send for Vector {}
-unsafe impl Sync for Vector {}
+unsafe impl Send for Chip {}
+unsafe impl Sync for Chip {}
 
-#[allow(unused)]
-impl Vector {
-    const fn new() -> Self {
-        Self(BTreeMap::new())
-    }
+pub fn enable_all() {
+    PlatformImpl::irq_all_enable();
+}
 
-    fn insert(&mut self, cpu_id: usize, irq_num: usize, dev_id: DeviceId, handler: Handler) {
-        self.0
-            .entry(cpu_id)
-            .or_insert(VectorPerCpu(BTreeMap::new()))
-            .0
-            .entry(irq_num)
-            .or_insert(VectorPerIrq(BTreeMap::new()))
-            .0
-            .insert(dev_id, handler);
+pub(crate) fn init_main_cpu() {
+    match &global_val().platform_info {
+        crate::globals::PlatformInfoKind::DeviceTree(fdt) => {
+            if let Err(e) = driver_manager::init_irq_chips_by_fdt(fdt.get_addr()) {
+                error!("{}", e);
+            }
+        }
     }
 
-    fn remove(&mut self, cpu_id: usize, irq_num: usize, dev_id: DeviceId) {
-        self.0
-            .get_mut(&cpu_id)
-            .and_then(|one| one.0.get_mut(&irq_num))
-            .and_then(|one| one.0.remove(&dev_id));
-    }
+    init_current_cpu();
+}
+
+pub(crate) fn init_current_cpu() {
+    let chip = driver_manager::use_irq_chips_by("Kernel IRQ init");
+    let g = unsafe { globals::cpu_global_mut() };
+
+    for c in chip {
+        let id = c.descriptor.driver_id;
+        let device = c.current_cpu_setup();
+        debug!(
+            "[{}]({id:?}) Init cpu: {:?}",
+            c.descriptor.name,
+            platform::cpu_id(),
+        );
+
+        let device = Device::new(c.descriptor.clone(), device);
 
-    fn get_handle_stack(&self, irq_num: usize) -> Vec<Handler> {
-        let cpu_id = unsafe { platform::cpu_id() } as usize;
-        self.0
-            .get(&cpu_id)
-            .and_then(|map| map.0.get(&irq_num))
-            .map(|map| map.0.values().cloned().collect::<Vec<_>>())
-            .unwrap_or_default()
+        g.irq_chips.0.insert(id, Chip {
+            device,
+            mutex: Mutex::new(()),
+            handlers: UnsafeCell::new(Default::default()),
+        });
     }
 }
 
-fn vector_cpu_set_handle(cpu_id: usize, irq_num: usize, dev_id: DeviceId, handler: Handler) {
-    IRQ_VECTOR.write().insert(cpu_id, irq_num, dev_id, handler);
+pub enum IrqHandleResult {
+    Handled,
+    None,
+}
+
+fn chip(id: DriverId) -> &'static Chip {
+    globals::cpu_global()
+        .irq_chips
+        .0
+        .get(&id)
+        .unwrap_or_else(|| panic!("irq chip {:?} not found", id))
 }
-pub fn irq_set_handle(
-    irq_num: usize,
-    dev_id: DeviceId,
-    handler: impl Fn(usize) -> IrqHandle + 'static,
-) {
-    let handler = Arc::new(handler);
-    vector_cpu_set_handle(unsafe { platform::cpu_id() } as _, irq_num, dev_id, handler);
+
+pub fn fdt_parse_config(
+    irq_parent: DriverId,
+    prop_interrupts: &[u32],
+) -> Result<IrqConfig, Box<dyn Error>> {
+    unsafe { &*chip(irq_parent).device.force_use() }.parse_fdt_config(prop_interrupts)
 }
 
-pub enum IrqHandle {
-    Handled,
-    None,
+pub struct IrqRegister {
+    pub param: IrqParam,
+    pub handler: Box<IrqHandler>,
+    pub priority: Option<usize>,
+    pub cpu_list: Vec<CpuId>,
 }
 
-#[derive(Debug, Clone)]
-pub struct IrqConfig {
-    pub irq: usize,
-    pub trigger: Trigger,
-    pub priority: usize,
-    pub cpu_list: Vec<u64>,
-}
-pub fn irq_setup(irq: usize, dev_id: DeviceId, trigger: Trigger) {
-    //TODO
-    let controller_id = DeviceId::default();
-
-    if let Some(chip) = irq_chip_by_id_or_first(controller_id) {
-        info!(
-            "[{}]Enable irq {} on chip: {} ",
-            dev_id, irq, chip.desc.name
-        );
-        let mut c = chip.spec.write();
+impl IrqRegister {
+    pub fn register(self) {
+        let irq = self.param.cfg.irq;
+        let irq_parent = self.param.irq_chip;
+        debug!("Enable irq {:?} on chip {:?}", irq, irq_parent);
+
+        let chip = chip(irq_parent);
+        chip.register_handle(irq, self.handler);
+
+        let mut c = chip.device.spin_try_use("register irq");
+        if let Some(p) = self.priority {
+            c.set_priority(irq, p);
+        } else {
+            c.set_priority(irq, 0);
+        }
+
+        if !self.cpu_list.is_empty() {
+            c.set_bind_cpu(irq, &self.cpu_list);
+        }
+
+        c.set_trigger(irq, self.param.cfg.trigger);
         c.irq_enable(irq);
-        c.set_priority(irq, 0);
-        c.set_trigger(irq, trigger);
+    }
+
+    pub fn priority(mut self, priority: usize) -> Self {
+        self.priority = Some(priority);
+        self
+    }
+
+    pub fn cpu_list(mut self, cpu_list: Vec<CpuId>) -> Self {
+        self.cpu_list = cpu_list;
+        self
     }
 }
 
-pub fn register_irq(
-    cfg: IrqConfig,
-    dev_id: DeviceId,
-    handler: impl Fn(usize) -> IrqHandle + 'static,
-) {
-    irq_set_handle(cfg.irq, dev_id, handler);
+impl Chip {
+    fn register_handle(&self, irq: IrqId, handle: Box<IrqHandler>) {
+        let g = NoIrqGuard::new();
+        let gm = self.mutex.lock();
+        unsafe { &mut *self.handlers.get() }.insert(irq, handle);
+        drop(gm);
+        drop(g);
+    }
 
-    //TODO
-    let controller_id = DeviceId::default();
+    fn unregister_handle(&self, irq: IrqId) {
+        let g = NoIrqGuard::new();
+        let gm = self.mutex.lock();
+        unsafe { &mut *self.handlers.get() }.remove(&irq);
+        drop(gm);
+        drop(g);
+    }
 
-    if let Some(chip) = irq_chip_by_id_or_first(controller_id) {
-        info!(
-            "[{}]Enable irq {} on chip: {} ",
-            dev_id, cfg.irq, chip.desc.name
-        );
-        let mut c = chip.spec.write();
-        c.irq_enable(cfg.irq);
-        c.set_priority(cfg.irq, cfg.priority);
-        c.set_trigger(cfg.irq, cfg.trigger);
+    fn handle_irq(&self) -> Option<()> {
+        let chip = unsafe { &mut *self.device.force_use() };
+
+        let irq = chip.get_and_acknowledge_interrupt()?;
+
+        if let Some(handler) = unsafe { &mut *self.handlers.get() }.get(&irq) {
+            let res = (handler)(irq);
+            if let IrqHandleResult::None = res {
+                return Some(());
+            }
+        } else {
+            warn!("IRQ {:?} no handler", irq);
+        }
+        chip.end_interrupt(irq);
+        Some(())
+    }
+
+    fn pin_to_id(&self, pin: usize) -> Result<IrqId, Box<dyn Error>> {
+        let chip = unsafe { &*self.device.force_use() };
+        chip.irq_pin_to_id(pin)
     }
 }
 
-fn get_chip() -> Option<DriverIrqChip> {
-    irq_chip_list().first().cloned()
+pub struct NoIrqGuard {
+    is_enabled: bool,
 }
 
-pub fn handle_irq() {
-    if let Some(chip) = get_chip() {
-        let c = chip.spec.read();
+impl NoIrqGuard {
+    pub fn new() -> Self {
+        let is_enabled = PlatformImpl::irq_all_is_enabled();
+        PlatformImpl::irq_all_disable();
+        Self { is_enabled }
+    }
+}
 
-        let irq_id = c.get_and_acknowledge_interrupt();
-        if let Some(irq_id) = irq_id {
-            handle_irq_by_id(irq_id);
-            c.end_interrupt(irq_id);
+impl Default for NoIrqGuard {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Drop for NoIrqGuard {
+    fn drop(&mut self) {
+        if self.is_enabled {
+            enable_all();
         }
     }
 }
 
-fn handle_irq_by_id(irq_id: usize) {
-    debug!("irq {}", irq_id);
-    let stack = { IRQ_VECTOR.read().get_handle_stack(irq_id) };
+pub fn handle_irq() {
+    for chip in cpu_global().irq_chips.0.values() {
+        chip.handle_irq();
+    }
+}
 
-    for handler in stack {
-        match handler(irq_id) {
-            IrqHandle::Handled => {
-                return;
-            }
-            IrqHandle::None => {}
+#[derive(Debug, Clone)]
+pub struct IrqParam {
+    pub irq_chip: DriverId,
+    pub cfg: IrqConfig,
+}
+
+impl IrqParam {
+    pub fn new_pin(pin: usize, irq_chip: DriverId) -> Result<Self, Box<dyn Error>> {
+        let chip = chip(irq_chip);
+        let irq_id = chip.pin_to_id(pin)?;
+        Ok(Self {
+            irq_chip,
+            cfg: IrqConfig {
+                irq: irq_id,
+                trigger: Trigger::LevelLow,
+            },
+        })
+    }
+
+    pub fn register_builder(
+        &self,
+        handler: impl Fn(IrqId) -> IrqHandleResult + 'static,
+    ) -> IrqRegister {
+        IrqRegister {
+            param: self.clone(),
+            handler: Box::new(handler),
+            priority: None,
+            cpu_list: Vec::new(),
         }
     }
+}
 
-    warn!("Irq {} not handled", irq_id);
+pub fn unregister_irq(irq: IrqId) {
+    for chip in cpu_global().irq_chips.0.values() {
+        chip.unregister_handle(irq);
+    }
 }
diff --git a/crates/sparreal-kernel/src/kernel.rs b/crates/sparreal-kernel/src/kernel.rs
deleted file mode 100644
index 5a1a824..0000000
--- a/crates/sparreal-kernel/src/kernel.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-use core::ptr::NonNull;
-
-use driver_interface::Register;
-use log::*;
-
-use page_table_generic::{AccessSetting, CacheSetting};
-use spin_on::spin_on;
-
-use crate::{
-    driver::{self, device_tree::set_dtb_addr},
-    logger::KLogger,
-    mem::{self, *},
-    platform::{self, app_main},
-    println,
-    stdout::{self, EarlyDebugWrite},
-};
-
-/// 初始化日志和内存
-///
-/// # Safety
-///
-/// 1. BSS 应当清零。
-/// 2. 若有MMU,应当已开启,且虚拟地址与代码段映射一致。
-pub unsafe fn init_log_and_memory(kconfig: &KernelConfig) {
-    set_dtb_addr(kconfig.dtb_addr);
-    let _ = log::set_logger(&KLogger);
-    log::set_max_level(LevelFilter::Trace);
-    stdout::set_stdout(EarlyDebugWrite {});
-    info!("Logger initialized.");
-
-    mem::init(kconfig);
-
-    let version = env!("CARGO_PKG_VERSION");
-    println!("Welcome to sparreal\nVersion: {version}");
-    platform::print_system_info();
-}
-
-/// 注册驱动
-pub fn driver_register_append(registers: impl IntoIterator<Item = Register>) {
-    driver::register_append(registers);
-}
-
-/// 运行内核主逻辑
-///
-/// # Safety
-///
-/// 需在 [init_log_and_memory] 之后执行,[run] 之前可用 [driver_register_append] 注册驱动。
-pub unsafe fn run() -> ! {
-    spin_on(async {
-        driver::init().await;
-    });
-    platform::irqs_enable();
-    app_main();
-    println!("Waiting for interrupt...");
-    loop {
-        platform::wait_for_interrupt();
-    }
-}
-
-#[repr(C)]
-#[derive(Debug, Clone, Copy)]
-pub struct MemoryRange {
-    pub start: Phys<u8>,
-    pub size: usize,
-}
-
-impl MemoryRange {
-    #[allow(clippy::new_without_default)]
-    pub const fn new() -> Self {
-        Self {
-            start: Phys::new(),
-            size: 0,
-        }
-    }
-}
-
-#[repr(C)]
-/// 内核配置
-#[derive(Clone)]
-pub struct KernelConfig {
-    /// 启动配置
-    pub boot_info: BootConfig,
-    /// 栈顶
-    pub stack_top: Phys<u8>,
-    /// 设备树地址
-    pub dtb_addr: Option<NonNull<u8>>,
-}
-
-#[derive(Clone)]
-pub struct BootConfig {
-    /// Kernel 所在的内存
-    pub main_memory: MemoryRange,
-    /// 已使用的内存
-    pub main_memory_heap_offset: usize,
-    /// 每核 Kernel sp 大小
-    pub hart_stack_size: usize,
-    /// 需要提前map的内存
-    pub reserved_memory: [Option<MemoryReservedRange>; 24],
-    /// 物理内存和虚拟内存的偏移
-    pub va_offset: usize,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct MemoryReservedRange {
-    pub name: &'static str,
-    pub start: Phys<u8>,
-    pub size: usize,
-    pub access: AccessSetting,
-    pub cache: CacheSetting,
-}
diff --git a/crates/sparreal-kernel/src/lang_items.rs b/crates/sparreal-kernel/src/lang_items.rs
index ad7137e..45c1358 100644
--- a/crates/sparreal-kernel/src/lang_items.rs
+++ b/crates/sparreal-kernel/src/lang_items.rs
@@ -2,14 +2,10 @@ use core::panic::PanicInfo;
 
 use log::error;
 
-use crate::platform;
+use crate::platform::shutdown;
 
 #[panic_handler]
 fn panic(info: &PanicInfo) -> ! {
-    error!("{info}");
-
-    unsafe {
-        platform::shutdown();
-    };
-    unreachable!()
+    error!("kernel panic: {:?}", info);
+    shutdown()
 }
diff --git a/crates/sparreal-kernel/src/lib.rs b/crates/sparreal-kernel/src/lib.rs
index e3de2bc..2b307b9 100644
--- a/crates/sparreal-kernel/src/lib.rs
+++ b/crates/sparreal-kernel/src/lib.rs
@@ -1,45 +1,25 @@
 #![no_std]
-#![feature(trait_upcasting)]
-#![allow(clippy::missing_safety_doc)]
+#![feature(linkage)]
+#![feature(fn_align)]
 
 extern crate alloc;
 
 pub mod __export;
-pub mod driver;
-pub mod executor;
-pub mod fdt;
+pub mod boot;
+mod driver_manager;
+pub mod globals;
+pub mod io;
+
+pub mod async_std;
 pub mod irq;
-pub mod kernel;
-#[cfg(all(target_os = "none", not(test)))]
 mod lang_items;
-pub mod logger;
+mod logger;
 pub mod mem;
 pub mod platform;
+pub mod platform_if;
 pub mod prelude;
-pub mod stdout;
-pub mod sync;
+pub mod task;
 pub mod time;
-pub mod trap;
-pub mod util;
-
-pub use kernel::{KernelConfig, MemoryRange};
-pub use mem::PhysAddr;
-pub use platform::Platform;
-pub use sparreal_macros::entry;
-
-#[macro_export]
-macro_rules! print {
-    ($($arg:tt)*) => {{
-        $crate::__export::print(format_args!($($arg)*));
-    }};
-}
 
-#[macro_export]
-macro_rules! println {
-    () => {
-        $crate::print!("\n")
-    };
-    ($($arg:tt)*) => {{
-        $crate::__export::print(format_args!("{}\r\n", format_args!($($arg)*)));
-    }};
-}
+pub use driver_interface;
+pub use mem::Address;
diff --git a/crates/sparreal-kernel/src/logger.rs b/crates/sparreal-kernel/src/logger.rs
index 5476f28..d2a347c 100644
--- a/crates/sparreal-kernel/src/logger.rs
+++ b/crates/sparreal-kernel/src/logger.rs
@@ -1,8 +1,6 @@
-use ansi_rgb::{red, yellow, Foreground};
+use ansi_rgb::{Foreground, red, yellow};
 use log::{Level, Log};
-use rgb::{Rgb, RGB8};
-
-use crate::stdout;
+use rgb::{RGB8, Rgb};
 
 fn level_to_rgb(level: Level) -> RGB8 {
     match level {
@@ -24,24 +22,6 @@ fn level_icon(level: Level) -> &'static str {
     }
 }
 
-macro_rules! format_record {
-    ($record:expr, $d: expr) => {{
-        format_args!(
-            "{}",
-            format_args!(
-                "{} {:.3?} [{path}:{line}] {args}\r\n",
-                // "{} [{path}:{line}] {args}\n",
-                level_icon($record.level()),
-                $d,
-                path = $record.target(),
-                line = $record.line().unwrap_or(0),
-                args = $record.args()
-            )
-            .fg(level_to_rgb($record.level()))
-        )
-    }};
-}
-
 pub struct KLogger;
 
 impl Log for KLogger {
@@ -51,9 +31,35 @@ impl Log for KLogger {
 
     fn log(&self, record: &log::Record) {
         if self.enabled(record.metadata()) {
+            let level = record.level();
+            let line = record.line().unwrap_or(0);
+            let path = record.target();
+            let args = record.args();
+
             let duration = crate::time::since_boot();
-            stdout::print(format_record!(record, duration));
+            crate::__export::print(format_args!(
+                "{}",
+                format_args!(
+                    "{} {duration:<10.3?} [{path}:{line}] {args}\r\n",
+                    level_icon(level),
+                )
+                .fg(level_to_rgb(level))
+            ));
         }
     }
     fn flush(&self) {}
 }
+
+#[macro_export]
+macro_rules! print {
+    ($($arg:tt)*) => {
+        $crate::__export::print(format_args!($($arg)*));
+    };
+}
+
+#[macro_export]
+macro_rules! println {
+    ($($arg:tt)*) => {
+        $crate::print!("{}\r\n", format_args!($($arg)*));
+    };
+}
diff --git a/crates/sparreal-kernel/src/mem/addr.rs b/crates/sparreal-kernel/src/mem/addr.rs
index 6e2063c..4f24b33 100644
--- a/crates/sparreal-kernel/src/mem/addr.rs
+++ b/crates/sparreal-kernel/src/mem/addr.rs
@@ -1,40 +1,101 @@
-use core::{
-    fmt::Display,
-    ops::{Add, Sub},
-};
+use core::fmt::Display;
+use core::marker::PhantomData;
+use core::ops::{Add, Sub};
+use core::ptr::NonNull;
 
-#[derive(Clone, Copy)]
+use super::va_offset_now;
+
+#[derive(Debug, Clone, Copy)]
+pub struct Address {
+    pub cpu: usize,
+    pub virt: Option<usize>,
+    pub bus: Option<u64>,
+}
+
+impl Address {
+    pub fn new(cpu: usize, virt: Option<*mut u8>, bus: Option<u64>) -> Self {
+        Self {
+            cpu,
+            virt: virt.map(|s| s as usize),
+            bus,
+        }
+    }
+
+    pub fn as_ptr(&self) -> *const u8 {
+        match self.virt {
+            Some(virt) => virt as *const u8,
+            None => self.cpu as *const u8,
+        }
+    }
+
+    pub fn bus(&self) -> u64 {
+        match self.bus {
+            Some(bus) => bus,
+            None => self.cpu as _,
+        }
+    }
+
+    pub fn physical(&self) -> usize {
+        self.cpu
+    }
+}
+
+impl Add<usize> for Address {
+    type Output = Self;
+
+    fn add(self, rhs: usize) -> Self::Output {
+        Self {
+            cpu: self.cpu + rhs,
+            virt: self.virt.map(|s| s + rhs),
+            bus: self.bus.map(|s| s + rhs as u64),
+        }
+    }
+}
+
+impl Sub<usize> for Address {
+    type Output = Self;
+
+    fn sub(self, rhs: usize) -> Self::Output {
+        Self {
+            cpu: self.cpu - rhs,
+            virt: self.virt.map(|s| s - rhs),
+            bus: self.bus.map(|s| s - rhs as u64),
+        }
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, PartialOrd)]
 #[repr(transparent)]
-pub struct Virt<T>(*const T);
+pub struct Virt<T>(usize, PhantomData<T>);
 unsafe impl<T> Send for Virt<T> {}
-unsafe impl<T> Sync for Virt<T> {}
 
 impl<T> From<*const T> for Virt<T> {
     fn from(value: *const T) -> Self {
-        Self(value)
+        Self(value as _, PhantomData)
     }
 }
 impl<T> From<*mut T> for Virt<T> {
     fn from(value: *mut T) -> Self {
-        Self(value as *const T)
+        Self(value as _, PhantomData)
     }
 }
+impl<T> From<NonNull<T>> for Virt<T> {
+    fn from(value: NonNull<T>) -> Self {
+        Self(value.as_ptr() as _, PhantomData)
+    }
+}
+
 impl<T> From<Virt<T>> for *const T {
     fn from(value: Virt<T>) -> Self {
-        value.0
+        value.0 as *const T
     }
 }
 
-pub type VirtAddr<T = u8> = Virt<T>;
+pub type VirtAddr = Virt<u8>;
 
 impl<T> Virt<T> {
-    #[allow(clippy::new_without_default)]
     pub const fn new() -> Self {
-        Self(0 as *const T)
-    }
-
-    pub fn convert_to_phys(self, va_offset: usize) -> Phys<T> {
-        Phys::from(self.0 as usize - va_offset)
+        Self(0, PhantomData)
     }
 
     pub fn as_mut_ptr(self) -> *mut T {
@@ -42,65 +103,71 @@ impl<T> Virt<T> {
     }
 
     pub fn as_usize(self) -> usize {
-        self.0 as usize
+        self.0
+    }
+}
+
+impl<T> Default for Virt<T> {
+    fn default() -> Self {
+        Self::new()
     }
 }
 
 impl<T> From<usize> for Virt<T> {
     fn from(value: usize) -> Self {
-        Self(value as *const T)
+        Self(value, PhantomData)
     }
 }
 impl<T> From<Virt<T>> for usize {
     fn from(value: Virt<T>) -> Self {
-        value.0 as usize
+        value.0
     }
 }
-impl<T> From<Phys<T>> for usize {
-    fn from(value: Phys<T>) -> Self {
-        value.0 as usize
+
+impl<T> From<PhysAddr> for Virt<T> {
+    fn from(value: PhysAddr) -> Self {
+        Self((value.0 + va_offset_now()) as _, PhantomData)
+    }
+}
+
+impl From<PhysAddr> for usize {
+    fn from(value: PhysAddr) -> Self {
+        value.0
     }
 }
-#[derive(Clone, Copy)]
-#[repr(transparent)]
-pub struct Phys<T>(*const T);
 
-impl<T> PartialEq for Phys<T> {
-    fn eq(&self, other: &Self) -> bool {
-        core::ptr::eq(self.0, other.0)
+impl<T> From<Virt<T>> for PhysAddr {
+    fn from(value: Virt<T>) -> Self {
+        Self(value.as_usize() - va_offset_now())
     }
 }
 
-unsafe impl<T> Send for Phys<T> {}
-unsafe impl<T> Sync for Phys<T> {}
+#[derive(Default, Clone, Copy, PartialEq, PartialOrd)]
+#[repr(transparent)]
+pub struct PhysAddr(usize);
 
-pub type PhysAddr<T = u8> = Phys<T>;
+unsafe impl Send for PhysAddr {}
 
-impl<T> From<usize> for Phys<T> {
+impl From<usize> for PhysAddr {
     fn from(value: usize) -> Self {
         Self(value as _)
     }
 }
-impl<T> From<*const T> for Phys<T> {
-    fn from(value: *const T) -> Self {
-        Self(value as _)
-    }
-}
-impl<T> Phys<T> {
-    #[allow(clippy::new_without_default)]
+
+impl PhysAddr {
     pub const fn new() -> Self {
-        Self(0 as *const T)
+        Self(0)
     }
 
     pub fn as_usize(&self) -> usize {
-        self.0 as usize
+        self.0
     }
 }
 
-impl<T> Sub<Phys<T>> for Phys<T> {
+impl Sub<PhysAddr> for PhysAddr {
     type Output = usize;
 
-    fn sub(self, rhs: Phys<T>) -> Self::Output {
+    fn sub(self, rhs: PhysAddr) -> Self::Output {
         self.as_usize() - rhs.as_usize()
     }
 }
@@ -160,7 +227,7 @@ pub const fn align_up(addr: usize, align: usize) -> usize {
     (addr + align - 1) & !(align - 1)
 }
 
-impl<T> Add<usize> for Phys<T> {
+impl Add<usize> for PhysAddr {
     type Output = Self;
 
     fn add(self, rhs: usize) -> Self::Output {
@@ -176,24 +243,32 @@ impl<T> Sub<usize> for Virt<T> {
     }
 }
 
-impl<T> Display for Phys<T> {
+impl<T> Sub<Virt<T>> for Virt<T> {
+    type Output = usize;
+
+    fn sub(self, rhs: Virt<T>) -> Self::Output {
+        self.as_usize() - rhs.as_usize()
+    }
+}
+
+impl Display for PhysAddr {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "PA({:p})", self.0)
+        write!(f, "{:#x}", self.0)
     }
 }
 impl<T> Display for Virt<T> {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "VA({:p})", self.0)
+        write!(f, "{:#x}", self.0)
     }
 }
 
-impl<T> core::fmt::Debug for Phys<T> {
+impl core::fmt::Debug for PhysAddr {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "PA({:p})", self.0)
+        write!(f, "{:#x}", self.0)
     }
 }
 impl<T> core::fmt::Debug for Virt<T> {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(f, "VA({:p})", self.0)
+        write!(f, "{:#x}", self.0)
     }
 }
diff --git a/crates/sparreal-kernel/src/mem/cache.rs b/crates/sparreal-kernel/src/mem/cache.rs
new file mode 100644
index 0000000..0f0b0b5
--- /dev/null
+++ b/crates/sparreal-kernel/src/mem/cache.rs
@@ -0,0 +1,29 @@
+use core::ptr::NonNull;
+
+use dma_api::Impl;
+
+use crate::platform_if::{CacheOp, PlatformImpl};
+
+use super::{PhysAddr, VirtAddr};
+
+struct DMAImpl;
+
+impl Impl for DMAImpl {
+    fn map(addr: NonNull<u8>, _size: usize, _direction: dma_api::Direction) -> u64 {
+        let vaddr = VirtAddr::from(addr);
+        let paddr = PhysAddr::from(vaddr);
+        paddr.as_usize() as _
+    }
+
+    fn unmap(_addr: NonNull<u8>, _size: usize) {}
+
+    fn flush(addr: NonNull<u8>, size: usize) {
+        PlatformImpl::dcache_range(CacheOp::Clean, addr.as_ptr() as _, size);
+    }
+
+    fn invalidate(addr: NonNull<u8>, size: usize) {
+        PlatformImpl::dcache_range(CacheOp::Invalidate, addr.as_ptr() as _, size);
+    }
+}
+
+dma_api::set_impl!(DMAImpl);
diff --git a/crates/sparreal-kernel/src/mem/dma.rs b/crates/sparreal-kernel/src/mem/dma.rs
deleted file mode 100644
index dd95612..0000000
--- a/crates/sparreal-kernel/src/mem/dma.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-use core::{alloc::Layout, ptr::NonNull};
-
-use super::{Virt, VirtToPhys};
-
-/// Allocates **coherent** memory that meets Direct Memory Access (DMA) requirements.
-///
-/// This function allocates a block of memory through the global allocator. The memory pages must be contiguous, undivided, and have consistent read and write access.
-///
-/// - `layout`: The memory layout, which describes the size and alignment requirements of the requested memory.
-///
-/// Returns an [`DMAInfo`] structure containing details about the allocated memory, such as the starting address and size. If it's not possible to allocate memory meeting the criteria, returns [`None`].
-/// # Safety
-/// This function is unsafe because it directly interacts with the global allocator, which can potentially cause memory leaks or other issues if not used correctly.
-pub unsafe fn alloc_coherent(layout: Layout) -> Option<DMAMem> {
-    let cpu_addr = NonNull::new(alloc::alloc::alloc(layout))?;
-    let bus_addr = Virt::<u8>::from(cpu_addr.as_ptr() as usize);
-    let bus_addr = bus_addr.to_phys();
-    let bus_addr: usize = bus_addr.into();
-
-    Some(DMAMem {
-        cpu_addr,
-        bus_addr: BusAddr(bus_addr as _),
-    })
-}
-
-/// Frees coherent memory previously allocated.
-///
-/// This function releases the memory block that was previously allocated and marked as coherent. It ensures proper deallocation and management of resources associated with the memory block.
-///
-/// - `dma_info`: An instance of [`DMAInfo`] containing the details of the memory block to be freed, such as its starting address and size.
-/// # Safety
-/// This function is unsafe because it directly interacts with the global allocator, which can potentially cause memory leaks or other issues if not used correctly.
-pub unsafe fn dealloc_coherent(dma: DMAMem, layout: Layout) {
-    alloc::alloc::dealloc(dma.cpu_addr.as_ptr(), layout);
-}
-
-/// Represents information related to a DMA operation.
-#[derive(Debug, Clone, Copy)]
-pub struct DMAMem {
-    /// The `cpu_addr` field represents the address at which the CPU accesses this memory region.
-    /// This address is a virtual memory address used by the CPU to access memory.
-    pub cpu_addr: NonNull<u8>,
-    /// The `bus_addr` field represents the physical address of this memory region on the bus.
-    /// The DMA controller uses this address to directly access memory.
-    pub bus_addr: BusAddr,
-}
-
-/// A bus memory address.
-///
-/// It's a wrapper type around an [`u64`].
-#[repr(transparent)]
-#[derive(Copy, Clone, Default, Ord, PartialOrd, Eq, PartialEq)]
-pub struct BusAddr(u64);
-
-impl BusAddr {
-    /// Converts an [`u64`] to a physical address.
-    pub const fn new(addr: u64) -> Self {
-        Self(addr)
-    }
-
-    /// Converts the address to an [`u64`].
-    pub const fn as_u64(self) -> u64 {
-        self.0
-    }
-}
-
-impl From<u64> for BusAddr {
-    fn from(value: u64) -> Self {
-        Self::new(value)
-    }
-}
-
-impl core::fmt::Debug for BusAddr {
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        f.debug_tuple("BusAddr")
-            .field(&format_args!("{:#X}", self.0))
-            .finish()
-    }
-}
diff --git a/crates/sparreal-kernel/src/mem/mmu/boot.rs b/crates/sparreal-kernel/src/mem/mmu/boot.rs
deleted file mode 100644
index f55c0d7..0000000
--- a/crates/sparreal-kernel/src/mem/mmu/boot.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-use core::ptr::NonNull;
-
-use page_table_generic::{err::PagingResult, Access, AccessSetting, CacheSetting, MapConfig};
-
-use crate::{dbg, dbg_hex, dbg_hexln, dbgln, kernel::BootConfig};
-
-use super::{table::PageTableRef, PageAllocator};
-
-pub fn new_boot_table(config: BootConfig) -> PagingResult<usize> {
-    let heap_size =
-        (config.main_memory.size - config.main_memory_heap_offset - config.hart_stack_size) / 2;
-    let heap_start = config.main_memory.start + config.main_memory_heap_offset + heap_size;
-
-    let mut access = unsafe {
-        PageAllocator::new(
-            NonNull::new_unchecked(heap_start.as_usize() as _),
-            heap_size,
-        )
-    };
-
-    let mut table = PageTableRef::create_empty(&mut access)?;
-    dbg_hexln!(config.va_offset);
-
-    unsafe {
-        map_boot_region(
-            "main memory",
-            &mut table,
-            config.main_memory.start.into(),
-            config.main_memory.size,
-            AccessSetting::Read | AccessSetting::Write | AccessSetting::Execute,
-            CacheSetting::Normal,
-            &mut access,
-            config.va_offset,
-        )?;
-
-        for rsv in config.reserved_memory.into_iter().flatten() {
-            map_boot_region(
-                rsv.name,
-                &mut table,
-                rsv.start.into(),
-                rsv.size,
-                rsv.access,
-                rsv.cache,
-                &mut access,
-                config.va_offset,
-            )?;
-        }
-    }
-    Ok(table.paddr())
-}
-
-#[allow(clippy::too_many_arguments)]
-unsafe fn map_boot_region(
-    name: &str,
-    table: &mut PageTableRef<'_>,
-    paddr: usize,
-    size: usize,
-    access_setting: AccessSetting,
-    cache_setting: CacheSetting,
-    access: &mut impl Access,
-    va_offset: usize,
-) -> PagingResult<()> {
-    map_boot_region_once(
-        name,
-        table,
-        paddr,
-        paddr,
-        size,
-        access_setting,
-        cache_setting,
-        access,
-    )?;
-
-    map_boot_region_once(
-        name,
-        table,
-        paddr + va_offset,
-        paddr,
-        size,
-        access_setting,
-        cache_setting,
-        access,
-    )?;
-
-    Ok(())
-}
-
-#[allow(clippy::too_many_arguments)]
-unsafe fn map_boot_region_once(
-    name: &str,
-    table: &mut PageTableRef<'_>,
-    vaddr: usize,
-    paddr: usize,
-    size: usize,
-    access_setting: AccessSetting,
-    cache_setting: CacheSetting,
-    access: &mut impl Access,
-) -> PagingResult<()> {
-    let name_count = name.chars().count();
-    let name_space = 12usize;
-    let space = name_space.saturating_sub(name_count);
-    dbg!("Map [");
-    dbg!(name);
-    for _ in 0..space {
-        dbg!(" ");
-    }
-    dbg!("]: [");
-    dbg_hex!(vaddr);
-    dbg!(", ");
-    dbg_hex!(vaddr + size);
-    dbg!(") -> [");
-    dbg_hex!(paddr);
-    dbg!(", ");
-    dbg_hex!(paddr + size);
-    dbgln!(")");
-
-    table.map_region(
-        MapConfig::new(vaddr as _, paddr, access_setting, cache_setting),
-        size,
-        true,
-        access,
-    )
-}
diff --git a/crates/sparreal-kernel/src/mem/mmu/mod.rs b/crates/sparreal-kernel/src/mem/mmu/mod.rs
index e79996f..dec1ce9 100644
--- a/crates/sparreal-kernel/src/mem/mmu/mod.rs
+++ b/crates/sparreal-kernel/src/mem/mmu/mod.rs
@@ -1,114 +1,183 @@
-use core::ptr::NonNull;
+use core::{alloc::Layout, ops::Range, ptr::NonNull};
 
-use log::debug;
-use page_table_generic::{err::PagingResult, AccessSetting, CacheSetting, MapConfig};
+use buddy_system_allocator::Heap;
+use page_table_generic::err::PagingError;
+pub use page_table_generic::{AccessSetting, CacheSetting, MapConfig};
 
-mod boot;
-mod table;
+mod paging;
 
-use super::*;
-use crate::platform;
-pub use boot::*;
-use table::{get_kernal_table, PageTableRef};
+pub use paging::iomap;
 
-struct BootInfo {
-    va_offset: usize,
-}
+use crate::{
+    globals::global_val,
+    io::print::{early_dbg, early_dbg_hex, early_dbg_hexln, early_dbg_range, early_dbgln},
+    platform_if::MMUImpl,
+};
+
+use paging::PageTableRef;
+pub use paging::init_table;
+
+use super::{Align, va_offset};
+
+struct PageHeap(Heap<32>);
 
-#[link_section = ".data.boot"]
-static mut BOOT_INFO: BootInfo = BootInfo { va_offset: 0 };
+impl page_table_generic::Access for PageHeap {
+    fn va_offset(&self) -> usize {
+        0
+    }
+
+    unsafe fn alloc(&mut self, layout: Layout) -> Option<NonNull<u8>> {
+        self.0.alloc(layout).ok()
+    }
 
-pub(super) unsafe fn set_va_offset(offset: usize) {
-    BOOT_INFO.va_offset = offset;
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: core::alloc::Layout) {
+        self.0.dealloc(ptr, layout);
+    }
 }
 
-pub fn va_offset() -> usize {
-    unsafe { BOOT_INFO.va_offset }
+pub struct BootMemoryRegion {
+    pub name: &'static str,
+    pub range: Range<usize>,
+    pub access: AccessSetting,
+    pub cache: CacheSetting,
 }
+pub fn new_boot_table(rsv: &[BootMemoryRegion]) -> Result<usize, &'static str> {
+    let debugcon = global_val().platform_info.debugcon();
+
+    let mut access = PageHeap(Heap::empty());
+    let memory = &global_val().main_memory;
+    let size = (memory.end - memory.start) / 2;
+    let start = memory.start + size;
+    let end = memory.end;
+
+    early_dbg_range("page table allocator", start.as_usize()..end.as_usize());
+    unsafe { access.0.add_to_heap(start.as_usize(), end.as_usize()) };
+
+    let mut table =
+        PageTableRef::create_empty(&mut access).map_err(|_| "page table allocator no memory")?;
+
+    let va_offset = va_offset();
+
+    for memory in global_val().platform_info.memorys() {
+        map_region(
+            &mut table,
+            va_offset,
+            &BootMemoryRegion {
+                name: "memory",
+                range: memory.start.as_usize()..memory.end.as_usize(),
+                access: AccessSetting::Read | AccessSetting::Write | AccessSetting::Execute,
+                cache: CacheSetting::Normal,
+            },
+            &mut access,
+        );
+    }
 
-pub(crate) unsafe fn init_table(
-    kconfig: &KernelConfig,
-    access: &mut PageAllocatorRef,
-) -> PagingResult<()> {
-    debug!("Initializing page table...");
-
-    let mut table = PageTableRef::create_empty(access)?;
-
-    for memory in kconfig.boot_info.reserved_memory.into_iter().flatten() {
-        let virt = memory.start.to_virt();
-        let size = memory.size.align_up(BYTES_1M * 2);
-        debug!(
-            "Map reserved memory region {:#X} -> {:#X}  size: {:#X}",
-            virt.as_usize(),
-            memory.start.as_usize(),
-            size,
+    if let Some(con) = debugcon {
+        let start = con.addr.align_down(0x1000).as_usize();
+
+        map_region(
+            &mut table,
+            va_offset,
+            &BootMemoryRegion {
+                name: "debugcon",
+                range: start..start + 0x1000,
+                access: AccessSetting::Read | AccessSetting::Write | AccessSetting::Execute,
+                cache: CacheSetting::Device,
+            },
+            &mut access,
         );
+    }
 
-        table.map_region(
-            MapConfig::new(
-                virt.as_mut_ptr(),
-                memory.start.as_usize(),
-                memory.access,
-                memory.cache,
-            ),
-            size,
-            true,
-            access,
-        )?;
+    for region in rsv {
+        map_region(&mut table, va_offset, region, &mut access);
     }
 
-    let virt = kconfig.boot_info.main_memory.start.to_virt();
-    debug!(
-        "Map memory {:#X} -> {:#X} size {:#X}",
-        virt.as_usize(),
-        kconfig.boot_info.main_memory.start.as_usize(),
-        kconfig.boot_info.main_memory.size
-    );
-
-    table.map_region(
-        MapConfig::new(
-            virt.as_mut_ptr(),
-            kconfig.boot_info.main_memory.start.as_usize(),
-            AccessSetting::Read | AccessSetting::Write | AccessSetting::Execute,
-            CacheSetting::Normal,
-        ),
-        kconfig.boot_info.main_memory.size,
-        true,
-        access,
-    )?;
-
-    platform::set_kernel_table(table.paddr());
-    platform::set_user_table(0);
-
-    debug!("Done!");
-    Ok(())
+    let table_addr = table.paddr();
+
+    early_dbg("Table: ");
+    early_dbg_hexln(table_addr as _);
+
+    Ok(table_addr)
 }
 
-pub fn iomap(paddr: PhysAddr, size: usize) -> NonNull<u8> {
+fn map_region(
+    table: &mut PageTableRef<'_>,
+    va_offset: usize,
+    region: &BootMemoryRegion,
+    access: &mut PageHeap,
+) {
+    let addr = region.range.start;
+    let size = region.range.end - region.range.start;
+
+    // let addr = align_down_1g(addr);
+    // let size = align_up_1g(size);
+    let vaddr = addr + va_offset;
+
+    early_dbg("map region: [");
+    early_dbg(region.name);
+    early_dbg("] [");
+    early_dbg_hex(vaddr as _);
+    early_dbg(", ");
+    early_dbg_hex((vaddr + size) as _);
+    early_dbg(") -> [");
+    early_dbg_hex(addr as _);
+    early_dbg(", ");
+    early_dbg_hex((addr + size) as _);
+    early_dbgln(")");
+
     unsafe {
-        let mut table = get_kernal_table();
-        let paddr = paddr.align_down(0x1000);
-        let vaddr = paddr.to_virt().as_mut_ptr();
-        let size = size.max(0x1000);
-
-        let heap = HEAP_ALLOCATOR.write();
-        let mut heap_mut = PageAllocatorRef::new(heap);
-
-        let _ = table.map_region_with_handle(
-            MapConfig::new(
-                vaddr,
-                paddr.as_usize(),
-                AccessSetting::Read | AccessSetting::Write,
-                CacheSetting::Device,
-            ),
+        if let Err(e) = table.map_region(
+            MapConfig::new(addr as _, addr, region.access, region.cache),
             size,
             true,
-            &mut heap_mut,
-            Some(&|p| {
-                platform::flush_tlb(Some(p));
-            }),
-        );
+            access,
+        ) {
+            early_handle_err(e);
+        }
+
+        if let Err(e) = table.map_region(
+            MapConfig::new(vaddr as _, addr, region.access, region.cache),
+            size,
+            true,
+            access,
+        ) {
+            early_handle_err(e);
+        }
+    }
+}
 
-        NonNull::new_unchecked(vaddr)
+fn early_handle_err(e: PagingError) {
+    match e {
+        PagingError::NoMemory => early_dbgln("no memory"),
+        PagingError::NotAligned => early_dbgln("not aligned"),
+        PagingError::NotMapped => early_dbgln("not mapped"),
+        PagingError::AlreadyMapped => {}
+        PagingError::MappedToHugePage => early_dbgln("mapped to huge page"),
     }
+    panic!()
+}
+
+pub fn set_kernel_table(addr: usize) {
+    MMUImpl::set_kernel_table(addr);
+}
+
+pub fn set_user_table(addr: usize) {
+    MMUImpl::set_user_table(addr);
+}
+pub fn get_user_table() -> usize {
+    MMUImpl::get_user_table()
+}
+
+#[allow(unused)]
+pub(crate) fn flush_tlb(addr: *const u8) {
+    unsafe { MMUImpl::flush_tlb(addr) };
+}
+pub fn flush_tlb_all() {
+    MMUImpl::flush_tlb_all();
+}
+pub fn page_size() -> usize {
+    MMUImpl::page_size()
+}
+pub fn table_level() -> usize {
+    MMUImpl::table_level()
 }
diff --git a/crates/sparreal-kernel/src/mem/mmu/paging.rs b/crates/sparreal-kernel/src/mem/mmu/paging.rs
new file mode 100644
index 0000000..096b68c
--- /dev/null
+++ b/crates/sparreal-kernel/src/mem/mmu/paging.rs
@@ -0,0 +1,148 @@
+use core::sync::atomic::{Ordering, fence};
+
+use log::*;
+use page_table_generic::{Access, PTEArch, PTEGeneric};
+use spin::MutexGuard;
+
+use crate::{
+    globals::global_val,
+    mem::{ALLOCATOR, Align, PhysAddr, VirtAddr},
+};
+
+use super::*;
+
+pub type PageTableRef<'a> = page_table_generic::PageTableRef<'a, PTEImpl>;
+
+#[allow(unused)]
+pub(crate) fn get_kernel_table<'a>() -> PageTableRef<'a> {
+    let addr = MMUImpl::get_kernel_table();
+    let level = table_level();
+    PageTableRef::from_addr(addr, level)
+}
+
+#[derive(Clone, Copy)]
+pub struct PTEImpl;
+
+impl PTEArch for PTEImpl {
+    fn page_size() -> usize {
+        MMUImpl::page_size()
+    }
+
+    fn level() -> usize {
+        MMUImpl::table_level()
+    }
+
+    fn new_pte(config: PTEGeneric) -> usize {
+        MMUImpl::new_pte(config)
+    }
+
+    fn read_pte(pte: usize) -> PTEGeneric {
+        MMUImpl::read_pte(pte)
+    }
+}
+
+struct HeapGuard<'a>(MutexGuard<'a, Heap<32>>);
+
+impl Access for HeapGuard<'_> {
+    fn va_offset(&self) -> usize {
+        va_offset()
+    }
+
+    unsafe fn alloc(&mut self, layout: Layout) -> Option<NonNull<u8>> {
+        self.0.alloc(layout).ok()
+    }
+
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+        self.0.dealloc(ptr, layout);
+    }
+}
+
+pub fn init_table() {
+    debug!("Initializing page table...");
+    let info = &global_val().platform_info;
+    let debugcon = info.debugcon();
+
+    unsafe {
+        let mut access = HeapGuard(ALLOCATOR.inner.lock());
+
+        let mut table = PageTableRef::create_empty(&mut access).unwrap();
+
+        for memory in info.memorys() {
+            let size = memory.end - memory.start;
+            let vaddr = VirtAddr::from(memory.start);
+
+            trace!(
+                "Mapping memory [{}, {}) -> [{}, {})",
+                vaddr,
+                vaddr + size,
+                memory.start,
+                memory.end,
+            );
+
+            table
+                .map_region(
+                    MapConfig::new(
+                        vaddr.into(),
+                        memory.start.into(),
+                        AccessSetting::Read | AccessSetting::Write | AccessSetting::Execute,
+                        CacheSetting::Normal,
+                    ),
+                    size,
+                    true,
+                    &mut access,
+                )
+                .unwrap()
+        }
+
+        if let Some(con) = debugcon {
+            let reg = con.addr.align_down(0x1000);
+
+            let vaddr = VirtAddr::from(reg);
+            trace!("Mapping stdout {} -> {}", vaddr, reg);
+
+            let _ = table.map_region(
+                MapConfig::new(
+                    vaddr.into(),
+                    reg.into(),
+                    AccessSetting::Read | AccessSetting::Write,
+                    CacheSetting::Device,
+                ),
+                0x1000,
+                true,
+                &mut access,
+            );
+        }
+
+        fence(Ordering::SeqCst);
+        set_kernel_table(table.paddr());
+        flush_tlb_all();
+    };
+}
+
+pub fn iomap(paddr: PhysAddr, size: usize) -> NonNull<u8> {
+    unsafe {
+        let mut table = get_kernel_table();
+        let paddr = paddr.align_down(0x1000);
+        let vaddr = VirtAddr::from(paddr);
+        let size = size.max(0x1000);
+
+        let mut heap = HeapGuard(ALLOCATOR.inner.lock());
+
+        let _ = table.map_region_with_handle(
+            MapConfig::new(
+                vaddr.into(),
+                paddr.as_usize(),
+                AccessSetting::Read | AccessSetting::Write,
+                CacheSetting::Device,
+            ),
+            size,
+            true,
+            &mut heap,
+            Some(&|p| {
+                MMUImpl::flush_tlb(p);
+            }),
+        );
+
+        NonNull::new(vaddr.as_mut_ptr()).unwrap()
+    }
+}
diff --git a/crates/sparreal-kernel/src/mem/mmu/table.rs b/crates/sparreal-kernel/src/mem/mmu/table.rs
deleted file mode 100644
index b73f3ff..0000000
--- a/crates/sparreal-kernel/src/mem/mmu/table.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use page_table_generic::{PTEArch, PTEGeneric};
-
-use crate::platform::{self, new_pte, page_size, read_pte, table_level};
-
-pub type PageTableRef<'a> = page_table_generic::PageTableRef<'a, PTEImpl>;
-
-pub fn get_kernal_table<'a>() -> PageTableRef<'a> {
-    let addr = unsafe { platform::get_kernel_table() };
-    let level = unsafe { platform::table_level() };
-    PageTableRef::from_addr(addr, level)
-}
-
-#[derive(Clone, Copy)]
-pub struct PTEImpl;
-
-impl PTEArch for PTEImpl {
-    fn page_size() -> usize {
-        unsafe { page_size() }
-    }
-
-    fn level() -> usize {
-        unsafe { table_level() }
-    }
-
-    fn new_pte(config: PTEGeneric) -> usize {
-        unsafe { new_pte(config) }
-    }
-
-    fn read_pte(pte: usize) -> PTEGeneric {
-        unsafe { read_pte(pte) }
-    }
-}
diff --git a/crates/sparreal-kernel/src/mem/mod.rs b/crates/sparreal-kernel/src/mem/mod.rs
index 816b415..3c7f1ba 100644
--- a/crates/sparreal-kernel/src/mem/mod.rs
+++ b/crates/sparreal-kernel/src/mem/mod.rs
@@ -1,174 +1,161 @@
-mod addr;
-
-pub mod dma;
-#[cfg(feature = "mmu")]
-pub mod mmu;
+#![allow(unused)]
 
 use core::{
-    alloc::{GlobalAlloc, Layout},
-    ptr::{null_mut, NonNull},
+    alloc::GlobalAlloc,
+    ptr::{NonNull, null_mut, slice_from_raw_parts_mut},
 };
 
-pub use addr::*;
 use buddy_system_allocator::Heap;
-use log::*;
+use log::debug;
+use spin::Mutex;
 
-use crate::{
-    kernel::KernelConfig,
-    sync::{RwLock, RwLockWriteGuard},
-};
+use crate::{globals::global_val, platform::kstack_size, println};
 
-#[global_allocator]
-static HEAP_ALLOCATOR: LockedHeap = LockedHeap::new();
+mod addr;
+mod cache;
+#[cfg(feature = "mmu")]
+pub mod mmu;
+pub mod region;
 
-pub const BYTES_1K: usize = 1024;
-pub const BYTES_1M: usize = 1024 * BYTES_1K;
-pub const BYTES_1G: usize = 1024 * BYTES_1M;
+pub use addr::*;
 
-pub unsafe fn init(kconfig: &KernelConfig) {
-    #[cfg(feature = "mmu")]
-    mmu::set_va_offset(kconfig.boot_info.va_offset);
+#[global_allocator]
+static ALLOCATOR: KAllocator = KAllocator {
+    inner: Mutex::new(Heap::empty()),
+};
 
-    let stack_size = kconfig.boot_info.hart_stack_size;
-    let start =
-        (kconfig.boot_info.main_memory.start + kconfig.boot_info.main_memory_heap_offset).to_virt();
-    let size =
-        kconfig.boot_info.main_memory.size - kconfig.boot_info.main_memory_heap_offset - stack_size;
-    let stack_top = kconfig.stack_top.to_virt();
+pub struct KAllocator {
+    pub(crate) inner: Mutex<Heap<32>>,
+}
 
-    debug!("Heap: [{}, {})", start, start + size);
-    debug!("Stack: [{}, {})", stack_top - stack_size, stack_top);
+impl KAllocator {
+    pub fn reset(&self, memory: &mut [u8]) {
+        let mut g = self.inner.lock();
 
-    let mut heap = HEAP_ALLOCATOR.write();
-    heap.init(start.as_usize(), size);
+        let mut h = Heap::empty();
 
-    debug!("Heap initialized.");
+        unsafe { h.init(memory.as_mut_ptr() as usize, memory.len()) };
 
-    #[cfg(feature = "mmu")]
-    {
-        let mut heap_mut = PageAllocatorRef::new(heap);
-        if let Err(e) = mmu::init_table(kconfig, &mut heap_mut) {
-            error!("Failed to initialize page table: {:?}", e);
-        }
+        *g = h;
     }
-}
-
-struct LockedHeap(RwLock<Heap<32>>);
-
-unsafe impl Sync for LockedHeap {}
-unsafe impl Send for LockedHeap {}
 
-impl LockedHeap {
-    const fn new() -> Self {
-        Self(RwLock::new(Heap::new()))
-    }
+    pub fn add_to_heap(&self, memory: &mut [u8]) {
+        let mut g = self.inner.lock();
+        let range = memory.as_mut_ptr_range();
 
-    fn write(&self) -> RwLockWriteGuard<'_, Heap<32>> {
-        self.0.write()
+        unsafe { g.add_to_heap(range.start as usize, range.end as usize) };
     }
 }
 
-unsafe impl GlobalAlloc for LockedHeap {
-    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
-        match self.write().alloc(layout) {
-            Ok(ptr) => ptr.as_ptr(),
-            Err(_) => null_mut(),
+unsafe impl GlobalAlloc for KAllocator {
+    unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
+        if let Ok(p) = self.inner.lock().alloc(layout) {
+            p.as_ptr()
+        } else {
+            null_mut()
         }
     }
 
-    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
-        self.write().dealloc(NonNull::new_unchecked(ptr), layout);
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
+        self.inner
+            .lock()
+            .dealloc(unsafe { NonNull::new_unchecked(ptr) }, layout);
     }
 }
 
-pub(crate) trait PhysToVirt<T> {
-    fn to_virt(self) -> Virt<T>;
-}
+static mut VA_OFFSET: usize = 0;
+static mut VA_OFFSET_NOW: usize = 0;
 
-impl<T> PhysToVirt<T> for Phys<T> {
-    fn to_virt(self) -> Virt<T> {
-        let a: usize = self.into();
+pub(crate) fn set_va_offset(offset: usize) {
+    unsafe { VA_OFFSET = offset };
+}
 
-        #[cfg(feature = "mmu")]
-        {
-            use mmu::va_offset;
-            (a + va_offset()).into()
-        }
+pub fn va_offset() -> usize {
+    unsafe { VA_OFFSET }
+}
 
-        #[cfg(not(feature = "mmu"))]
-        {
-            a.into()
-        }
-    }
+pub(crate) unsafe fn set_va_offset_now(va: usize) {
+    unsafe { VA_OFFSET_NOW = va };
 }
 
-pub(crate) trait VirtToPhys<T> {
-    fn to_phys(self) -> Phys<T>;
+fn va_offset_now() -> usize {
+    unsafe { VA_OFFSET_NOW }
 }
 
-impl<T> VirtToPhys<T> for Virt<T> {
-    fn to_phys(self) -> Phys<T> {
-        #[cfg(feature = "mmu")]
-        {
-            use mmu::va_offset;
-            self.convert_to_phys(va_offset())
-        }
+pub(crate) fn init_heap() {
+    let main = global_val().main_memory.clone();
+    let mut start = VirtAddr::from(main.start);
+    let mut end = VirtAddr::from(main.end);
 
-        #[cfg(not(feature = "mmu"))]
-        {
-            let a: usize = self.into();
-            a.into()
-        }
+    let bss_end = crate::mem::region::bss().as_ptr_range().end.into();
+
+    if (start..end).contains(&bss_end) {
+        start = bss_end;
     }
-}
 
-#[allow(dead_code)]
-pub struct PageAllocatorRef<'a> {
-    inner: RwLockWriteGuard<'a, Heap<32>>,
-}
-impl<'a> PageAllocatorRef<'a> {
-    pub fn new(inner: RwLockWriteGuard<'a, Heap<32>>) -> Self {
-        Self { inner }
+    let stack_top = VirtAddr::from(global_val().kstack_top);
+    let stack_bottom = stack_top - kstack_size();
+
+    if (start..end).contains(&stack_bottom) {
+        end = stack_bottom;
     }
+
+    println!("heap add memory [{}, {})", start, end);
+    ALLOCATOR
+        .add_to_heap(unsafe { &mut *slice_from_raw_parts_mut(start.as_mut_ptr(), end - start) });
+
+    println!("heap initialized");
 }
 
-#[cfg(feature = "mmu")]
-impl page_table_generic::Access for PageAllocatorRef<'_> {
-    fn va_offset(&self) -> usize {
-        mmu::va_offset()
-    }
+pub(crate) fn init_page_and_memory() {
+    #[cfg(feature = "mmu")]
+    mmu::init_table();
 
-    unsafe fn alloc(&mut self, layout: Layout) -> Option<NonNull<u8>> {
-        self.inner.alloc(layout).ok()
-    }
+    let main = global_val().main_memory.clone();
+
+    for memory in global_val().platform_info.memorys() {
+        if memory.contains(&main.start) {
+            continue;
+        }
+        let start = VirtAddr::from(memory.start);
+        let end = VirtAddr::from(memory.end);
+        let len = memory.end - memory.start;
 
-    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
-        self.inner.dealloc(ptr, layout);
+        debug!("Heap add memory [{}, {})", start, end);
+        ALLOCATOR.add_to_heap(unsafe { &mut *slice_from_raw_parts_mut(start.as_mut_ptr(), len) });
     }
 }
 
-#[allow(unused)]
-pub struct PageAllocator(Heap<32>);
+#[repr(C)]
+#[derive(Debug, Clone, Copy)]
+pub struct CMemRange {
+    pub start: usize,
+    pub end: usize,
+}
 
-impl PageAllocator {
-    pub unsafe fn new(start: NonNull<u8>, size: usize) -> Self {
-        let mut heap = Heap::new();
-        heap.init(start.as_ptr() as usize, size);
-        Self(heap)
+impl CMemRange {
+    pub fn as_slice(&self) -> &'static [u8] {
+        unsafe { core::slice::from_raw_parts(self.start as *const u8, self.end - self.start) }
     }
 }
 
-#[cfg(feature = "mmu")]
-impl page_table_generic::Access for PageAllocator {
-    fn va_offset(&self) -> usize {
-        mmu::va_offset()
-    }
+#[repr(C)]
+#[derive(Debug, Clone, Copy)]
+pub struct KernelRegions {
+    pub text: CMemRange,
+    pub rodata: CMemRange,
+    pub data: CMemRange,
+    pub bss: CMemRange,
+}
 
-    unsafe fn alloc(&mut self, layout: Layout) -> Option<NonNull<u8>> {
-        self.0.alloc(layout).ok()
+pub fn iomap(paddr: PhysAddr, _size: usize) -> NonNull<u8> {
+    #[cfg(feature = "mmu")]
+    {
+        mmu::iomap(paddr, _size)
     }
 
-    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
-        self.0.dealloc(ptr, layout);
+    #[cfg(not(feature = "mmu"))]
+    unsafe {
+        NonNull::new_unchecked(paddr.as_usize() as *mut u8)
     }
 }
diff --git a/crates/sparreal-kernel/src/mem/region.rs b/crates/sparreal-kernel/src/mem/region.rs
new file mode 100644
index 0000000..5bae6db
--- /dev/null
+++ b/crates/sparreal-kernel/src/mem/region.rs
@@ -0,0 +1,9 @@
+use crate::platform_if::PlatformImpl;
+
+pub fn bss() -> &'static [u8] {
+    PlatformImpl::kernel_regions().bss.as_slice()
+}
+
+pub fn text() -> &'static [u8] {
+    PlatformImpl::kernel_regions().text.as_slice()
+}
diff --git a/crates/sparreal-kernel/src/platform/fdt.rs b/crates/sparreal-kernel/src/platform/fdt.rs
new file mode 100644
index 0000000..c13d930
--- /dev/null
+++ b/crates/sparreal-kernel/src/platform/fdt.rs
@@ -0,0 +1,146 @@
+use alloc::string::{String, ToString};
+use alloc::vec::Vec;
+use core::{
+    ops::Range,
+    ptr::{NonNull, slice_from_raw_parts, slice_from_raw_parts_mut},
+};
+use fdt_parser::Node;
+use log::error;
+
+use crate::driver_manager::device::DriverId;
+use crate::globals::{self, global_val};
+use crate::irq::IrqInfo;
+use crate::mem::{Align, VirtAddr};
+use crate::{io::print::*, mem::PhysAddr};
+
+use super::{CPUInfo, SerialPort};
+
+pub struct Fdt(PhysAddr);
+
+impl Fdt {
+    pub fn new(addr: NonNull<u8>) -> Self {
+        Self(VirtAddr::from(addr).into())
+    }
+
+    pub fn model_name(&self) -> Option<String> {
+        let fdt = self.get();
+        let node = fdt.all_nodes().next()?;
+
+        let model = node.find_property("model")?;
+
+        Some(model.str().to_string())
+    }
+
+    pub fn cpus(&self) -> Vec<CPUInfo> {
+        let fdt = self.get();
+
+        fdt.find_nodes("/cpus/cpu")
+            .map(|cpu| {
+                let reg = cpu.reg().unwrap().next().unwrap();
+                CPUInfo {
+                    cpu_id: (reg.address as usize).into(),
+                }
+            })
+            .collect()
+    }
+
+    pub fn setup(&mut self) -> Result<(), &'static str> {
+        let main_memory = global_val().main_memory.clone();
+        let fdt_start = self.move_to(main_memory.end.as_usize());
+        unsafe { globals::edit(|g| g.kstack_top = fdt_start.into()) };
+        Ok(())
+    }
+
+    fn move_to(&mut self, dst_end: usize) -> usize {
+        let size = self.get().total_size();
+
+        let dst = (dst_end - size).align_down(0x1000);
+
+        early_dbg("Move FDT from ");
+        early_dbg_hex(self.0.as_usize() as _);
+        early_dbg(" to ");
+        early_dbg_hexln(dst as _);
+
+        unsafe {
+            let dest = &mut *slice_from_raw_parts_mut(dst as _, size);
+            let src = &*slice_from_raw_parts(VirtAddr::from(self.0).as_mut_ptr(), size);
+            dest.copy_from_slice(src);
+            self.0 = dst.into();
+        }
+        dst
+    }
+
+    pub fn get(&self) -> fdt_parser::Fdt<'static> {
+        let addr = VirtAddr::from(self.0).as_mut_ptr();
+        let ptr = NonNull::new(addr).unwrap();
+        fdt_parser::Fdt::from_ptr(ptr).unwrap()
+    }
+
+    pub fn get_addr(&self) -> NonNull<u8> {
+        unsafe { NonNull::new_unchecked(VirtAddr::from(self.0).as_mut_ptr()) }
+    }
+
+    pub fn memorys(&self) -> Vec<Range<PhysAddr>> {
+        let mut out = Vec::new();
+
+        let fdt = self.get();
+
+        for node in fdt.memory() {
+            for region in node.regions() {
+                let addr = (region.address as usize).into();
+                out.push(addr..addr + region.size);
+            }
+        }
+        out
+    }
+
+    pub fn take_memory(&self) -> Range<PhysAddr> {
+        let region = self
+            .get()
+            .memory()
+            .next()
+            .unwrap()
+            .regions()
+            .next()
+            .unwrap();
+        let addr = (region.address as usize).into();
+        addr..addr + region.size
+    }
+
+    pub fn debugcon(&self) -> Option<SerialPort> {
+        let fdt = self.get();
+        let stdout = fdt.chosen()?.stdout()?;
+        let compatible = stdout.node.compatibles();
+        let reg = stdout.node.reg()?.next()?;
+        Some(SerialPort::new(
+            (reg.address as usize).into(),
+            reg.size,
+            compatible,
+        ))
+    }
+}
+
+pub trait GetIrqConfig {
+    fn irq_info(&self) -> Option<IrqInfo>;
+}
+
+impl GetIrqConfig for Node<'_> {
+    fn irq_info(&self) -> Option<IrqInfo> {
+        let irq_chip_node = self.interrupt_parent()?;
+
+        let irq_parent = DriverId::from(irq_chip_node.node.phandle()?.as_usize());
+
+        let mut cfgs = Vec::new();
+        if let Some(irqs) = self.interrupts() {
+            for irq in irqs {
+                let raw = irq.collect::<Vec<_>>();
+                match crate::irq::fdt_parse_config(irq_parent, &raw) {
+                    Ok(cfg) => cfgs.push(cfg),
+                    Err(e) => error!("{:?}", e),
+                }
+            }
+        }
+
+        Some(IrqInfo { irq_parent, cfgs })
+    }
+}
diff --git a/crates/sparreal-kernel/src/platform/mod.rs b/crates/sparreal-kernel/src/platform/mod.rs
index 4b1fd65..5d6c74d 100644
--- a/crates/sparreal-kernel/src/platform/mod.rs
+++ b/crates/sparreal-kernel/src/platform/mod.rs
@@ -1,56 +1,177 @@
 use alloc::string::String;
-use sparreal_macros::api_trait;
+use alloc::vec::Vec;
+use core::ffi::CStr;
+use core::ops::Range;
+use core::ptr::NonNull;
+use driver_interface::DriverRegister;
+use driver_interface::interrupt_controller::CpuId;
 
-#[cfg(feature = "mmu")]
-use page_table_generic::PTEGeneric;
+use crate::globals::global_val;
+use crate::mem::PhysAddr;
+use crate::platform_if::*;
+use fdt::Fdt;
 
-pub enum PageAttribute {
-    Read,
-    Write,
-    Device,
-    Execute,
-    NonCache,
+pub mod fdt;
+
+pub enum PlatformInfoKind {
+    DeviceTree(Fdt),
+}
+
+impl PlatformInfoKind {
+    pub fn new_fdt(addr: NonNull<u8>) -> Self {
+        PlatformInfoKind::DeviceTree(Fdt::new(addr))
+    }
+
+    pub fn memorys(&self) -> impl Iterator<Item = Range<PhysAddr>> {
+        let mut out: [Option<Range<PhysAddr>>; 24] =
+            unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
+        let mut len = 0;
+
+        match self {
+            PlatformInfoKind::DeviceTree(fdt) => {
+                for (i, m) in fdt
+                    .get()
+                    .memory()
+                    .flat_map(|m| m.regions())
+                    .map(|r| {
+                        let start = PhysAddr::from(r.address as usize);
+                        start..start + r.size
+                    })
+                    .enumerate()
+                {
+                    if i >= out.len() {
+                        break;
+                    }
+                    out[i] = Some(m);
+                    len += 1;
+                }
+            }
+        }
+
+        let mut iter = 0;
+        core::iter::from_fn(move || {
+            if iter >= len {
+                None
+            } else {
+                let m = out[iter].take().unwrap();
+                iter += 1;
+                Some(m)
+            }
+        })
+    }
+
+    pub fn main_memory(&self) -> Option<Range<PhysAddr>> {
+        let kernel_text = PlatformImpl::kernel_regions().text;
+
+        let mut first = None;
+
+        for m in self.memorys() {
+            let r = m.start.as_usize()..m.end.as_usize();
+            if r.contains(&kernel_text.end) {
+                return Some(m);
+            }
+            if first.is_none() {
+                first = Some(m);
+            }
+        }
+
+        first
+    }
+
+    pub fn debugcon(&self) -> Option<SerialPort> {
+        match self {
+            Self::DeviceTree(fdt) => fdt.debugcon(),
+        }
+    }
+}
+
+pub fn cpu_list() -> Vec<CPUInfo> {
+    match &global_val().platform_info {
+        PlatformInfoKind::DeviceTree(fdt) => fdt.cpus(),
+    }
+}
+
+pub fn cpu_id() -> CpuId {
+    PlatformImpl::cpu_id().into()
 }
 
-pub enum PageError {
-    NoMemory,
-    Other,
+pub fn platform_name() -> String {
+    match &global_val().platform_info {
+        PlatformInfoKind::DeviceTree(fdt) => fdt.model_name().unwrap_or_default(),
+    }
+}
+
+pub fn shutdown() -> ! {
+    PlatformImpl::shutdown()
+}
+
+pub fn wait_for_interrupt() {
+    PlatformImpl::wait_for_interrupt();
+}
+
+pub fn kstack_size() -> usize {
+    PlatformImpl::kstack_size()
 }
 
 pub fn app_main() {
-    extern "C" {
+    unsafe extern "C" {
         fn __sparreal_rt_main();
     }
-
     unsafe { __sparreal_rt_main() }
 }
 
-#[api_trait]
-pub trait Platform {
-    unsafe fn shutdown();
-    unsafe fn wait_for_interrupt();
-    unsafe fn current_ticks() -> u64;
-    unsafe fn tick_hz() -> u64;
-    unsafe fn debug_write_byte(ch: u8);
-
-    fn print_system_info();
-
-    fn irqs_enable();
-    fn irqs_disable();
-    fn cpu_id() -> u64;
-    fn cpu_id_display() -> String;
-}
-
-#[cfg(feature = "mmu")]
-#[api_trait]
-pub trait PlatformPageTable {
-    fn set_kernel_table(addr: usize);
-    fn get_kernel_table() -> usize;
-    fn set_user_table(addr: usize);
-    fn get_user_table() -> usize;
-    fn flush_tlb(addr: Option<*const u8>);
-    fn page_size() -> usize;
-    fn table_level() -> usize;
-    fn new_pte(config: PTEGeneric) -> usize;
-    fn read_pte(pte: usize) -> PTEGeneric;
+#[derive(Debug)]
+pub struct CPUInfo {
+    pub cpu_id: CpuId,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct SerialPort {
+    pub addr: PhysAddr,
+    pub size: Option<usize>,
+    compatible: [Option<[u8; 128]>; 4],
+}
+
+impl SerialPort {
+    pub fn new<'a>(
+        addr: PhysAddr,
+        size: Option<usize>,
+        compatibles: impl Iterator<Item = &'a str>,
+    ) -> Self {
+        let mut compatible_out = [None; 4];
+
+        for (i, c) in compatibles.enumerate() {
+            if i == compatible_out.len() {
+                break;
+            }
+            let bytes = c.as_bytes();
+            let mut bytes_out = [0u8; 128];
+            bytes_out[..bytes.len()].copy_from_slice(bytes);
+            compatible_out[i] = Some(bytes_out);
+        }
+
+        Self {
+            addr,
+            size,
+            compatible: compatible_out,
+        }
+    }
+
+    pub fn compatibles(&self) -> impl Iterator<Item = &str> {
+        let mut iter = 0;
+
+        core::iter::from_fn(move || {
+            if iter >= self.compatible.len() {
+                None
+            } else {
+                let bytes = self.compatible[iter].as_ref()?;
+                iter += 1;
+                CStr::from_bytes_until_nul(bytes).ok()?.to_str().ok()
+            }
+        })
+    }
+}
+
+pub fn module_registers() -> Vec<DriverRegister> {
+    PlatformImpl::driver_registers().as_slice().to_vec()
 }
diff --git a/crates/sparreal-kernel/src/platform_if/mod.rs b/crates/sparreal-kernel/src/platform_if/mod.rs
new file mode 100644
index 0000000..1ff6724
--- /dev/null
+++ b/crates/sparreal-kernel/src/platform_if/mod.rs
@@ -0,0 +1,84 @@
+use core::ffi::c_void;
+
+pub use driver_interface::DriverRegisterListRef;
+use sparreal_macros::api_trait;
+
+use crate::mem::KernelRegions;
+
+#[api_trait]
+pub trait Platform {
+    fn kernel_regions() -> KernelRegions;
+    fn kstack_size() -> usize;
+    fn cpu_id() -> usize;
+    fn cpu_context_size() -> usize;
+
+    /// # Safety
+    ///
+    ///
+    unsafe fn get_current_tcb_addr() -> *const u8;
+
+    /// # Safety
+    ///
+    ///
+    unsafe fn set_current_tcb_addr(addr: *const u8);
+
+    /// # Safety
+    ///
+    ///
+    unsafe fn cpu_context_init(ctx_ptr: *mut u8, pc: *const c_void, stack_top: *const u8);
+
+    /// # Safety
+    ///
+    /// `ctx_ptr` 是有效的上下文指针
+    unsafe fn cpu_context_sp(ctx_ptr: *const u8) -> usize;
+
+    /// # Safety
+    ///
+    ///
+    unsafe fn cpu_context_switch(prev: *mut u8, next: *mut u8);
+
+    fn wait_for_interrupt();
+
+    fn irq_all_enable();
+    fn irq_all_disable();
+    fn irq_all_is_enabled() -> bool;
+
+    fn on_boot_success() {}
+    fn shutdown() -> !;
+    fn debug_put(b: u8);
+
+    fn dcache_range(op: CacheOp, addr: usize, size: usize);
+
+    fn driver_registers() -> DriverRegisterListRef;
+}
+
+#[cfg(feature = "mmu")]
+#[api_trait]
+pub trait MMU {
+    fn set_kernel_table(addr: usize);
+    fn get_kernel_table() -> usize;
+    fn set_user_table(addr: usize);
+    fn get_user_table() -> usize;
+
+    /// flush tlb
+    /// # Safety
+    /// addr must be page aligned
+    unsafe fn flush_tlb(addr: *const u8);
+    fn flush_tlb_all();
+    fn page_size() -> usize;
+    fn table_level() -> usize;
+    fn new_pte(config: page_table_generic::PTEGeneric) -> usize;
+    fn read_pte(pte: usize) -> page_table_generic::PTEGeneric;
+    fn enable_mmu(stack_top: usize, jump_to: usize) -> !;
+}
+
+#[repr(C)]
+#[derive(Debug, Clone, Copy)]
+pub enum CacheOp {
+    /// Write back to memory
+    Clean,
+    /// Invalidate cache
+    Invalidate,
+    /// Clean and invalidate
+    CleanAndInvalidate,
+}
diff --git a/crates/sparreal-kernel/src/prelude.rs b/crates/sparreal-kernel/src/prelude.rs
index 59236ee..75909e9 100644
--- a/crates/sparreal-kernel/src/prelude.rs
+++ b/crates/sparreal-kernel/src/prelude.rs
@@ -1 +1,5 @@
-pub use crate::driver::device_tree::FDTExtend;
+pub use crate::platform::fdt::GetIrqConfig;
+pub use crate::print;
+pub use crate::println;
+pub use fdt_parser;
+pub use sparreal_macros::entry;
diff --git a/crates/sparreal-kernel/src/stdout/mod.rs b/crates/sparreal-kernel/src/stdout/mod.rs
deleted file mode 100644
index 4d39c59..0000000
--- a/crates/sparreal-kernel/src/stdout/mod.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use core::fmt::{self, Write};
-
-use alloc::{boxed::Box, sync::Arc};
-use driver_interface::uart;
-
-use crate::{
-    driver::{DriverArc, DriverWeak},
-    platform,
-    sync::RwLock,
-    util::boot::boot_debug_hex,
-};
-
-static STDOUT: RwLock<Option<Box<dyn StdoutWrite>>> = RwLock::new(None);
-
-pub trait StdoutWrite: Send + Sync + Write + 'static {}
-
-pub fn print(args: fmt::Arguments) {
-    let mut stdout = STDOUT.write();
-    if let Some(stdout) = stdout.as_mut() {
-        let _ = stdout.write_fmt(args);
-    }
-}
-
-pub fn set_stdout(stdout: impl StdoutWrite) {
-    let stdout = Box::new(stdout);
-    *STDOUT.write() = Some(stdout);
-}
-
-#[derive(Clone)]
-pub struct UartWrite {
-    pub driver: DriverWeak<uart::BoxDriver>,
-}
-
-impl UartWrite {
-    pub fn new(driver: &DriverArc<uart::BoxDriver>) -> Self {
-        Self {
-            driver: Arc::downgrade(driver),
-        }
-    }
-}
-
-impl Write for UartWrite {
-    fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
-        if let Some(arc) = self.driver.upgrade() {
-            let mut g = arc.write();
-            let _ = g.write_all(s.as_bytes());
-        }
-        Ok(())
-    }
-}
-impl StdoutWrite for UartWrite {}
-
-#[derive(Clone, Copy)]
-pub struct EarlyDebugWrite;
-
-impl Write for EarlyDebugWrite {
-    fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
-        unsafe {
-            s.bytes().for_each(|ch| {
-                platform::debug_write_byte(ch);
-            });
-        }
-        Ok(())
-    }
-}
-impl StdoutWrite for EarlyDebugWrite {}
-
-pub fn early_print_str(s: &str) {
-    let _ = EarlyDebugWrite {}.write_str(s);
-}
-
-#[macro_export]
-macro_rules! dbg {
-    ($v:expr) => {
-        $crate::__export::early_print_str($v)
-    };
-}
-
-#[macro_export]
-macro_rules! dbgln {
-    () => {
-        $crate::dbg!("\r\n")
-    };
-    ($v:expr) => {
-        $crate::dbg!($v);
-        $crate::dbg!("\r\n")
-    };
-}
-
-#[macro_export]
-macro_rules! dbg_hex {
-    ($v:expr) => {
-        $crate::__export::debug_hex($v as _)
-    };
-}
-
-#[macro_export]
-macro_rules! dbg_hexln {
-    ($v:expr) => {
-        $crate::__export::debug_hex($v as _);
-        $crate::dbgln!()
-    };
-}
-
-pub fn debug_hex(v: u64) {
-    boot_debug_hex(EarlyDebugWrite {}, v);
-}
diff --git a/crates/sparreal-kernel/src/sync/mod.rs b/crates/sparreal-kernel/src/sync/mod.rs
deleted file mode 100644
index 98d21fc..0000000
--- a/crates/sparreal-kernel/src/sync/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-mod rwlock;
-mod spin;
-
-pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
-pub use spin::{Spinlock, SpinlockGuard};
diff --git a/crates/sparreal-kernel/src/sync/rwlock.rs b/crates/sparreal-kernel/src/sync/rwlock.rs
deleted file mode 100644
index 2157bc1..0000000
--- a/crates/sparreal-kernel/src/sync/rwlock.rs
+++ /dev/null
@@ -1,125 +0,0 @@
-#![allow(unused)]
-
-use core::{
-    hint::spin_loop,
-    sync::atomic::{AtomicUsize, Ordering},
-};
-
-use lock_api::GuardSend;
-use log::warn;
-
-const READER: usize = 1 << 2;
-const UPGRADED: usize = 1 << 1;
-const WRITER: usize = 1;
-const READERS_MASK: usize = !(WRITER | UPGRADED);
-
-pub type RwLock<T> = lock_api::RwLock<RawRwLock, T>;
-/// RAII structure used to release the shared read access of a lock when
-/// dropped.
-pub type RwLockReadGuard<'a, T> = lock_api::RwLockReadGuard<'a, RawRwLock, T>;
-
-/// RAII structure used to release the exclusive write access of a lock when
-/// dropped.
-pub type RwLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, RawRwLock, T>;
-
-/// Raw reader-writer lock type backed by the parking lot.
-pub struct RawRwLock {
-    lock: AtomicUsize,
-}
-
-unsafe impl lock_api::RawRwLock for RawRwLock {
-    #[allow(clippy::declare_interior_mutable_const)]
-    const INIT: RawRwLock = RawRwLock {
-        lock: AtomicUsize::new(0),
-    };
-
-    type GuardMarker = GuardSend;
-
-    #[inline]
-    fn lock_exclusive(&self) {
-        // Note: This isn't the best way of implementing a spinlock, but it
-        // suffices for the sake of this example.
-        while !self.try_lock_exclusive() {
-            spin_loop();
-        }
-    }
-
-    #[inline]
-    fn try_lock_exclusive(&self) -> bool {
-        self.lock
-            .compare_exchange(0, WRITER, Ordering::Acquire, Ordering::Relaxed)
-            .is_ok()
-    }
-
-    #[inline]
-    unsafe fn unlock_exclusive(&self) {
-        // Writer is responsible for clearing both WRITER and UPGRADED bits.
-        // The UPGRADED bit may be set if an upgradeable lock attempts an upgrade while this lock is held.
-        self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
-    }
-
-    #[inline]
-    fn lock_shared(&self) {
-        // Note: This isn't the best way of implementing a spinlock, but it
-        // suffices for the sake of this example.
-        while !self.try_lock_shared() {
-            spin_loop();
-        }
-    }
-
-    #[inline]
-    fn try_lock_shared(&self) -> bool {
-        let value = match self.acquire_reader() {
-            Some(v) => v,
-            None => return false,
-        };
-        // We check the UPGRADED bit here so that new readers are prevented when an UPGRADED lock is held.
-        // This helps reduce writer starvation.
-        if value & (WRITER | UPGRADED) != 0 {
-            // Lock is taken, undo.
-            self.lock.fetch_sub(READER, Ordering::Release);
-            false
-        } else {
-            true
-        }
-    }
-
-    #[inline]
-    unsafe fn unlock_shared(&self) {
-        self.lock.fetch_sub(READER, Ordering::Release);
-    }
-
-    #[inline]
-    fn is_locked(&self) -> bool {
-        let state = self.lock.load(Ordering::Relaxed);
-        state & (WRITER | READERS_MASK) != 0
-    }
-
-    #[inline]
-    fn is_locked_exclusive(&self) -> bool {
-        let state = self.lock.load(Ordering::Relaxed);
-        state & (WRITER) != 0
-    }
-}
-impl RawRwLock {
-    // Acquire a read lock, returning the new lock value.
-    fn acquire_reader(&self) -> Option<usize> {
-        // An arbitrary cap that allows us to catch overflows long before they happen
-        const MAX_READERS: usize = usize::MAX / READER / 2;
-
-        let value = self.lock.fetch_add(READER, Ordering::Acquire);
-
-        if value > MAX_READERS * READER {
-            self.lock.fetch_sub(READER, Ordering::Relaxed);
-            warn!("Too many lock readers, cannot safely proceed");
-            None
-        } else {
-            Some(value)
-        }
-    }
-
-    unsafe fn force_write_unlock(&self) {
-        debug_assert_eq!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED), 0);
-        self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
-    }
-}
diff --git a/crates/sparreal-kernel/src/sync/spin.rs b/crates/sparreal-kernel/src/sync/spin.rs
deleted file mode 100644
index 0c0b9c3..0000000
--- a/crates/sparreal-kernel/src/sync/spin.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// pub use spin::Mutex;
-
-use core::{
-    hint::spin_loop,
-    sync::atomic::{AtomicBool, Ordering},
-};
-use lock_api::{GuardSend, RawMutex};
-
-// 1. Define our raw lock type
-pub struct RawSpinlock(AtomicBool);
-
-// 2. Implement RawMutex for this type
-unsafe impl RawMutex for RawSpinlock {
-    #[allow(clippy::declare_interior_mutable_const)]
-    const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
-
-    // A spinlock guard can be sent to another thread and unlocked there
-    type GuardMarker = GuardSend;
-
-    fn lock(&self) {
-        // Note: This isn't the best way of implementing a spinlock, but it
-        // suffices for the sake of this example.
-        while !self.try_lock() {
-            spin_loop();
-        }
-    }
-
-    fn try_lock(&self) -> bool {
-        self.0
-            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
-            .is_ok()
-    }
-
-    unsafe fn unlock(&self) {
-        self.0.store(false, Ordering::Release);
-    }
-}
-
-// 3. Export the wrappers. This are the types that your users will actually use.
-pub type Spinlock<T> = lock_api::Mutex<RawSpinlock, T>;
-pub type SpinlockGuard<'a, T> = lock_api::MutexGuard<'a, RawSpinlock, T>;
diff --git a/crates/sparreal-kernel/src/task/mod.rs b/crates/sparreal-kernel/src/task/mod.rs
new file mode 100644
index 0000000..9bb3b51
--- /dev/null
+++ b/crates/sparreal-kernel/src/task/mod.rs
@@ -0,0 +1,53 @@
+use alloc::string::{String, ToString};
+use tcb::{Pid, TaskControlBlock, set_current};
+
+mod schedule;
+mod tcb;
+
+pub use schedule::suspend;
+pub use tcb::current;
+
+#[derive(Debug, Clone)]
+pub enum TaskError {
+    NoMemory,
+}
+
+#[derive(Debug, Clone)]
+pub struct TaskConfig {
+    pub name: String,
+    pub priority: usize,
+    pub stack_size: usize,
+}
+
+impl TaskConfig {
+    pub fn new(name: impl ToString) -> Self {
+        Self {
+            name: name.to_string(),
+            priority: 0,
+            stack_size: 2 * 1024 * 1024,
+        }
+    }
+}
+
+pub fn spawn_with_config<F>(f: F, config: TaskConfig) -> Result<(), TaskError>
+where
+    F: FnOnce() + Send + 'static,
+{
+    let task = TaskControlBlock::new(f, config)?;
+
+    tcb::current().switch_to(&task);
+
+    Ok(())
+}
+
+pub fn init() {
+    let task = TaskControlBlock::new(|| {}, TaskConfig {
+        name: "Task0".into(),
+        priority: 0,
+        stack_size: 0,
+    })
+    .unwrap();
+    set_current(&task);
+}
+
+pub fn wake_up_in_irq(_pid: Pid) {}
diff --git a/crates/sparreal-kernel/src/task/schedule.rs b/crates/sparreal-kernel/src/task/schedule.rs
new file mode 100644
index 0000000..56b8669
--- /dev/null
+++ b/crates/sparreal-kernel/src/task/schedule.rs
@@ -0,0 +1,54 @@
+use alloc::collections::vec_deque::VecDeque;
+use log::debug;
+use spin::Mutex;
+
+use crate::platform_if::PlatformImpl;
+
+use super::tcb::{TaskControlBlock, TaskState, current};
+
+static IDLE: Mutex<VecDeque<TaskControlBlock>> = Mutex::new(VecDeque::new());
+static FINISHED: Mutex<VecDeque<TaskControlBlock>> = Mutex::new(VecDeque::new());
+
+pub fn schedule() {
+    let idle = idle_pop();
+    if let Some(mut idle) = idle {
+        let mut cu = current();
+        if matches!(cu.info().state, TaskState::Running) {
+            cu.info_mut().state = TaskState::Suspend;
+        }
+        idle.info_mut().state = TaskState::Running;
+
+        cu.switch_to(&idle);
+    } else {
+        debug!("No task idle");
+        loop {
+            PlatformImpl::wait_for_interrupt();
+        }
+    }
+}
+
+pub fn idle_push(tcb: TaskControlBlock) {
+    IDLE.lock().push_back(tcb);
+}
+
+pub fn idle_pop() -> Option<TaskControlBlock> {
+    let mut g = IDLE.lock();
+    while let Some(one) = g.pop_front() {
+        if matches!(one.info().state, TaskState::Stopped) {
+            unsafe { one.drop() };
+            continue;
+        }
+        return Some(one);
+    }
+    None
+}
+
+pub fn finished_push(tcb: TaskControlBlock) {
+    FINISHED.lock().push_back(tcb);
+}
+
+pub fn suspend() {
+    let mut current = current();
+    current.info_mut().state = TaskState::Suspend;
+    schedule();
+}
diff --git a/crates/sparreal-kernel/src/task/tcb.rs b/crates/sparreal-kernel/src/task/tcb.rs
new file mode 100644
index 0000000..bbaf26c
--- /dev/null
+++ b/crates/sparreal-kernel/src/task/tcb.rs
@@ -0,0 +1,193 @@
+use core::{
+    alloc::Layout,
+    fmt::Debug,
+    ptr::NonNull,
+    sync::atomic::{AtomicUsize, Ordering},
+};
+
+use alloc::{boxed::Box, string::String};
+use log::debug;
+
+use crate::{platform_if::PlatformImpl, task::schedule::*};
+
+use super::{TaskConfig, TaskError};
+
+const TCB_ALIGN: usize = 16;
+
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct TaskControlBlock(*mut u8);
+
+unsafe impl Send for TaskControlBlock {}
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+pub struct Pid(usize);
+
+impl Pid {
+    pub fn new() -> Self {
+        static ITER: AtomicUsize = AtomicUsize::new(0);
+        Self(ITER.fetch_add(1, Ordering::SeqCst))
+    }
+}
+
+impl Default for Pid {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Debug for Pid {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        writeln!(f, "{:?}", self.0)
+    }
+}
+
+impl TaskControlBlock {
+    pub(super) fn new<F>(entry: F, config: TaskConfig) -> Result<Self, TaskError>
+    where
+        F: FnOnce() + Send + 'static,
+    {
+        let entry_box = Box::new(entry);
+
+        let buffer = NonNull::new(unsafe {
+            alloc::alloc::alloc_zeroed(
+                Layout::from_size_align(Self::tcb_size(config.stack_size), TCB_ALIGN).unwrap(),
+            )
+        })
+        .ok_or(TaskError::NoMemory)?;
+
+        let pid = Pid::new();
+
+        let pc;
+
+        unsafe {
+            let task_info = &mut *(buffer.as_ptr() as *mut TaskInfo);
+            task_info.pid = pid;
+            task_info.stack_size = config.stack_size;
+            task_info.priority = config.priority;
+            task_info.name = config.name;
+            task_info.state = TaskState::Idle;
+            task_info.entry = Some(entry_box);
+
+            pc = task_entry as usize as _;
+        }
+
+        let task = Self(buffer.as_ptr());
+
+        unsafe {
+            let stack_top = task.stack().as_ptr().add(config.stack_size);
+
+            debug!(
+                "New task [{:?}], stack_top: {:p}",
+                task.info().name,
+                stack_top
+            );
+
+            PlatformImpl::cpu_context_init(
+                task.cpu_context_ptr(),
+                pc,
+                task.stack().as_ptr().add(config.stack_size),
+            );
+        }
+        Ok(task)
+    }
+
+    fn tcb_size(stack_size: usize) -> usize {
+        size_of::<TaskInfo>() + stack_size + PlatformImpl::cpu_context_size()
+    }
+
+    pub fn info(&self) -> &TaskInfo {
+        unsafe { &*(self.0 as *mut TaskInfo) }
+    }
+
+    pub(super) fn info_mut(&mut self) -> &mut TaskInfo {
+        unsafe { &mut *(self.0 as *mut TaskInfo) }
+    }
+
+    pub(super) fn stack(&self) -> &[u8] {
+        let stack_size = self.info().stack_size;
+        unsafe { core::slice::from_raw_parts_mut(self.0.add(size_of::<TaskInfo>()), stack_size) }
+    }
+
+    pub(super) unsafe fn drop(self) {
+        let info = self.info();
+
+        let size = Self::tcb_size(info.stack_size);
+
+        unsafe {
+            alloc::alloc::dealloc(self.0, Layout::from_size_align_unchecked(size, TCB_ALIGN))
+        };
+    }
+
+    fn cpu_context_ptr(&self) -> *mut u8 {
+        unsafe {
+            self.0
+                .add(size_of::<TaskInfo>())
+                .add(self.info().stack_size)
+        }
+    }
+
+    fn addr(&self) -> *mut u8 {
+        self.0 as _
+    }
+
+    pub(super) fn switch_to(&self, next: &TaskControlBlock) {
+        debug!("switch {} -> {}", self.info().name, next.info().name);
+        set_current(next);
+        match self.info().state {
+            TaskState::Stopped => finished_push(*self),
+            _ => idle_push(*self),
+        }
+
+        unsafe {
+            PlatformImpl::cpu_context_switch(self.cpu_context_ptr(), next.cpu_context_ptr());
+        }
+    }
+
+    #[allow(unused)]
+    pub fn sp(&self) -> usize {
+        unsafe { PlatformImpl::cpu_context_sp(self.cpu_context_ptr()) }
+    }
+}
+
+pub struct TaskInfo {
+    pub pid: Pid,
+    pub name: String,
+    pub priority: usize,
+    pub stack_size: usize,
+    pub entry: Option<Box<dyn FnOnce()>>,
+    pub state: TaskState,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub enum TaskState {
+    Idle,
+    Running,
+    Suspend,
+    Stopped,
+}
+
+extern "C" fn task_entry() -> ! {
+    let mut task = current();
+    let task_mut = task.info_mut();
+    if let Some(entry) = task_mut.entry.take() {
+        entry();
+        task_mut.state = TaskState::Stopped;
+    }
+    schedule();
+    unreachable!("task exited!");
+}
+
+pub fn current() -> TaskControlBlock {
+    unsafe {
+        let ptr = PlatformImpl::get_current_tcb_addr();
+        TaskControlBlock(ptr as _)
+    }
+}
+
+pub fn set_current(tcb: &TaskControlBlock) {
+    unsafe {
+        PlatformImpl::set_current_tcb_addr(tcb.addr());
+    }
+}
diff --git a/crates/sparreal-kernel/src/time.rs b/crates/sparreal-kernel/src/time.rs
deleted file mode 100644
index 3522220..0000000
--- a/crates/sparreal-kernel/src/time.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use core::{future::Future, time::Duration};
-
-use crate::platform;
-
-pub fn since_boot() -> Duration {
-    let current_tick = unsafe { platform::current_ticks() };
-    let freq = unsafe { platform::tick_hz() };
-    Duration::from_nanos(current_tick * 1_000_000_000 / freq)
-}
-
-pub fn delay(duration: Duration) -> impl Future<Output = ()> {
-    unsafe {
-        let current_tick = platform::current_ticks();
-        let freq = platform::tick_hz();
-        let ticks = duration.as_nanos() * freq as u128 / 1_000_000_000;
-        let until = current_tick + ticks as u64;
-        FutureDelay { until }
-    }
-}
-
-pub struct FutureDelay {
-    until: u64,
-}
-
-impl Future for FutureDelay {
-    type Output = ();
-
-    fn poll(
-        self: core::pin::Pin<&mut Self>,
-        cx: &mut core::task::Context<'_>,
-    ) -> core::task::Poll<Self::Output> {
-        let current_tick = unsafe { platform::current_ticks() };
-        if current_tick >= self.until {
-            core::task::Poll::Ready(())
-        } else {
-            cx.waker().wake_by_ref();
-            core::task::Poll::Pending
-        }
-    }
-}
diff --git a/crates/sparreal-kernel/src/time/mod.rs b/crates/sparreal-kernel/src/time/mod.rs
new file mode 100644
index 0000000..5eae1ea
--- /dev/null
+++ b/crates/sparreal-kernel/src/time/mod.rs
@@ -0,0 +1,98 @@
+use core::time::Duration;
+
+use crate::{
+    driver_manager::{
+        self,
+        device::{BorrowGuard, Device},
+        manager,
+    },
+    globals::{cpu_global, cpu_global_meybeuninit, cpu_global_mut, global_val},
+    irq::{IrqHandleResult, IrqParam},
+};
+
+use driver_interface::{interrupt_controller::IrqId, timer::*};
+use log::error;
+
+#[derive(Default)]
+pub(crate) struct TimerData {
+    timer: Option<Device<Timer>>,
+}
+
+pub fn since_boot() -> Duration {
+    _since_boot().unwrap_or_default()
+}
+
+fn _since_boot() -> Option<Duration> {
+    Some(cpu_global_meybeuninit()?.timer.timer.as_ref()?.since_boot())
+}
+
+pub(crate) fn init_main_cpu() {
+    match &global_val().platform_info {
+        crate::globals::PlatformInfoKind::DeviceTree(fdt) => {
+            if let Err(e) = driver_manager::init_timer_by_fdt(fdt.get_addr()) {
+                error!("{}", e);
+            }
+        }
+    }
+
+    init_current_cpu();
+}
+
+pub(crate) fn init_current_cpu() -> Option<()> {
+    let timer = manager().timer.get_cpu_timer();
+    unsafe { cpu_global_mut().timer.timer = timer };
+
+    let mut t = timer_write()?;
+
+    t.set_irq_enable(false);
+    t.enable();
+
+    let irq_chip = t.descriptor.irq.as_ref()?.irq_parent;
+
+    IrqParam {
+        irq_chip,
+        cfg: t.irq(),
+    }
+    .register_builder(irq_handle)
+    .register();
+
+    Some(())
+}
+
+fn timer_write() -> Option<BorrowGuard<Timer>> {
+    Some(timer_data().timer.as_ref()?.spin_try_use("Kernel"))
+}
+fn irq_handle(_irq: IrqId) -> IrqHandleResult {
+    let t = unsafe { &mut *timer_data().timer.as_ref().unwrap().force_use() };
+    t.handle_irq();
+    IrqHandleResult::Handled
+}
+
+fn timer_data() -> &'static TimerData {
+    &cpu_global().timer
+}
+
+pub fn after(duration: Duration, call: impl Fn() + 'static) {
+    if let Some(mut t) = timer_write() {
+        t.after(duration, call);
+    }
+}
+
+pub fn spin_delay(duration: Duration) {
+    let now = since_boot();
+    let at = now + duration;
+
+    loop {
+        if since_boot() >= at {
+            break;
+        }
+    }
+}
+
+pub fn sleep(duration: Duration) {
+    let pid = crate::task::current().info().pid;
+    after(duration, move || {
+        crate::task::wake_up_in_irq(pid);
+    });
+    crate::task::suspend();
+}
diff --git a/crates/sparreal-kernel/src/trap.rs b/crates/sparreal-kernel/src/trap.rs
deleted file mode 100644
index 8b13789..0000000
--- a/crates/sparreal-kernel/src/trap.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/crates/sparreal-kernel/src/util/boot.rs b/crates/sparreal-kernel/src/util/boot.rs
deleted file mode 100644
index d9fb636..0000000
--- a/crates/sparreal-kernel/src/util/boot.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-use core::{fmt::Write, ptr::NonNull};
-
-use fdt_parser::Fdt;
-
-pub fn boot_debug_hex(mut w: impl Write, v: u64) {
-    const HEX_BUF_SIZE: usize = 20; // 最大长度,包括前缀"0x"和数字
-    let mut hex_buf: [char; HEX_BUF_SIZE] = ['0'; HEX_BUF_SIZE];
-    let mut n = v;
-    let _ = w.write_str("0x");
-
-    if n == 0 {
-        let _ = w.write_str("0");
-        return;
-    }
-    let mut i = 0;
-    while n > 0 {
-        let digit = n & 0xf;
-        let ch = if digit < 10 {
-            (b'0' + digit as u8) as char
-        } else {
-            (b'a' + (digit - 10) as u8) as char
-        };
-        n >>= 4; // 右移四位
-        hex_buf[i] = ch;
-        i += 1;
-    }
-    let s = &hex_buf[..i];
-    for ch in s.iter().rev() {
-        let _ = w.write_char(*ch);
-    }
-}
-
-pub struct StdoutReg {
-    pub reg: *const u8,
-    pub size: usize,
-}
-
-pub unsafe fn stdout_reg(dtb: NonNull<u8>) -> Option<StdoutReg> {
-    let fdt = Fdt::from_ptr(dtb).ok()?;
-    let chosen = fdt.chosen()?;
-    if let Some(stdout) = chosen.stdout() {
-        let r = stdout.node.reg()?.next()?;
-        return Some(StdoutReg {
-            reg: r.address as usize as _,
-            size: r.size.unwrap_or_default(),
-        });
-    }
-    None
-}
diff --git a/crates/sparreal-kernel/src/util/mod.rs b/crates/sparreal-kernel/src/util/mod.rs
deleted file mode 100644
index 1fc13aa..0000000
--- a/crates/sparreal-kernel/src/util/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod boot;
diff --git a/crates/sparreal-kernel/tests/test.rs b/crates/sparreal-kernel/tests/test.rs
deleted file mode 100644
index 61e9a15..0000000
--- a/crates/sparreal-kernel/tests/test.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use sparreal_kernel::util::boot::boot_debug_hex;
-use std::fmt;
-
-#[test]
-fn test_hex_fmt() {
-    struct TestWriter;
-    impl fmt::Write for TestWriter {
-        fn write_str(&mut self, s: &str) -> fmt::Result {
-            std::println!("{}", s);
-            Ok(())
-        }
-    }
-
-    boot_debug_hex(TestWriter {}, 0x12345678);
-}
diff --git a/crates/sparreal-macros/Cargo.toml b/crates/sparreal-macros/Cargo.toml
index 9122060..78a2712 100644
--- a/crates/sparreal-macros/Cargo.toml
+++ b/crates/sparreal-macros/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "sparreal-macros"
-version = "0.0.5"
-edition = "2021"
+version.workspace = true
+edition = "2024"
 license = "MIT"
 description = "macros for sparreal"
 authors = ["周睿 <zrufo747@outlook.com>"]
@@ -15,5 +15,5 @@ proc-macro = true
 quote = "1.0"
 proc-macro2 = "1.0"
 syn = { version = "2.0", features = ["extra-traits", "full"] }
-
+abi-singleton = "0.3"
 [features]
diff --git a/crates/sparreal-macros/src/api_trait.rs b/crates/sparreal-macros/src/api_trait.rs
index 0f51d1a..1c49845 100644
--- a/crates/sparreal-macros/src/api_trait.rs
+++ b/crates/sparreal-macros/src/api_trait.rs
@@ -3,6 +3,8 @@ mod tests {
 
     use syn::TraitItem;
 
+    use super::*;
+
     #[test]
     fn it_works() {
         let f = syn::parse_str::<syn::ItemTrait>(
diff --git a/crates/sparreal-macros/src/arch/aarch64.rs b/crates/sparreal-macros/src/arch/aarch64.rs
new file mode 100644
index 0000000..42bff9b
--- /dev/null
+++ b/crates/sparreal-macros/src/arch/aarch64.rs
@@ -0,0 +1,72 @@
+#![allow(unused)]
+
+use proc_macro::TokenStream;
+use syn::parse;
+
+pub fn store_cpu_context(input: TokenStream) -> Result<TokenStream, parse::Error> {
+    // let reg = syn::parse::<syn::LitStr>(input)?;
+
+    // let after = format!("[{},#-0x20]!", reg.value());
+
+    let after = format!("[{},#-0x20]!", "sp");
+    let asm_str = reg_op_pair("stp", "q", 0..32, &after, true);
+
+    Ok(asm_str.parse().unwrap())
+}
+
+fn reg_op_pair(
+    op: &str,
+    reg: &str,
+    range: std::ops::Range<usize>,
+    after: &str,
+    reverse: bool,
+) -> String {
+    let mut ls = range
+        .step_by(2)
+        .map(|p0| {
+            format!(
+                "{op} {:>3},{:>3},    {after}",
+                format!("{reg}{p0}"),
+                format!("{reg}{}", p0 + 1)
+            )
+        })
+        .collect::<Vec<_>>();
+
+    if reverse {
+        ls.reverse();
+    }
+
+    ls.join("\n")
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_reg_op_pair() {
+        let want = "
+ldp  X1, X2,    [sp], #0x10
+ldp  X3, X4,    [sp], #0x10
+ldp  X5, X6,    [sp], #0x10
+ldp  X7, X8,    [sp], #0x10
+ldp  X9,X10,    [sp], #0x10
+ldp X11,X12,    [sp], #0x10
+ldp X13,X14,    [sp], #0x10
+ldp X15,X16,    [sp], #0x10
+ldp X17,X18,    [sp], #0x10
+ldp X19,X20,    [sp], #0x10
+ldp X21,X22,    [sp], #0x10
+ldp X23,X24,    [sp], #0x10
+ldp X25,X26,    [sp], #0x10
+ldp X27,X28,    [sp], #0x10
+ldp X29,X30,    [sp], #0x10
+";
+
+        let a_str = reg_op_pair("ldp", "X", 1..31, "[sp], #0x10", false);
+
+        println!("{a_str}");
+
+        assert_eq!(a_str.trim(), want.trim());
+    }
+}
diff --git a/crates/sparreal-macros/src/arch/mod.rs b/crates/sparreal-macros/src/arch/mod.rs
new file mode 100644
index 0000000..de0a2a6
--- /dev/null
+++ b/crates/sparreal-macros/src/arch/mod.rs
@@ -0,0 +1 @@
+pub mod aarch64;
diff --git a/crates/sparreal-macros/src/lib.rs b/crates/sparreal-macros/src/lib.rs
index f8cf27a..8047d81 100644
--- a/crates/sparreal-macros/src/lib.rs
+++ b/crates/sparreal-macros/src/lib.rs
@@ -7,13 +7,11 @@ extern crate proc_macro2;
 extern crate syn;
 
 mod api_trait;
+mod arch;
 
 use proc_macro::TokenStream;
-use proc_macro2::{Ident, Span};
-use syn::{
-    parse, spanned::Spanned, FnArg, ImplItem, ItemFn, ItemImpl, ItemTrait, Pat, PathArguments,
-    TraitItem, Type, Visibility,
-};
+use proc_macro2::Span;
+use syn::{FnArg, ItemFn, PathArguments, Type, Visibility, parse, spanned::Spanned};
 
 /// Attribute to declare the entry point of the program
 ///
@@ -113,7 +111,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
 
     quote!(
         #[allow(non_snake_case)]
-        #[no_mangle]
+        #[unsafe(no_mangle)]
         #(#attrs)*
         pub #unsafety extern "C" fn __sparreal_rt_main(#args) {
             #(#stmts)*
@@ -135,109 +133,61 @@ fn is_simple_type(ty: &Type, name: &str) -> bool {
     false
 }
 
-fn func_ident(trait_ident: &Ident, func_ident: &Ident) -> Ident {
-    let trait_ident = trait_ident.to_string().to_ascii_lowercase();
-    format_ident!("__sparreal_api_{}_{}", trait_ident, func_ident)
-}
+const NAMESPACE: &str = "sparreal_os";
 
 #[proc_macro_attribute]
-pub fn api_trait(_args: TokenStream, input: TokenStream) -> TokenStream {
-    let f = parse_macro_input!(input as ItemTrait);
-
-    let mut funcs = Vec::new();
-
-    for item in &f.items {
-        if let TraitItem::Fn(func) = item {
-            let ident = func.sig.ident.clone();
-            let inputs = func.sig.inputs.clone();
-            let output = func.sig.output.clone();
-
-            let api_name = func_ident(&f.ident, &ident);
-
-            let mut args = Vec::new();
-
-            for arg in &inputs {
-                if let FnArg::Typed(t) = arg {
-                    if let Pat::Ident(i) = t.pat.as_ref() {
-                        let ident = &i.ident;
-                        args.push(quote! { #ident , });
-                    }
-                }
-            }
-            funcs.push(quote! {
-
-                pub unsafe fn #ident (#inputs) #output{
-                    extern "Rust" {
-                        fn #api_name ( #inputs ) #output;
-                    }
+pub fn api_trait(_args: TokenStream, item: TokenStream) -> TokenStream {
+    abi_singleton::api_trait(item, NAMESPACE)
+}
 
-                    #api_name ( #(#args)* )
-                }
-            });
-        }
-    }
+#[proc_macro_attribute]
+pub fn api_impl(_args: TokenStream, item: TokenStream) -> TokenStream {
+    abi_singleton::api_impl(item, NAMESPACE)
+}
 
+#[proc_macro]
+pub fn build_test_setup(_input: TokenStream) -> TokenStream {
     quote! {
-        #f
-        #(#funcs)*
-
+    println!("cargo::rustc-link-arg-tests=-Tlink.x");
+    println!("cargo::rustc-link-arg-tests=-no-pie");
+    println!("cargo::rustc-link-arg-tests=-znostart-stop-gc");
     }
     .into()
 }
 
-#[proc_macro_attribute]
-pub fn api_impl(_args: TokenStream, input: TokenStream) -> TokenStream {
-    let f = parse_macro_input!(input as ItemImpl);
-
-    let mut funcs = Vec::new();
-
-    let ty = f.self_ty.clone();
-
-    for item in &f.items {
-        if let ImplItem::Fn(func) = item {
-            let ident = func.sig.ident.clone();
-            let inputs = func.sig.inputs.clone();
-            let output = func.sig.output.clone();
-
-            let api_name = func_ident(
-                f.trait_.clone().unwrap().1.get_ident().unwrap(),
-                &func.sig.ident,
-            );
-
-            let mut args = Vec::new();
-
-            for arg in &inputs {
-                if let FnArg::Typed(t) = arg {
-                    if let Pat::Ident(i) = t.pat.as_ref() {
-                        let ident = &i.ident;
-                        args.push(quote! { #ident , });
+#[proc_macro]
+pub fn module_driver(input: TokenStream) -> TokenStream {
+    let input = proc_macro2::TokenStream::from(input);
+    let mut name = None;
+
+    {
+        let mut it = input.clone().into_iter();
+        while let Some(t) = it.next() {
+            if let proc_macro2::TokenTree::Ident(i) = t {
+                if i == "name" {
+                    it.next();
+                    if let Some(proc_macro2::TokenTree::Literal(l)) = it.next() {
+                        let l = l.to_string();
+                        let l = l.trim_matches('"');
+                        name = Some(l.to_string());
+                        break;
                     }
                 }
             }
-
-            funcs.push(quote! {
-                #[no_mangle]
-                unsafe fn #api_name (#inputs) #output{
-                    #ty:: #ident ( #(#args)* )
-                }
-            });
         }
     }
 
-    quote! {
-        #f
-        #(#funcs)*
+    let st_name = name.unwrap_or_default().replace("-", "_").replace(" ", "_");
 
-    }
-    .into()
-}
+    let static_name = format_ident!("DRIVER_{}", st_name.to_uppercase());
 
-#[proc_macro]
-pub fn build_test_setup(_input: TokenStream) -> TokenStream {
     quote! {
-    println!("cargo::rustc-link-arg-tests=-Tlink.x");
-    println!("cargo::rustc-link-arg-tests=-no-pie");
-    println!("cargo::rustc-link-arg-tests=-znostart-stop-gc");
+        #[unsafe(link_section = ".driver.register")]
+        #[unsafe(no_mangle)]
+        #[used(linker)]
+        pub static #static_name: sparreal_kernel::driver_interface::DriverRegister = sparreal_kernel::driver_interface::DriverRegister{
+            #input
+        };
     }
     .into()
 }
diff --git a/crates/sparreal-macros/tests/test.rs b/crates/sparreal-macros/tests/test.rs
new file mode 100644
index 0000000..0bbac32
--- /dev/null
+++ b/crates/sparreal-macros/tests/test.rs
@@ -0,0 +1,4 @@
+#![feature(used_with_arg)]
+
+#[test]
+fn test_module() {}
diff --git a/crates/sparreal-rt/.gitignore b/crates/sparreal-rt/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/crates/sparreal-rt/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/crates/sparreal-rt/Cargo.toml b/crates/sparreal-rt/Cargo.toml
index bd675c8..5d5c7d7 100644
--- a/crates/sparreal-rt/Cargo.toml
+++ b/crates/sparreal-rt/Cargo.toml
@@ -1,9 +1,9 @@
 [package]
 name = "sparreal-rt"
-version = "0.2.0"
-authors = ["Zhourui <zrufo747@outlook.com>"]
-edition = "2021"
-repository = "https://github.com/qclic/sparreal-os"
+version.workspace = true
+authors = ["周睿 <zrufo747@outlook.com>"]
+edition = "2024"
+repository = "https://github.com/ZR233/sparreal-os"
 license = "MPL-2.0"
 description = "Sparreal OS Runtime"
 keywords = ["os"]
@@ -15,18 +15,16 @@ early-print = []
 
 [dependencies]
 log = "0.4"
-sparreal-kernel = { version = "0.1", path = "../sparreal-kernel", features = [
+page-table-generic = { version = "0.3" }
+futures = { version = "0.3", default-features = false, features = ["alloc"] }
+sparreal-macros = { version = "0.6", path = "../sparreal-macros" }
+sparreal-kernel = { version = "0.6", path = "../sparreal-kernel", features = [
     "mmu",
 ] }
-page-table-generic = { version = "0.2.2" }
-driver-interface = { version = "0.0.1", path = "../driver-interface" }
-futures = { version = "0.3", default-features = false, features = ["alloc"] }
-embedded-io = "0.6"
-memory_addr = "0.3"
-sparreal-macros = { version = "0.0.5", path = "../sparreal-macros" }
 bitflags = "2.6"
 fdt-parser = "0.4"
 dma-api = "0.2"
+buddy_system_allocator = "0.11"
 
 
 [target.'cfg(target_arch = "aarch64")'.dependencies]
@@ -34,5 +32,5 @@ aarch64-cpu = "10.0"
 tock-registers = "0.9"
 arm-pl011-rs = "0.2"
 arm-gic-driver = "0.3"
-# arm_pl031 = "0.2.1"
+arm_pl031 = "0.2.1"
 page-table-arm = { version = "0.1", path = "../page-table-arm" }
diff --git a/crates/sparreal-rt/build.rs b/crates/sparreal-rt/build.rs
index 4a261e7..0a5f311 100644
--- a/crates/sparreal-rt/build.rs
+++ b/crates/sparreal-rt/build.rs
@@ -12,8 +12,13 @@ fn main() {
     println!("cargo::rustc-link-arg=-znostart-stop-gc");
 
     println!("cargo:rustc-link-search={}", config.out_dir.display());
-    println!("cargo:rerun-if-changed=Link.ld");
-    // println!("cargo:rerun-if-changed=build.rs");
+    println!("cargo:rerun-if-changed=link.ld");
+    println!("cargo:rerun-if-changed=build.rs");
+
+    println!("cargo::rustc-check-cfg=cfg(hard_float)");
+    if std::env::var("TARGET").unwrap() == "aarch64-unknown-none" {
+        println!("cargo::rustc-cfg=hard_float");
+    }
 }
 #[derive(Debug)]
 pub enum Arch {
@@ -32,23 +37,25 @@ impl Default for Arch {
         }
     }
 }
+
 struct Config {
-    // smp: usize,
-    hart_stack_size: usize,
+    stack_size: usize,
     out_dir: PathBuf,
     arch: Arch,
 }
 
 // 8MiB stack size per hart
-const DEFAULT_HART_STACK_SIZE: usize = 8 * 1024 * 1024;
+const DEFAULT_KERNEL_STACK_SIZE: usize = 8 * 1024 * 1024;
 const KERNEL_VADDR: u64 = 0xffff_ff00_0008_0000;
+// const KERNEL_VADDR: u64 = 0x40080000;
+// const KERNEL_VADDR: u64 = 0x1000000;
 
 impl Config {
     fn new() -> Self {
         let arch = Arch::default();
 
         Self {
-            hart_stack_size: DEFAULT_HART_STACK_SIZE,
+            stack_size: DEFAULT_KERNEL_STACK_SIZE,
             out_dir: PathBuf::from(std::env::var("OUT_DIR").unwrap()),
             arch,
         }
@@ -63,24 +70,19 @@ impl Config {
             format!("{:?}", self.arch)
         };
 
-        let ld_content = std::fs::read_to_string("Link.ld").unwrap();
+        let ld_content = std::fs::read_to_string("link.ld").unwrap();
         let ld_content = ld_content.replace("%ARCH%", &output_arch);
         let ld_content = ld_content.replace("%KERNEL_VADDR%", &format!("{:#x}", KERNEL_VADDR));
-        let ld_content =
-            ld_content.replace("%STACK_SIZE%", &format!("{:#x}", self.hart_stack_size));
-        let ld_content =
-            ld_content.replace("%CPU_STACK_SIZE%", &format!("{:#x}", self.hart_stack_size));
+
+        let ld_content = ld_content.replace("%STACK_SIZE%", &format!("{:#x}", self.stack_size));
         std::fs::write(self.out_dir.join("link.x"), ld_content).expect("link.x write failed");
     }
 
     fn gen_const(&self) {
         let const_content = format!(
-            r#"
-
-            pub const SMP: usize = {:#x};
-            pub const HART_STACK_SIZE: usize = {:#x};
+            r#"pub const KERNEL_STACK_SIZE: usize = {:#x};
             "#,
-            1, self.hart_stack_size
+            self.stack_size
         );
 
         std::fs::write(self.out_dir.join("constant.rs"), const_content)
diff --git a/crates/sparreal-rt/Link.ld b/crates/sparreal-rt/link.ld
similarity index 73%
rename from crates/sparreal-rt/Link.ld
rename to crates/sparreal-rt/link.ld
index 1571863..d2936bd 100644
--- a/crates/sparreal-rt/Link.ld
+++ b/crates/sparreal-rt/link.ld
@@ -2,15 +2,7 @@ OUTPUT_ARCH(%ARCH%)
 
 ENTRY(_start)
 
-/* Define the program headers we want so the bootloader gives us the right */
-/* MMU permissions; this also allows us to exert more control over the linking */
-/* process. */
-PHDRS
-{
-    text    PT_LOAD;
-    rodata  PT_LOAD;
-    data    PT_LOAD;
-}
+
 
 SECTIONS
 {
@@ -19,14 +11,14 @@ SECTIONS
 
     .text : ALIGN(4K) {
         _stext = .;
-        KEEP(*(.head.text))
+        KEEP(*(.text.head))
         KEEP(*(.text.boot.start))
         KEEP(*(.text.boot .text.boot.*))
         . = ALIGN(4);
         *(.text .text.*);
         . = ALIGN(4K);
         _etext = .;
-    } :text
+    } 
 
     .rodata : ALIGN(4K) {
         _srodata = .;
@@ -35,8 +27,14 @@ SECTIONS
         *(.sdata2 .sdata2.*)
         . = ALIGN(4K);
         _erodata = .;
-    } :rodata
+    } 
 
+    .driver.register : ALIGN(4K) {
+        _sdriver = .;
+        *(.driver.register .driver.register.*)
+        _edriver = .;
+        . = ALIGN(4K);
+    }
    
     .data : ALIGN(4K) {
         _sdata = .;
@@ -45,20 +43,20 @@ SECTIONS
         *(.data .data.*)
         *(.sdata .sdata.*)
         *(.got .got.*)
-    } :data
+    } 
 
     .tdata : ALIGN(0x10) {
         _stdata = .;
         *(.tdata .tdata.*)
         _etdata = .;
-    } :data
+    } 
 
     .tbss : ALIGN(0x10) {
         _stbss = .;
         *(.tbss .tbss.*)
         *(.tcommon)
         _etbss = .;
-    } :data
+    } 
 
     . = ALIGN(4K);
     _edata = .;
@@ -70,14 +68,14 @@ SECTIONS
         *(COMMON)
         . = ALIGN(4K);
         _ebss = .;
-    } :data
+    } 
 
     _ekernel = .;
+    _kernel_size = _ekernel - _skernel;
 
     . = ALIGN(4K);
+    _stack_bottom = .;
     _stack_top = . + %STACK_SIZE%;
-    _cpu_stack_size = %CPU_STACK_SIZE%;
-    _kernel_size = _stack_top - _skernel;
 	/DISCARD/ : {
         *(.comment) *(.gnu*) *(.note*) *(.eh_frame*)
     }
diff --git a/crates/sparreal-rt/src/arch/aarch64/boot.rs b/crates/sparreal-rt/src/arch/aarch64/boot.rs
index a47f411..edd258f 100644
--- a/crates/sparreal-rt/src/arch/aarch64/boot.rs
+++ b/crates/sparreal-rt/src/arch/aarch64/boot.rs
@@ -1,187 +1,38 @@
 use core::{
     arch::{asm, global_asm},
-    cell::UnsafeCell,
-    ptr::{slice_from_raw_parts_mut, NonNull},
+    ptr::NonNull,
 };
 
-use aarch64_cpu::{asm::barrier, registers::*};
-use fdt_parser::Fdt;
-use kernel::{BootConfig, MemoryReservedRange};
-use mem::*;
-use page_table_generic::{AccessSetting, CacheSetting};
-use platform::PlatformPageTable;
-use sparreal_kernel::*;
-use tock_registers::interfaces::ReadWriteable;
+use crate::mem::clear_bss;
+use aarch64_cpu::registers::*;
+use sparreal_kernel::{io::print::*, platform::PlatformInfoKind};
 
-use crate::{
-    arch::{
-        debug::{init_debug, mmu_add_offset},
-        mmu::PageTableImpl,
-    },
-    consts::*,
-};
-
-use super::mmu;
-
-global_asm!(include_str!("boot.S"));
-global_asm!(include_str!("vectors.S"));
-
-extern "C" {
-    fn _skernel();
-    fn _ekernel();
-    fn _stack_top();
-}
-
-pub(crate) static BOOT_INFO: BootInfoWapper = BootInfoWapper::new();
-
-#[no_mangle]
-unsafe extern "C" fn __rust_main(dtb_addr: usize, va_offset: usize) -> ! {
-    clear_bss();
-    print_info(dtb_addr, va_offset);
-    BOOT_INFO.as_mut().va_offset = va_offset;
-
-    let mut kernel_end = Phys::from(_ekernel as *const u8);
-
-    let new_dtb_addr = sparreal_kernel::driver::move_dtb(
-        dtb_addr as _,
-        NonNull::new_unchecked(kernel_end.as_usize() as _),
-    );
-
-    if let Some(addr) = new_dtb_addr {
-        BOOT_INFO.as_mut().fdt_addr = addr.as_ptr() as usize;
-
-        dbg!("DTB moved to ");
-        dbg_hex!(BOOT_INFO.as_ref().fdt_addr);
-        dbg!(", size: ");
-        dbg_hexln!(addr.len());
-        kernel_end = kernel_end + addr.len();
-    }
-
-    dbg!("Kernel @");
-    dbg_hexln!(_skernel as *const u8 as usize);
-
-    let kernel_start = Phys::from(_skernel as *const u8).align_down(BYTES_1M * 2);
-    let kernel_size = kernel_end - kernel_start;
-
-    if let Err(msg) = config_memory_by_fdt(kernel_start, kernel_size) {
-        dbgln!(msg);
-
-        BOOT_INFO.as_mut().main_memory.start = kernel_start;
-        BOOT_INFO.as_mut().main_memory_heap_offset = kernel_size;
-        BOOT_INFO.as_mut().main_memory.size =
-            BOOT_INFO.as_ref().main_memory_heap_offset + BYTES_1M * 16;
-    }
-
-    let table = mmu::init_boot_table();
-
-    dbgln!("table initialized");
-
-    // Enable TTBR0 and TTBR1 walks, page size = 4K, vaddr size = 48 bits, paddr size = 40 bits.
-    let tcr_flags0 = TCR_EL1::EPD0::EnableTTBR0Walks
-        + TCR_EL1::TG0::KiB_4
-        + TCR_EL1::SH0::Inner
-        + TCR_EL1::ORGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
-        + TCR_EL1::IRGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
-        + TCR_EL1::T0SZ.val(16);
-    let tcr_flags1 = TCR_EL1::EPD1::EnableTTBR1Walks
-        + TCR_EL1::TG1::KiB_4
-        + TCR_EL1::SH1::Inner
-        + TCR_EL1::ORGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable
-        + TCR_EL1::IRGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable
-        + TCR_EL1::T1SZ.val(16);
-    TCR_EL1.write(TCR_EL1::IPS::Bits_48 + tcr_flags0 + tcr_flags1);
-
-    // 需要先清缓存
-    PageTableImpl::flush_tlb(None);
+global_asm!(include_str!("boot.s"));
 
-    // Set both TTBR0 and TTBR1
-    TTBR1_EL1.set_baddr(table);
-    TTBR0_EL1.set_baddr(table);
+#[unsafe(no_mangle)]
+extern "C" fn __rust_boot(va_offset: usize, fdt_addr: usize) {
+    unsafe {
+        clear_bss();
 
-    BOOT_INFO.as_mut().stack_top =
-        BOOT_INFO.as_ref().main_memory.start + BOOT_INFO.as_ref().main_memory.size;
+        let platform_info: PlatformInfoKind = if let Some(addr) = NonNull::new(fdt_addr as _) {
+            PlatformInfoKind::new_fdt(addr)
+        } else {
+            todo!()
+        };
 
-    let stack_top = BOOT_INFO.as_ref().stack_top.as_usize() + va_offset;
-
-    dbg!("stack top: ");
-    dbg_hexln!(stack_top);
-    dbg!("TCR_EL1:");
-    dbg_hexln!(TCR_EL1.get());
-    dbgln!("table set");
-
-    mmu_add_offset(va_offset);
-    if BOOT_INFO.as_ref().fdt_addr > 0 {
-        BOOT_INFO.as_mut().fdt_addr += va_offset;
-    }
-    PageTableImpl::flush_tlb(None);
-    // Enable the MMU and turn on I-cache and D-cache
-    SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
-    barrier::isb(barrier::SY);
-
-    asm!("
-    MOV  sp,  {sp_top}
-    ADD  x30, x30, {offset}
-    LDR      x8, =__rust_main_after_mmu
-    BLR      x8
-    B       .
-    ", 
-    sp_top = in(reg) stack_top,
-    offset = in(reg) va_offset,
-    options(noreturn)
-    )
-}
-
-#[no_mangle]
-unsafe extern "C" fn __rust_main_after_mmu() -> ! {
-    dbgln!("MMU enabled");
-
-    let cfg = KernelConfig {
-        boot_info: BOOT_INFO.to_boot_config(),
-        stack_top: BOOT_INFO.as_ref().stack_top,
-        dtb_addr: NonNull::new(BOOT_INFO.as_ref().fdt_addr as _),
-    };
-
-    crate::boot(cfg);
-}
+        if let Some(info) = platform_info.debugcon() {
+            crate::debug::init_by_info(info);
+        }
 
-unsafe fn clear_bss() {
-    extern "C" {
-        fn _sbss();
-        fn _ebss();
-    }
-    let bss = &mut *slice_from_raw_parts_mut(_sbss as *mut u8, _ebss as usize - _sbss as usize);
-    bss.fill(0);
-}
+        let rsv = [];
 
-unsafe fn print_info(dtb_addr: usize, va_offset: usize) {
-    if let Some(dtb) = NonNull::new(dtb_addr as *mut u8) {
-        if let Some(reg) = util::boot::stdout_reg(dtb) {
-            BOOT_INFO.as_mut().early_debug_reg = Some(MemoryRange {
-                start: reg.reg.into(),
-                size: reg.size,
-            });
-            init_debug(reg);
+        if let Err(s) = sparreal_kernel::boot::start(va_offset, platform_info, &rsv) {
+            early_dbgln(s);
         }
     }
-    if let Some(dtb) = NonNull::new(dtb_addr as *mut u8) {
-        if let Ok(fdt) = fdt_parser::Fdt::from_ptr(dtb) {
-            let cpu = fdt.boot_cpuid_phys();
-            dbg!("DTB boot CPU: ");
-            dbg_hexln!(cpu);
-        }
-    }
-
-    dbg!("dtb @");
-    dbg_hex!(dtb_addr);
-    dbg!(" va_offset: ");
-    dbg_hexln!(va_offset);
 }
 
-fn device_tree() -> Option<Fdt<'static>> {
-    Fdt::from_ptr(NonNull::new(BOOT_INFO.as_ref().fdt_addr as _)?).ok()
-}
-
-#[no_mangle]
+#[unsafe(no_mangle)]
 unsafe extern "C" fn __switch_to_el1() {
     SPSel.write(SPSel::SP::ELx);
     SP_EL0.set(0);
@@ -200,12 +51,14 @@ unsafe extern "C" fn __switch_to_el1() {
                     + SPSR_EL3::I::Masked
                     + SPSR_EL3::F::Masked,
             );
-            asm!(
-                "
+            unsafe {
+                asm!(
+                    "
             adr      x2, _start_boot
             msr elr_el3, x2
             "
-            );
+                );
+            }
         }
         // Disable EL1 timer traps and the timer offset.
         CNTHCTL_EL2.modify(CNTHCTL_EL2::EL1PCEN::SET + CNTHCTL_EL2::EL1PCTEN::SET);
@@ -220,9 +73,9 @@ unsafe extern "C" fn __switch_to_el1() {
                 + SPSR_EL2::I::Masked
                 + SPSR_EL2::F::Masked,
         );
-
-        asm!(
-            "
+        unsafe {
+            asm!(
+                "
             mov     x8, sp
             msr     sp_el1, x8
             MOV      x0, x19
@@ -230,113 +83,9 @@ unsafe extern "C" fn __switch_to_el1() {
             msr      elr_el2, x2
             eret
             "
-        );
-    } else {
-        asm!("bl _el1_entry")
-    }
-}
-
-unsafe fn config_memory_by_fdt(
-    kernel_start: Phys<u8>,
-    kernel_size: usize,
-) -> Result<(), &'static str> {
-    let fdt = device_tree().ok_or("FDT not found")?;
-
-    for node in fdt.memory() {
-        for region in node.regions() {
-            let address = region.address as usize;
-            dbg!("memory @");
-            dbg_hex!(address);
-            dbg!(", size: ");
-            dbg_hexln!(region.size);
-
-            if address <= kernel_start.as_usize() && kernel_start.as_usize() < address + region.size
-            {
-                BOOT_INFO.as_mut().main_memory.start = address.into();
-                BOOT_INFO.as_mut().main_memory.size = region.size;
-                BOOT_INFO.as_mut().main_memory_heap_offset =
-                    kernel_start.as_usize() + kernel_size - address;
-
-                dbg!("Kernel start: ");
-                dbg_hex!(kernel_start.as_usize());
-                dbg!(", Kernel is in this memory, used: ");
-                dbg_hexln!(BOOT_INFO.as_ref().main_memory_heap_offset);
-
-                return Ok(());
-            }
-        }
-    }
-    if BOOT_INFO.as_mut().main_memory.size == 0 {
-        Err("No memory region found")
+            )
+        };
     } else {
-        Ok(())
-    }
-}
-
-pub(crate) struct BootInfoWapper(UnsafeCell<BootInfo>);
-
-unsafe impl Sync for BootInfoWapper {}
-
-impl BootInfoWapper {
-    pub const fn new() -> Self {
-        Self(UnsafeCell::new(BootInfo::new()))
-    }
-
-    #[allow(clippy::mut_from_ref)]
-    pub unsafe fn as_mut(&self) -> &mut BootInfo {
-        &mut *self.0.get()
-    }
-
-    pub fn as_ref(&self) -> &BootInfo {
-        unsafe { &*self.0.get() }
-    }
-
-    pub fn to_boot_config(&self) -> BootConfig {
-        self.as_ref().to_boot_config()
-    }
-}
-
-pub(crate) struct BootInfo {
-    va_offset: usize,
-    fdt_addr: usize,
-    main_memory: MemoryRange,
-    main_memory_heap_offset: usize,
-    early_debug_reg: Option<MemoryRange>,
-    stack_top: Phys<u8>,
-}
-
-unsafe impl Send for BootInfo {}
-
-impl BootInfo {
-    const fn new() -> Self {
-        Self {
-            va_offset: 0,
-            fdt_addr: 0,
-            main_memory: MemoryRange::new(),
-            main_memory_heap_offset: 0,
-            early_debug_reg: None,
-            stack_top: Phys::new(),
-        }
-    }
-
-    pub fn to_boot_config(&self) -> BootConfig {
-        let mut reserved_memory = [None; 24];
-
-        if let Some(reg) = self.early_debug_reg {
-            reserved_memory[0] = Some(MemoryReservedRange {
-                start: reg.start,
-                size: reg.size,
-                access: AccessSetting::Read | AccessSetting::Write,
-                cache: CacheSetting::Device,
-                name: "debug uart",
-            });
-        }
-        BootConfig {
-            main_memory: self.main_memory,
-            main_memory_heap_offset: self.main_memory_heap_offset,
-            hart_stack_size: HART_STACK_SIZE,
-            reserved_memory,
-            va_offset: self.va_offset,
-        }
+        unsafe { asm!("bl _el1_entry") }
     }
 }
diff --git a/crates/sparreal-rt/src/arch/aarch64/boot.S b/crates/sparreal-rt/src/arch/aarch64/boot.s
similarity index 65%
rename from crates/sparreal-rt/src/arch/aarch64/boot.S
rename to crates/sparreal-rt/src/arch/aarch64/boot.s
index a677374..905e9a1 100644
--- a/crates/sparreal-rt/src/arch/aarch64/boot.S
+++ b/crates/sparreal-rt/src/arch/aarch64/boot.s
@@ -1,4 +1,4 @@
-.section ".head.text","ax"
+.section ".text.head","ax"
 .global _start
 
 // Linux header
@@ -39,31 +39,40 @@ _start_boot:
 
   MOV      x19, x0        // x19 = dtb_addr
 
+  // // 获取当前CPU ID
+  // MRS      x2, mpidr_el1
+  // AND      x2, x2, #0xFF // 只保留CPU ID部分
+
+  // // 设备树中的start cpuid存储在设备树的偏移量处
+  // ADD      x3, x19, #0x28
+  // LDR      x4, [x3] // x4 = start cpuid from dtb
+
+  // // 比较当前CPU ID和start cpuid
+  // CMP      x2, x4
+  // BNE      .wfi_loop // 如果不相等,跳转到wfi循环
+
   LDR      x1, =_stack_top
   SUB      x1, x1, x18 // X1 == STACK_TOP
   MOV      sp, x1
-
   BL       __switch_to_el1
 
-.global _el1_entry
-.type _el1_entry, @function
+
 _el1_entry:
   // Install vector table
   // --------------------- 
   .global  vector_table_el1
   LDR      x0, =vector_table_el1
   MSR      VBAR_EL1, x0
-  
+
   MOV      X1, #(0x3 << 20) // FPEN disables trapping to EL1.
   MSR      CPACR_EL1, X1
   ISB
 
-  MOV      x0, x19
-  MOV      x1, x18
-  BL       __rust_main
-  B        .
+  MOV      x0, x18
+  MOV      x1, x19
 
+  BL       __rust_boot
 
-_suspend:
-  wfi
-  B _suspend
\ No newline at end of file
+.wfi_loop:
+  WFI // 等待中断
+  B       .wfi_loop // 无限循环等待中断  
\ No newline at end of file
diff --git a/crates/sparreal-rt/src/arch/aarch64/cache.rs b/crates/sparreal-rt/src/arch/aarch64/cache.rs
index 9e48c25..1b1e760 100644
--- a/crates/sparreal-rt/src/arch/aarch64/cache.rs
+++ b/crates/sparreal-rt/src/arch/aarch64/cache.rs
@@ -1,7 +1,10 @@
-use core::{arch::asm, ptr::NonNull};
+#![allow(unused)]
 
-use dma_api::Impl;
-use sparreal_kernel::mem::{mmu::va_offset, Virt};
+use core::arch::asm;
+
+use aarch64_cpu::{asm::barrier::*, registers::*};
+
+use super::CacheOp;
 
 #[inline(always)]
 fn cache_line_size() -> usize {
@@ -14,78 +17,91 @@ fn cache_line_size() -> usize {
     }
 }
 
-struct DCacheIter {
-    aligned_addr: usize,
-    end: usize,
-    cache_line_size: usize,
-}
+/// Performs a cache operation on all memory.
+pub fn dcache_all(op: CacheOp) {
+    let clidr = CLIDR_EL1.get();
 
-impl DCacheIter {
-    fn new(addr: NonNull<u8>, size: usize) -> DCacheIter {
-        let start = addr.as_ptr() as usize;
-        let end = start + size;
-        let cache_line_size = cache_line_size();
-
-        let aligned_addr = addr.as_ptr() as usize & !(cache_line_size - 1);
-        DCacheIter {
-            aligned_addr,
-            end,
-            cache_line_size,
+    for level in 0..8 {
+        let ty = (clidr >> (level * 3)) & 0b111;
+        if ty == 0 {
+            return;
         }
+
+        dcache_level(op, level);
     }
+    dsb(SY);
+    isb(SY);
 }
 
-impl Iterator for DCacheIter {
-    type Item = usize;
+/// Performs a cache operation on a range of memory.
+#[inline]
+pub fn dcache_range(op: CacheOp, addr: usize, size: usize) {
+    let start = addr;
+    let end = start + size;
+    let cache_line_size = cache_line_size();
 
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.aligned_addr < self.end {
-            let addr = self.aligned_addr;
-            self.aligned_addr += self.cache_line_size;
-            Some(addr)
-        } else {
-            None
-        }
+    let mut aligned_addr = addr & !(cache_line_size - 1);
+
+    while aligned_addr < end {
+        _dcache_line(op, aligned_addr);
+        aligned_addr += cache_line_size;
     }
+
+    dsb(SY);
+    isb(SY);
 }
 
-/// Invalidate data cache
-pub fn dcache_invalidate_range(addr: NonNull<u8>, size: usize) {
+/// Performs a cache operation on a cache line.
+#[inline]
+fn _dcache_line(op: CacheOp, addr: usize) {
     unsafe {
-        for addr in DCacheIter::new(addr, size) {
-            asm!("dc ivac, {}", in(reg) addr);
+        match op {
+            CacheOp::Invalidate => asm!("dc ivac, {0}", in(reg) addr),
+            CacheOp::Clean => asm!("dc cvac, {0}", in(reg) addr),
+            CacheOp::CleanAndInvalidate => asm!("dc civac, {0}", in(reg) addr),
         }
-        asm!("dsb sy");
     }
 }
 
-/// Flush data cache
-pub fn dcache_flush_range(addr: NonNull<u8>, size: usize) {
-    unsafe {
-        for addr in DCacheIter::new(addr, size) {
-            asm!("dc civac, {}", in(reg) addr);
-        }
-        asm!("dsb sy");
-    }
+/// Performs a cache operation on a cache line.
+#[inline]
+pub fn dcache_line(op: CacheOp, addr: usize) {
+    _dcache_line(op, addr);
+    dsb(SY);
+    isb(SY);
 }
 
-struct DMAImpl;
+/// Performs a cache operation on a cache level.
+/// https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Instructions/DC-CISW--Data-or-unified-Cache-line-Clean-and-Invalidate-by-Set-Way
+#[inline]
+fn dcache_level(op: CacheOp, level: u64) {
+    assert!(level < 8, "armv8 level range is 0-7");
 
-impl Impl for DMAImpl {
-    fn map(addr: NonNull<u8>, _size: usize, _direction: dma_api::Direction) -> u64 {
-        let p: Virt<u8> = Virt::from(addr.as_ptr());
-        p.convert_to_phys(va_offset()).as_usize() as _
-    }
+    isb(SY);
+    CSSELR_EL1.write(CSSELR_EL1::InD::Data + CSSELR_EL1::Level.val(level));
+    isb(SY);
+    let lines = CCSIDR_EL1.read(CCSIDR_EL1::LineSize) as u32;
+    let ways = CCSIDR_EL1.read(CCSIDR_EL1::AssociativityWithCCIDX) as u32;
+    let sets = CCSIDR_EL1.read(CCSIDR_EL1::NumSetsWithCCIDX) as u32;
 
-    fn unmap(_addr: NonNull<u8>, _size: usize) {}
+    let l = lines + 4;
 
-    fn flush(addr: NonNull<u8>, size: usize) {
-        dcache_flush_range(addr, size);
-    }
+    // Calculate bit position of number of ways
+    let way_adjust = ways.leading_zeros();
 
-    fn invalidate(addr: NonNull<u8>, size: usize) {
-        dcache_invalidate_range(addr, size);
+    // Loop over sets and ways
+    for set in 0..sets {
+        for way in 0..ways {
+            let set_way = (way << way_adjust) | (set << l);
+
+            let cisw = (level << 1) | set_way as u64;
+            unsafe {
+                match op {
+                    CacheOp::Invalidate => asm!("dc isw, {0}", in(reg) cisw),
+                    CacheOp::Clean => asm!("dc csw, {0}", in(reg) cisw),
+                    CacheOp::CleanAndInvalidate => asm!("dc cisw, {0}", in(reg) cisw),
+                }
+            }
+        }
     }
 }
-
-dma_api::set_impl!(DMAImpl);
diff --git a/crates/sparreal-rt/src/arch/aarch64/debug.rs b/crates/sparreal-rt/src/arch/aarch64/debug.rs
deleted file mode 100644
index bd5c4b9..0000000
--- a/crates/sparreal-rt/src/arch/aarch64/debug.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use sparreal_kernel::util::boot::StdoutReg;
-
-static mut OUT_REG: usize = 0;
-
-pub unsafe fn mmu_add_offset(va_offset: usize) {
-    OUT_REG += va_offset;
-}
-
-#[cfg(feature = "early-print")]
-pub unsafe fn put_debug(char: u8) {
-    if OUT_REG == 0 {
-        return;
-    }
-    let base = OUT_REG;
-
-    let state = (base + 0x18) as *mut u8;
-    let put = (base) as *mut u8;
-    while (state.read_volatile() & 0x20_u8) != 0 {}
-    put.write_volatile(char);
-}
-
-pub fn init_debug(stdout: StdoutReg) {
-    unsafe { OUT_REG = stdout.reg as usize };
-}
diff --git a/crates/sparreal-rt/src/arch/aarch64/gic/gic_v2.rs b/crates/sparreal-rt/src/arch/aarch64/gic/gic_v2.rs
new file mode 100644
index 0000000..08e7c24
--- /dev/null
+++ b/crates/sparreal-rt/src/arch/aarch64/gic/gic_v2.rs
@@ -0,0 +1,131 @@
+use alloc::{boxed::Box, format, sync::Arc, vec::Vec};
+use core::{cell::UnsafeCell, error::Error, ptr::NonNull};
+
+use arm_gic_driver::GicGeneric;
+use sparreal_kernel::{
+    driver_interface::{DriverGeneric, ProbeFnKind, RegAddress, interrupt_controller::*},
+    mem::iomap,
+};
+use sparreal_macros::module_driver;
+
+use super::*;
+
+module_driver!(
+    name: "GICv2",
+    compatibles: &["arm,cortex-a15-gic", "arm,gic-400"],
+    probe: ProbeFnKind::InterruptController(probe_gic_v2),
+);
+
+struct GicV2 {
+    gicd: NonNull<u8>,
+    gicc: NonNull<u8>,
+    gic: Arc<UnsafeCell<Option<arm_gic_driver::GicV2>>>,
+}
+
+unsafe impl Send for GicV2 {}
+
+impl GicV2 {
+    #[allow(clippy::arc_with_non_send_sync)]
+    fn new(gicd: NonNull<u8>, gicc: NonNull<u8>) -> Self {
+        Self {
+            gic: Arc::new(UnsafeCell::new(None)),
+            gicd,
+            gicc,
+        }
+    }
+}
+
+struct GicV2PerCpu(Arc<UnsafeCell<Option<arm_gic_driver::GicV2>>>);
+
+unsafe impl Send for GicV2PerCpu {}
+
+impl GicV2PerCpu {
+    fn get_mut(&mut self) -> &mut arm_gic_driver::GicV2 {
+        unsafe { &mut *self.0.get() }.as_mut().unwrap()
+    }
+}
+
+impl InterfaceCPU for GicV2PerCpu {
+    fn get_and_acknowledge_interrupt(&mut self) -> Option<IrqId> {
+        self.get_mut()
+            .get_and_acknowledge_interrupt()
+            .map(|id| (id.to_u32() as usize).into())
+    }
+
+    fn end_interrupt(&mut self, irq: IrqId) {
+        self.get_mut().end_interrupt(convert_id(irq));
+    }
+
+    fn irq_enable(&mut self, irq: IrqId) {
+        self.get_mut().irq_enable(convert_id(irq));
+    }
+
+    fn irq_disable(&mut self, irq: IrqId) {
+        self.get_mut().irq_disable(convert_id(irq));
+    }
+
+    fn set_priority(&mut self, irq: IrqId, priority: usize) {
+        self.get_mut().set_priority(convert_id(irq), priority);
+    }
+
+    fn set_trigger(&mut self, irq: IrqId, trigger: Trigger) {
+        self.get_mut().set_trigger(convert_id(irq), match trigger {
+            Trigger::EdgeBoth => arm_gic_driver::Trigger::Edge,
+            Trigger::EdgeRising => arm_gic_driver::Trigger::Edge,
+            Trigger::EdgeFailling => arm_gic_driver::Trigger::Edge,
+            Trigger::LevelHigh => arm_gic_driver::Trigger::Level,
+            Trigger::LevelLow => arm_gic_driver::Trigger::Level,
+        });
+    }
+
+    fn set_bind_cpu(&mut self, irq: IrqId, cpu_list: &[CpuId]) {
+        let id_list = cpu_list
+            .iter()
+            .map(|v| arm_gic_driver::MPID::from(Into::<usize>::into(*v)))
+            .map(|v| v.into())
+            .collect::<Vec<_>>();
+
+        self.get_mut().set_bind_cpu(convert_id(irq), &id_list);
+    }
+
+    fn parse_fdt_config(&self, prop_interupt: &[u32]) -> Result<IrqConfig, Box<dyn Error>> {
+        fdt_parse_irq_config(prop_interupt)
+    }
+
+    fn irq_pin_to_id(&self, pin: usize) -> Result<IrqId, Box<dyn Error>> {
+        super::irq_pin_to_id(pin)
+    }
+}
+
+impl DriverGeneric for GicV2 {
+    fn open(&mut self) -> Result<(), alloc::string::String> {
+        let gic =
+            arm_gic_driver::GicV2::new(self.gicd, self.gicc).map_err(|e| format!("{:?}", e))?;
+        unsafe { &mut *self.gic.get() }.replace(gic);
+
+        Ok(())
+    }
+
+    fn close(&mut self) -> Result<(), alloc::string::String> {
+        Ok(())
+    }
+}
+
+impl Interface for GicV2 {
+    fn current_cpu_setup(&self) -> Box<dyn InterfaceCPU> {
+        unsafe { &mut *self.gic.get() }
+            .as_mut()
+            .unwrap()
+            .current_cpu_setup();
+        Box::new(GicV2PerCpu(self.gic.clone()))
+    }
+}
+
+fn probe_gic_v2(regs: Vec<RegAddress>) -> Hardware {
+    let gicd_reg = regs[0];
+    let gicc_reg = regs[1];
+    let gicd = iomap(gicd_reg.addr.into(), gicd_reg.size.unwrap_or(0x1000));
+    let gicc = iomap(gicc_reg.addr.into(), gicc_reg.size.unwrap_or(0x1000));
+
+    Box::new(GicV2::new(gicd, gicc))
+}
diff --git a/crates/sparreal-rt/src/arch/aarch64/gic/gic_v3.rs b/crates/sparreal-rt/src/arch/aarch64/gic/gic_v3.rs
new file mode 100644
index 0000000..608f233
--- /dev/null
+++ b/crates/sparreal-rt/src/arch/aarch64/gic/gic_v3.rs
@@ -0,0 +1,137 @@
+use core::{cell::UnsafeCell, error::Error, ptr::NonNull};
+
+use alloc::{boxed::Box, format, sync::Arc, vec::Vec};
+use arm_gic_driver::{GicGeneric, GicV3, Trigger};
+use sparreal_kernel::{
+    driver_interface::{
+        DriverGeneric, ProbeFnKind, RegAddress,
+        interrupt_controller::{self, CpuId, InterfaceCPU},
+    },
+    mem::iomap,
+};
+use sparreal_macros::module_driver;
+
+use super::*;
+
+module_driver!(
+    name: "GICv3",
+    compatibles: &["arm,gic-v3"],
+    probe: ProbeFnKind::InterruptController(probe_gic),
+);
+
+struct Gic {
+    gicd: NonNull<u8>,
+    gicr: NonNull<u8>,
+    gic: Arc<UnsafeCell<Option<GicV3>>>,
+}
+
+unsafe impl Send for Gic {}
+
+impl Gic {
+    #[allow(clippy::arc_with_non_send_sync)]
+    fn new(gicd: NonNull<u8>, gicr: NonNull<u8>) -> Self {
+        Self {
+            gic: Arc::new(UnsafeCell::new(None)),
+            gicd,
+            gicr,
+        }
+    }
+}
+
+struct GicPerCpu(Arc<UnsafeCell<Option<GicV3>>>);
+
+unsafe impl Send for GicPerCpu {}
+
+impl GicPerCpu {
+    fn get_mut(&mut self) -> &mut GicV3 {
+        unsafe { &mut *self.0.get() }.as_mut().unwrap()
+    }
+}
+
+impl InterfaceCPU for GicPerCpu {
+    fn get_and_acknowledge_interrupt(&mut self) -> Option<interrupt_controller::IrqId> {
+        self.get_mut()
+            .get_and_acknowledge_interrupt()
+            .map(|id| (id.to_u32() as usize).into())
+    }
+
+    fn end_interrupt(&mut self, irq: interrupt_controller::IrqId) {
+        self.get_mut().end_interrupt(convert_id(irq));
+    }
+
+    fn irq_enable(&mut self, irq: interrupt_controller::IrqId) {
+        self.get_mut().irq_enable(convert_id(irq));
+    }
+
+    fn irq_disable(&mut self, irq: interrupt_controller::IrqId) {
+        self.get_mut().irq_disable(convert_id(irq));
+    }
+
+    fn set_priority(&mut self, irq: interrupt_controller::IrqId, priority: usize) {
+        self.get_mut().set_priority(convert_id(irq), priority);
+    }
+
+    fn set_trigger(
+        &mut self,
+        irq: interrupt_controller::IrqId,
+        trigger: interrupt_controller::Trigger,
+    ) {
+        self.get_mut().set_trigger(convert_id(irq), match trigger {
+            interrupt_controller::Trigger::EdgeBoth => Trigger::Edge,
+            interrupt_controller::Trigger::EdgeRising => Trigger::Edge,
+            interrupt_controller::Trigger::EdgeFailling => Trigger::Edge,
+            interrupt_controller::Trigger::LevelHigh => Trigger::Level,
+            interrupt_controller::Trigger::LevelLow => Trigger::Level,
+        });
+    }
+
+    fn set_bind_cpu(&mut self, irq: interrupt_controller::IrqId, cpu_list: &[CpuId]) {
+        let id_list = cpu_list
+            .iter()
+            .map(|v| arm_gic_driver::MPID::from(Into::<usize>::into(*v)))
+            .map(|v| v.into())
+            .collect::<Vec<_>>();
+
+        self.get_mut().set_bind_cpu(convert_id(irq), &id_list);
+    }
+
+    fn parse_fdt_config(&self, prop_interupt: &[u32]) -> Result<IrqConfig, Box<dyn Error>> {
+        fdt_parse_irq_config(prop_interupt)
+    }
+
+    fn irq_pin_to_id(&self, pin: usize) -> Result<IrqId, Box<dyn Error>> {
+        super::irq_pin_to_id(pin)
+    }
+}
+
+impl DriverGeneric for Gic {
+    fn open(&mut self) -> Result<(), alloc::string::String> {
+        let gic = GicV3::new(self.gicd, self.gicr).map_err(|e| format!("{:?}", e))?;
+        unsafe { &mut *self.gic.get() }.replace(gic);
+
+        Ok(())
+    }
+
+    fn close(&mut self) -> Result<(), alloc::string::String> {
+        Ok(())
+    }
+}
+
+impl interrupt_controller::Interface for Gic {
+    fn current_cpu_setup(&self) -> Box<dyn interrupt_controller::InterfaceCPU> {
+        unsafe { &mut *self.gic.get() }
+            .as_mut()
+            .unwrap()
+            .current_cpu_setup();
+        Box::new(GicPerCpu(self.gic.clone()))
+    }
+}
+
+fn probe_gic(regs: Vec<RegAddress>) -> interrupt_controller::Hardware {
+    let gicd_reg = regs[0];
+    let gicc_reg = regs[1];
+    let gicd = iomap(gicd_reg.addr.into(), gicd_reg.size.unwrap_or(0x1000));
+    let gicr = iomap(gicc_reg.addr.into(), gicc_reg.size.unwrap_or(0x1000));
+
+    Box::new(Gic::new(gicd, gicr))
+}
diff --git a/crates/sparreal-rt/src/arch/aarch64/gic/mod.rs b/crates/sparreal-rt/src/arch/aarch64/gic/mod.rs
new file mode 100644
index 0000000..05edd7a
--- /dev/null
+++ b/crates/sparreal-rt/src/arch/aarch64/gic/mod.rs
@@ -0,0 +1,69 @@
+use core::error::Error;
+
+use alloc::boxed::Box;
+use arm_gic_driver::IntId;
+use sparreal_kernel::driver_interface::interrupt_controller::{IrqConfig, IrqId, Trigger};
+
+mod gic_v2;
+mod gic_v3;
+
+fn convert_id(irq: IrqId) -> IntId {
+    let id: usize = irq.into();
+    unsafe { IntId::raw(id as u32) }
+}
+
+use bitflags::bitflags;
+
+// The `bitflags!` macro generates `struct`s that manage a set of flags.
+bitflags! {
+    /// Represents a set of flags.
+    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+    struct TriggerFlag: usize {
+        const NONE = 0;
+        const EDGE_RISING = 1;
+        const EDGE_FALLING = 2;
+        const EDGE_BOTH = Self::EDGE_RISING.bits()| Self::EDGE_FALLING.bits();
+        const LEVEL_HIGH = 4;
+        const LEVEL_LOW = 8;
+    }
+}
+
+fn fdt_parse_irq_config(itr: &[u32]) -> Result<IrqConfig, Box<dyn Error>> {
+    const SPI: u32 = 0;
+    const PPI: u32 = 1;
+
+    let num = itr[1];
+
+    let irq_id: u32 = match itr[0] {
+        SPI => IntId::spi(num),
+        PPI => IntId::ppi(num),
+        _ => panic!("Invalid irq type {}", itr[0]),
+    }
+    .into();
+
+    let flag = TriggerFlag::from_bits_truncate(itr[2] as _);
+
+    let trigger = if flag.contains(TriggerFlag::EDGE_BOTH) {
+        Trigger::EdgeBoth
+    } else if flag.contains(TriggerFlag::EDGE_RISING) {
+        Trigger::EdgeRising
+    } else if flag.contains(TriggerFlag::EDGE_FALLING) {
+        Trigger::EdgeFailling
+    } else if flag.contains(TriggerFlag::LEVEL_HIGH) {
+        Trigger::LevelHigh
+    } else if flag.contains(TriggerFlag::LEVEL_LOW) {
+        Trigger::LevelLow
+    } else {
+        panic!("Invalid irq type {}", itr[2])
+    };
+
+    Ok(IrqConfig {
+        irq: (irq_id as usize).into(),
+        trigger,
+    })
+}
+
+fn irq_pin_to_id(pin: usize) -> Result<IrqId, Box<dyn Error>> {
+    let irq_id = arm_gic_driver::IntId::spi(pin as _);
+    Ok((irq_id.to_u32() as usize).into())
+}
diff --git a/crates/sparreal-rt/src/arch/aarch64/mmu.rs b/crates/sparreal-rt/src/arch/aarch64/mmu.rs
index 143f846..31def34 100644
--- a/crates/sparreal-rt/src/arch/aarch64/mmu.rs
+++ b/crates/sparreal-rt/src/arch/aarch64/mmu.rs
@@ -1,53 +1,25 @@
 use core::arch::asm;
 
-use aarch64_cpu::registers::*;
-use page_table_arm::{MAIRDefault, MAIRKind, MAIRSetting, PTEFlags, PTE};
+use aarch64_cpu::{asm::barrier::*, registers::*};
+use page_table_arm::*;
 use page_table_generic::*;
-use sparreal_kernel::{dbg, platform::PlatformPageTable};
+use sparreal_kernel::{
+    io::print::{early_dbg, early_dbg_hexln},
+    mem::va_offset,
+    platform_if::*,
+};
 use sparreal_macros::api_impl;
 
-use super::boot::BOOT_INFO;
-
-extern "C" {
-    fn _skernel();
-    fn _stack_top();
-    fn _ekernel();
-}
-
-pub unsafe fn init_boot_table() -> u64 {
-    let table = match sparreal_kernel::mem::mmu::new_boot_table(BOOT_INFO.to_boot_config()) {
-        Ok(t) => t,
-        Err(e) => {
-            dbg!("failed to create boot table: ");
-            dbg!(match e {
-                err::PagingError::NoMemory => "NoMemory",
-                err::PagingError::NotAligned => "NotAligned",
-                err::PagingError::NotMapped => "NotMapped",
-                err::PagingError::AlreadyMapped => "AlreadyMapped",
-                err::PagingError::MappedToHugePage => "MappedToHugePage",
-            });
-            panic!("Failed to create boot table");
-        }
-    };
-
-    MAIRDefault::mair_el1_apply();
-
-    table as _
-}
-
 pub struct PageTableImpl;
 
 #[api_impl]
-impl PlatformPageTable for PageTableImpl {
-    fn flush_tlb(addr: Option<*const u8>) {
-        unsafe {
-            if let Some(vaddr) = addr {
-                asm!("tlbi vaae1is, {}; dsb nsh; isb", in(reg) vaddr as usize)
-            } else {
-                // flush the entire TLB
-                asm!("tlbi vmalle1; dsb nsh; isb")
-            };
-        }
+impl MMU for PageTableImpl {
+    unsafe fn flush_tlb(addr: *const u8) {
+        unsafe { asm!("tlbi vaae1is, {}; dsb nsh; isb", in(reg) addr as usize) };
+    }
+
+    fn flush_tlb_all() {
+        unsafe { asm!("tlbi vmalle1is; dsb nsh; isb") };
     }
 
     fn page_size() -> usize {
@@ -74,6 +46,8 @@ impl PlatformPageTable for PageTableImpl {
             CacheSetting::Normal => MAIRKind::Normal,
             CacheSetting::Device => MAIRKind::Device,
             CacheSetting::NonCache => MAIRKind::NonCache,
+            CacheSetting::ToDevice => MAIRKind::Device,
+            CacheSetting::FromDevice => MAIRKind::Device,
         }));
 
         let privilege = &config.setting.privilege_access;
@@ -176,7 +150,7 @@ impl PlatformPageTable for PageTableImpl {
 
     fn set_kernel_table(addr: usize) {
         TTBR1_EL1.set_baddr(addr as _);
-        Self::flush_tlb(None);
+        Self::flush_tlb_all();
     }
 
     fn get_kernel_table() -> usize {
@@ -185,10 +159,53 @@ impl PlatformPageTable for PageTableImpl {
 
     fn set_user_table(addr: usize) {
         TTBR0_EL1.set_baddr(addr as _);
-        Self::flush_tlb(None);
+        Self::flush_tlb_all();
     }
 
     fn get_user_table() -> usize {
         TTBR0_EL1.get_baddr() as _
     }
+
+    fn enable_mmu(stack_top: usize, jump_to: usize) -> ! {
+        MAIRDefault::mair_el1_apply();
+
+        // Enable TTBR0 and TTBR1 walks, page size = 4K, vaddr size = 48 bits, paddr size = 40 bits.
+        let tcr_flags0 = TCR_EL1::EPD0::EnableTTBR0Walks
+            + TCR_EL1::TG0::KiB_4
+            + TCR_EL1::SH0::Inner
+            + TCR_EL1::ORGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
+            + TCR_EL1::IRGN0::WriteBack_ReadAlloc_WriteAlloc_Cacheable
+            + TCR_EL1::T0SZ.val(16);
+        let tcr_flags1 = TCR_EL1::EPD1::EnableTTBR1Walks
+            + TCR_EL1::TG1::KiB_4
+            + TCR_EL1::SH1::Inner
+            + TCR_EL1::ORGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable
+            + TCR_EL1::IRGN1::WriteBack_ReadAlloc_WriteAlloc_Cacheable
+            + TCR_EL1::T1SZ.val(16);
+        TCR_EL1.write(TCR_EL1::IPS::Bits_48 + tcr_flags0 + tcr_flags1);
+
+        early_dbg("TCR_EL1: ");
+        early_dbg_hexln(TCR_EL1.get());
+        unsafe {
+            crate::debug::mmu_add_offset(va_offset());
+
+            asm!("tlbi vmalle1");
+            isb(SY);
+            dsb(NSH);
+            // Enable the MMU and turn on I-cache and D-cache
+            SCTLR_EL1
+                .modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable);
+            isb(SY);
+
+            asm!(
+                "MOV      sp,  {stack}",
+                "MOV      x8,  {entry}",
+                "BLR      x8",
+                "B       .",
+                stack = in(reg) stack_top,
+                entry = in(reg) jump_to,
+                options(nomem, nostack,noreturn)
+            )
+        }
+    }
 }
diff --git a/crates/sparreal-rt/src/arch/aarch64/mod.rs b/crates/sparreal-rt/src/arch/aarch64/mod.rs
index 9fdeb51..32cf5a0 100644
--- a/crates/sparreal-rt/src/arch/aarch64/mod.rs
+++ b/crates/sparreal-rt/src/arch/aarch64/mod.rs
@@ -1,84 +1,113 @@
+use core::{arch::asm, ffi::c_void};
+
+use aarch64_cpu::registers::*;
+use sparreal_kernel::{
+    globals::global_val, mem::KernelRegions, platform::PlatformInfoKind, platform_if::*, println,
+};
+use sparreal_macros::api_impl;
+
+use crate::mem::driver_registers;
+
 mod boot;
 mod cache;
-mod debug;
-mod mmu;
+mod gic;
+pub(crate) mod mmu;
 mod psci;
+mod timer;
 mod trap;
 
-use core::arch::asm;
-
-use aarch64_cpu::registers::*;
-use alloc::{format, string::String};
-use sparreal_kernel::{driver::device_tree::get_device_tree, platform::Platform, print, println};
-use sparreal_macros::api_impl;
+pub(crate) fn cpu_id() -> usize {
+    const CPU_ID_MASK: u64 = 0xFF_FFFF + (0xFFFF_FFFF << 32);
+    (aarch64_cpu::registers::MPIDR_EL1.get() & CPU_ID_MASK) as usize
+}
 
-pub struct PlatformImpl;
+struct PlatformImpl;
 
 #[api_impl]
 impl Platform for PlatformImpl {
-    unsafe fn shutdown() {
-        psci::system_off();
+    fn kstack_size() -> usize {
+        crate::config::KERNEL_STACK_SIZE
     }
 
-    unsafe fn wait_for_interrupt() {
-        aarch64_cpu::asm::wfi();
+    fn kernel_regions() -> KernelRegions {
+        crate::mem::kernel_regions()
     }
 
-    unsafe fn current_ticks() -> u64 {
-        CNTPCT_EL0.get()
+    fn cpu_id() -> usize {
+        cpu_id()
     }
 
-    unsafe fn tick_hz() -> u64 {
-        CNTFRQ_EL0.get()
+    fn cpu_context_size() -> usize {
+        size_of::<trap::Context>()
     }
 
-    unsafe fn debug_write_byte(_value: u8) {
-        #[cfg(feature = "early-print")]
-        debug::put_debug(_value);
+    unsafe fn cpu_context_sp(ctx_ptr: *const u8) -> usize {
+        let ctx = unsafe { &*(ctx_ptr as *const trap::Context) };
+        ctx.sp
     }
 
-    fn print_system_info() {
-        println!(
-            "CPU: {}.{}.{}.{}",
-            MPIDR_EL1.read(MPIDR_EL1::Aff0),
-            MPIDR_EL1.read(MPIDR_EL1::Aff1),
-            MPIDR_EL1.read(MPIDR_EL1::Aff2),
-            MPIDR_EL1.read(MPIDR_EL1::Aff3)
-        );
-        let _ = print_board_info();
+    unsafe fn get_current_tcb_addr() -> *const u8 {
+        SP_EL0.get() as usize as _
     }
 
-    fn irqs_enable() {
-        unsafe { asm!("msr daifclr, #2") };
+    unsafe fn set_current_tcb_addr(addr: *const u8) {
+        SP_EL0.set(addr as usize as _);
     }
 
-    fn irqs_disable() {
-        unsafe { asm!("msr daifset, #2") };
+    unsafe fn cpu_context_init(ctx_ptr: *mut u8, pc: *const c_void, stack_top: *const u8) {
+        unsafe {
+            let ctx = &mut *(ctx_ptr as *mut trap::Context);
+            ctx.spsr = SPSR_EL1.get();
+            ctx.pc = pc as usize;
+            ctx.sp = stack_top as usize;
+        }
+    }
+    unsafe fn cpu_context_switch(prev: *mut u8, next: *mut u8) {
+        unsafe {
+            let prev = &mut *(prev as *mut trap::Context);
+            let next = &mut *(next as *mut trap::Context);
+            prev.switch_to(next);
+        }
     }
 
-    fn cpu_id() -> u64 {
-        MPIDR_EL1.get()
+    fn wait_for_interrupt() {
+        aarch64_cpu::asm::wfi();
     }
-    fn cpu_id_display() -> String {
-        format!(
-            "{}.{}.{}.{}",
-            MPIDR_EL1.read(MPIDR_EL1::Aff0),
-            MPIDR_EL1.read(MPIDR_EL1::Aff1),
-            MPIDR_EL1.read(MPIDR_EL1::Aff2),
-            MPIDR_EL1.read(MPIDR_EL1::Aff3)
-        )
+
+    fn shutdown() -> ! {
+        psci::system_off()
+    }
+
+    fn debug_put(b: u8) {
+        crate::debug::put(b);
     }
-}
 
-fn print_board_info() -> Option<()> {
-    let fdt = get_device_tree()?;
-    let root = fdt.all_nodes().next()?;
-    let caps = root.compatibles();
+    fn irq_all_enable() {
+        unsafe { asm!("msr daifclr, #2") };
+    }
+    fn irq_all_disable() {
+        unsafe { asm!("msr daifset, #2") };
+    }
+    fn irq_all_is_enabled() -> bool {
+        let c = DAIF.read(DAIF::I);
+        c > 0
+    }
+
+    fn on_boot_success() {
+        match &global_val().platform_info {
+            PlatformInfoKind::DeviceTree(fdt) => {
+                if let Err(e) = psci::setup_method_by_fdt(fdt.get()) {
+                    println!("{}", e);
+                }
+            }
+        }
+    }
+
+    fn dcache_range(op: CacheOp, addr: usize, size: usize) {
+        cache::dcache_range(op, addr, size);
+    }
 
-    print!("Board:");
-    for cap in caps {
-        print!(" {}", cap);
+    fn driver_registers() -> DriverRegisterListRef {
+        DriverRegisterListRef::from_raw(driver_registers())
     }
-    println!();
-    Some(())
 }
diff --git a/crates/sparreal-rt/src/arch/aarch64/psci.rs b/crates/sparreal-rt/src/arch/aarch64/psci.rs
index e2f2b34..cfa757d 100644
--- a/crates/sparreal-rt/src/arch/aarch64/psci.rs
+++ b/crates/sparreal-rt/src/arch/aarch64/psci.rs
@@ -2,8 +2,26 @@
 
 #![allow(dead_code)]
 
+use fdt_parser::Fdt;
 use log::{error, info};
-use sparreal_kernel::{driver::device_tree::get_device_tree, Platform};
+use sparreal_kernel::platform::wait_for_interrupt;
+
+#[derive(Debug, Clone, Copy)]
+pub enum Method {
+    Smc,
+    Hvc,
+}
+
+static mut METHOD: Method = Method::Smc;
+fn set_method(method: Method) {
+    unsafe {
+        METHOD = method;
+    }
+}
+
+fn method() -> Method {
+    unsafe { METHOD }
+}
 
 pub const PSCI_0_2_FN_BASE: u32 = 0x84000000;
 pub const PSCI_0_2_64BIT: u32 = 0x40000000;
@@ -50,6 +68,23 @@ impl From<i32> for PsciError {
     }
 }
 
+pub(crate) fn setup_method_by_fdt(fdt: Fdt<'_>) -> Result<(), &'static str> {
+    let node = fdt
+        .find_compatible(&["arm,psci", "arm,psci-1.0"])
+        .next()
+        .ok_or("PSCI node not found")?;
+    let prop = node
+        .find_property("method")
+        .ok_or("FDT PSCI method property not found")?;
+    match prop.str() {
+        "smc" => set_method(Method::Smc),
+        "hvc" => set_method(Method::Hvc),
+        _ => return Err("Unknown PSCI method"),
+    }
+
+    Ok(())
+}
+
 /// arm,psci method: smc
 /// when SMCCC_CONDUIT_SMC = 1
 fn arm_smccc_smc(func: u32, arg0: usize, arg1: usize, arg2: usize) -> usize {
@@ -82,17 +117,9 @@ fn psci_hvc_call(func: u32, arg0: usize, arg1: usize, arg2: usize) -> usize {
 }
 
 fn psci_call(func: u32, arg0: usize, arg1: usize, arg2: usize) -> Result<(), PsciError> {
-    let dtb = get_device_tree().ok_or(PsciError::NotSupported)?;
-    let node = dtb
-        .find_compatible(&["arm,psci"])
-        .next()
-        .ok_or(PsciError::NotSupported)?;
-    let method = node.find_property("method").unwrap().str();
-
-    let ret = match method {
-        "smc" => arm_smccc_smc(func, arg0, arg1, arg2),
-        "hvc" => psci_hvc_call(func, arg0, arg1, arg2),
-        _ => panic!("Unknown PSCI method: {}", method),
+    let ret = match method() {
+        Method::Smc => arm_smccc_smc(func, arg0, arg1, arg2),
+        Method::Hvc => psci_hvc_call(func, arg0, arg1, arg2),
     };
     if ret == 0 {
         Ok(())
@@ -105,9 +132,7 @@ fn psci_call(func: u32, arg0: usize, arg1: usize, arg2: usize) -> Result<(), Psc
 pub fn system_off() -> ! {
     psci_call(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0).ok();
     loop {
-        unsafe {
-            super::PlatformImpl::wait_for_interrupt();
-        }
+        wait_for_interrupt();
     }
 }
 
@@ -120,10 +145,10 @@ pub fn system_off() -> ! {
 /// `entry_point` is the physical address of the secondary CPU's entry point.
 /// `arg` will be passed to the `X0` register of the secondary CPU.
 pub fn cpu_on(target_cpu: usize, entry_point: usize, arg: usize) {
-    info!("Starting CPU {:x} ON ...", target_cpu);
+    info!("Starting CPU {:#x} ON ...", target_cpu);
     let res = psci_call(PSCI_0_2_FN64_CPU_ON, target_cpu, entry_point, arg);
     if let Err(e) = res {
-        error!("failed to boot CPU {:x} ({:?})", target_cpu, e);
+        error!("failed to boot CPU {:#x} ({:?})", target_cpu, e);
     }
 }
 
diff --git a/crates/sparreal-rt/src/arch/aarch64/timer.rs b/crates/sparreal-rt/src/arch/aarch64/timer.rs
new file mode 100644
index 0000000..b1aa9ef
--- /dev/null
+++ b/crates/sparreal-rt/src/arch/aarch64/timer.rs
@@ -0,0 +1,71 @@
+use aarch64_cpu::registers::*;
+use alloc::{boxed::Box, vec::Vec};
+use sparreal_kernel::driver_interface::{
+    DriverGeneric, ProbeFnKind, interrupt_controller::IrqConfig, timer::*,
+};
+use sparreal_macros::module_driver;
+
+module_driver!(
+    name: "ARMv8 Timer",
+    compatibles: &["arm,armv8-timer"],
+    probe: ProbeFnKind::Timer(probe_timer),
+);
+
+#[derive(Clone)]
+struct ArmV8Timer {
+    irq: IrqConfig,
+}
+
+impl Interface for ArmV8Timer {
+    fn get_current_cpu(&mut self) -> Box<dyn InterfaceCPU> {
+        Box::new(self.clone())
+    }
+}
+
+impl InterfaceCPU for ArmV8Timer {
+    fn set_timeval(&mut self, ticks: u64) {
+        CNTP_TVAL_EL0.set(ticks);
+    }
+
+    fn current_ticks(&self) -> u64 {
+        CNTPCT_EL0.get()
+    }
+
+    fn tick_hz(&self) -> u64 {
+        CNTFRQ_EL0.get()
+    }
+
+    fn set_irq_enable(&mut self, enable: bool) {
+        CNTP_CTL_EL0.modify(if enable {
+            CNTP_CTL_EL0::IMASK::CLEAR
+        } else {
+            CNTP_CTL_EL0::IMASK::SET
+        });
+    }
+
+    fn get_irq_status(&self) -> bool {
+        CNTP_CTL_EL0.is_set(CNTP_CTL_EL0::ISTATUS)
+    }
+
+    fn irq(&self) -> IrqConfig {
+        self.irq.clone()
+    }
+}
+
+impl DriverGeneric for ArmV8Timer {
+    fn open(&mut self) -> Result<(), alloc::string::String> {
+        CNTP_CTL_EL0.modify(CNTP_CTL_EL0::ENABLE::SET);
+        Ok(())
+    }
+
+    fn close(&mut self) -> Result<(), alloc::string::String> {
+        CNTP_CTL_EL0.modify(CNTP_CTL_EL0::ENABLE::CLEAR);
+        Ok(())
+    }
+}
+
+fn probe_timer(irqs: Vec<IrqConfig>) -> Hardware {
+    Box::new(ArmV8Timer {
+        irq: irqs[1].clone(),
+    })
+}
diff --git a/crates/sparreal-rt/src/arch/aarch64/trap.rs b/crates/sparreal-rt/src/arch/aarch64/trap.rs
index ed601f3..2b41d8b 100644
--- a/crates/sparreal-rt/src/arch/aarch64/trap.rs
+++ b/crates/sparreal-rt/src/arch/aarch64/trap.rs
@@ -1,14 +1,15 @@
-use core::fmt;
-
 use aarch64_cpu::registers::*;
+use core::{
+    arch::{asm, global_asm, naked_asm},
+    fmt::{self, Debug},
+};
 use log::*;
-use memory_addr::VirtAddr;
 
-#[no_mangle]
-unsafe extern "C" fn __handle_sync(tf: &TrapFrame) {
+#[unsafe(no_mangle)]
+unsafe extern "C" fn __handle_sync(ctx: &Context) {
     let esr = ESR_EL1.extract();
     let iss = esr.read(ESR_EL1::ISS);
-    let elr = tf.elr;
+    let elr = ctx.pc;
 
     if let Some(code) = esr.read_as_enum(ESR_EL1::EC) {
         match code {
@@ -23,8 +24,8 @@ unsafe extern "C" fn __handle_sync(tf: &TrapFrame) {
             }
             _ => {
                 panic!(
-                    "\r\n{}\r\nUnhandled synchronous exception @ {:#x}: ESR={:#x} (EC {:#08b}, ISS {:#x})",
-                    tf,
+                    "\r\n{:?}\r\nUnhandled synchronous exception @ {:#x}: ESR={:#x} (EC {:#08b}, ISS {:#x})",
+                    ctx,
                     elr,
                     esr.get(),
                     esr.read(ESR_EL1::EC),
@@ -35,19 +36,25 @@ unsafe extern "C" fn __handle_sync(tf: &TrapFrame) {
     }
 }
 
-#[no_mangle]
-unsafe extern "C" fn __handle_irq() {
-    debug!("IRQ!");
+#[unsafe(no_mangle)]
+unsafe extern "C" fn __handle_irq(ctx: &Context) {
+    let sp = ctx.sp;
     sparreal_kernel::irq::handle_irq();
+    unsafe {
+        asm!(
+            "mov x0, {0}",
+            in(reg) sp,
+        );
+    }
 }
 
-#[no_mangle]
-unsafe extern "C" fn __handle_serror(tf: &TrapFrame) {
+#[unsafe(no_mangle)]
+unsafe extern "C" fn __handle_serror(ctx: &Context) {
     error!("SError exception:");
     let esr = ESR_EL1.extract();
     let _iss = esr.read(ESR_EL1::ISS);
     let elr = ELR_EL1.get();
-    error!("{}", tf);
+    error!("{:?}", ctx);
     panic!(
         "Unhandled synchronous exception @ {:#x}: ESR={:#x} (EC {:#08b}, ISS {:#x})",
         elr,
@@ -57,97 +64,396 @@ unsafe extern "C" fn __handle_serror(tf: &TrapFrame) {
     );
 }
 
-#[no_mangle]
-unsafe extern "C" fn __handle_frq() {
-    panic!("frq")
+#[unsafe(no_mangle)]
+unsafe extern "C" fn __handle_fiq() {
+    panic!("fiq")
 }
 fn handle_data_abort(iss: u64, _is_user: bool) {
     let wnr = (iss & (1 << 6)) != 0; // WnR: Write not Read
     let cm = (iss & (1 << 8)) != 0; // CM: Cache maintenance
-    let reason = if wnr & !cm {
+    let _reason = if wnr & !cm {
         PageFaultReason::Write
     } else {
         PageFaultReason::Read
     };
-    let vaddr = VirtAddr::from(FAR_EL1.get() as usize);
+    // let vaddr = VirtAddr::from(FAR_EL1.get() as usize);
 
-    handle_page_fault(vaddr, reason);
+    // handle_page_fault(vaddr, reason);
 }
 
-pub fn handle_page_fault(vaddr: VirtAddr, reason: PageFaultReason) {
-    panic!("Invalid addr fault @{vaddr:?}, reason: {reason:?}");
-}
-
-#[derive(Debug)]
 pub enum PageFaultReason {
     Read,
     Write,
 }
 
-#[derive(Debug)]
-#[repr(C)]
-pub struct TrapFrame {
+// pub fn handle_page_fault(vaddr: VirtAddr, reason: PageFaultReason) {
+//     // panic!("Invalid addr fault @{vaddr:?}, reason: {reason:?}");
+// }
+
+#[repr(C, align(0x10))]
+#[derive(Clone)]
+pub struct Context {
+    pub sp: usize,
+    pub pc: usize,
+    #[cfg(hard_float)]
+    /// Floating-point Control Register (FPCR)
+    pub fpcr: usize,
+    #[cfg(hard_float)]
+    /// Floating-point Status Register (FPSR)
+    pub fpsr: usize,
+    #[cfg(hard_float)]
+    pub q: [u128; 32],
     pub spsr: u64,
-    pub sp: u64,
-    pub cpacr: u64,
-    pub elr: u64,
-    pub q: [u64; 64],
-    pub x29: u64,
-    pub x30: u64,
-    pub x18: u64,
-    pub x19: u64,
-    pub x16: u64,
-    pub x17: u64,
-    pub x14: u64,
-    pub x15: u64,
-    pub x12: u64,
-    pub x13: u64,
-    pub x10: u64,
-    pub x11: u64,
-    pub x8: u64,
-    pub x9: u64,
-    pub x6: u64,
-    pub x7: u64,
-    pub x4: u64,
-    pub x5: u64,
-    pub x2: u64,
-    pub x3: u64,
-    pub x0: u64,
-    pub x1: u64,
-}
-
-impl fmt::Display for TrapFrame {
+    pub x: [usize; 31],
+}
+
+impl Debug for Context {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        writeln!(f, "TrapFrame:")?;
-        writeln!(f, "  spsr: {:#x}", self.spsr)?;
-        writeln!(f, "  sp: {:#x}", self.sp)?;
-        writeln!(f, "  cpacr: {:#x}", self.cpacr)?;
-        writeln!(f, "  elr: {:#x}", self.elr)?;
-        writeln!(
-            f,
-            "  x00: {:#x} x01: {:#x} x02: {:#x} x03: {:#x}",
-            self.x0, self.x1, self.x2, self.x3
-        )?;
-        writeln!(
-            f,
-            "  x04: {:#x} x05: {:#x} x06: {:#x} x07: {:#x}",
-            self.x4, self.x5, self.x6, self.x7
-        )?;
-        writeln!(
-            f,
-            "  x08: {:#x} x09: {:#x} x10: {:#x} x11: {:#x}",
-            self.x8, self.x9, self.x10, self.x11
-        )?;
-        writeln!(
-            f,
-            "  x12: {:#x} x13: {:#x} x14: {:#x} x15: {:#x}",
-            self.x12, self.x13, self.x14, self.x15
-        )?;
-        writeln!(
-            f,
-            "  x16: {:#x} x17: {:#x} x18: {:#x} x19: {:#x}",
-            self.x16, self.x17, self.x18, self.x19
-        )?;
-        writeln!(f, "  x29: {:#x} x30: {:#x} ", self.x29, self.x30)
+        writeln!(f, "Context:")?;
+
+        const NUM_CHUNKS: usize = 4;
+
+        for (r, chunk) in self.x.chunks(NUM_CHUNKS).enumerate() {
+            let row_start = r * NUM_CHUNKS;
+
+            for (i, v) in chunk.iter().enumerate() {
+                let i = row_start + i;
+                write!(f, "  x{:<3}: {:#18x}", i, v)?;
+            }
+            writeln!(f)?;
+        }
+        writeln!(f, "  spsr: {:#18x}", self.spsr)?;
+        writeln!(f, "  pc  : {:#18x}", self.pc)?;
+        writeln!(f, "  sp  : {:#18x}", self.sp)
+    }
+}
+
+impl Context {
+    /// Switches to another task.
+    ///
+    /// It first saves the current task's context from CPU to this place, and then
+    /// restores the next task's context from `next_ctx` to CPU.
+    pub fn switch_to(&mut self, next_ctx: &Self) {
+        debug!("switch_to {:?}", next_ctx);
+        unsafe { context_switch(self, next_ctx) }
+    }
+}
+
+#[cfg(hard_float)]
+macro_rules! save_q {
+    () => {
+        "
+    stp q30, q31,  [sp,#-0x20]!
+    stp q28, q29,  [sp,#-0x20]!
+    stp q26, q27,  [sp,#-0x20]!
+    stp q24, q25,  [sp,#-0x20]!
+    stp q22, q23,  [sp,#-0x20]!
+    stp q20, q21,  [sp,#-0x20]!
+    stp q18, q19,  [sp,#-0x20]!
+    stp q16, q17,  [sp,#-0x20]!
+    stp q14, q15,  [sp,#-0x20]!
+    stp q12, q13,  [sp,#-0x20]!
+    stp q10, q11,  [sp,#-0x20]!
+    stp q8,  q9,   [sp,#-0x20]!
+    stp q6,  q7,   [sp,#-0x20]!
+    stp q4,  q5,   [sp,#-0x20]!
+    stp q2,  q3,   [sp,#-0x20]!
+    stp q0,  q1,   [sp,#-0x20]!
+    mrs     x9,  fpcr
+    mrs     x10, fpsr
+    stp x9,  x10,  [sp,#-0x10]!
+"
+    };
+}
+
+#[cfg(hard_float)]
+macro_rules! restore_q {
+    () => {
+        "
+    ldp    x9,  x10, [sp], #0x10
+    msr    fpcr, x9
+    msr    fpsr, x10
+    ldp    q0,  q1,  [sp], #0x20
+    ldp    q2,  q3,  [sp], #0x20
+    ldp    q4,  q5,  [sp], #0x20
+    ldp    q6,  q7,  [sp], #0x20
+    ldp    q8,  q9,  [sp], #0x20
+    ldp    q10, q11, [sp], #0x20
+    ldp    q12, q13, [sp], #0x20
+    ldp    q14, q15, [sp], #0x20
+    ldp    q16, q17, [sp], #0x20
+    ldp    q18, q19, [sp], #0x20
+    ldp    q20, q21, [sp], #0x20
+    ldp    q22, q23, [sp], #0x20
+    ldp    q24, q25, [sp], #0x20
+    ldp    q26, q27, [sp], #0x20
+    ldp    q28, q29, [sp], #0x20
+    ldp    q30, q31, [sp], #0x20
+"
+    };
+}
+
+macro_rules! save_x_spsr {
+    () => {
+        "
+	stp X29,X30, [sp,#-0x10]!
+	stp X27,X28, [sp,#-0x10]!
+    stp X25,X26, [sp,#-0x10]!
+	stp X23,X24, [sp,#-0x10]!
+    stp X21,X22, [sp,#-0x10]!
+	stp X19,X20, [sp,#-0x10]!
+	stp	X17,X18, [sp,#-0x10]!
+	stp	X15,X16, [sp,#-0x10]!
+	stp	X13,X14, [sp,#-0x10]!
+	stp	X11,X12, [sp,#-0x10]!
+	stp	X9,X10,  [sp,#-0x10]!
+	stp	X7,X8,   [sp,#-0x10]!
+	stp	X5,X6,   [sp,#-0x10]!
+	stp	X3,X4,   [sp,#-0x10]!
+    stp	X1,X2,   [sp,#-0x10]!
+    mrs	x9, SPSR_EL1
+    stp x9, x0, [sp,#-0x10]!
+        "
+    };
+}
+
+macro_rules! save_pc_sp {
+    () => {
+        "
+    mrs x10, ELR_EL1
+    mov x0, sp
+    sub x0, x0,   #0x10
+	stp x0, x10,  [sp,#-0x10]!
+        "
+    };
+}
+
+macro_rules! restore_pc_sp {
+    () => {
+        "
+    mov sp, x0
+    ldp X0, X10,    [sp], #0x10
+    msr	ELR_EL1,    X10
+        "
+    };
+}
+
+macro_rules! restore_x_spsr {
+    () => {
+        "
+    ldp X9,X0,      [sp], #0x10
+    msr	SPSR_EL1,   X9
+	ldp	X1,X2,      [sp], #0x10
+    ldp X3,X4,      [sp], #0x10
+	ldp X5,X6,      [sp], #0x10
+	ldp	X7,X8,      [sp], #0x10
+	ldp	X9,X10,     [sp], #0x10
+	ldp	X11,X12,    [sp], #0x10
+	ldp	X13,X14,    [sp], #0x10
+	ldp	X15,X16,    [sp], #0x10
+	ldp	X17,X18,    [sp], #0x10
+	ldp	X19,x20,    [sp], #0x10
+	ldp	X21,X22,    [sp], #0x10
+	ldp	X23,X24,    [sp], #0x10
+	ldp	X25,X26,    [sp], #0x10
+	ldp	X27,X28,    [sp], #0x10
+	ldp	X29,X30,    [sp], #0x10
+        "
+    };
+}
+
+#[cfg(hard_float)]
+// `handler`返回时,从 `x0` 取出 `sp`,作为栈顶地址
+macro_rules! handler {
+    ($name:ident, $handler:expr) => {
+        #[naked]
+        extern "C" fn $name(ctx: &Context) {
+        unsafe {
+        naked_asm!(
+            save_x_spsr!(),
+            save_q!(),
+            save_pc_sp!(),
+            "mov    x0, sp",
+            "BL 	{handle}",
+            restore_pc_sp!(),
+            restore_q!(),
+            restore_x_spsr!(),
+            "eret",
+            handle = sym $handler,
+                )
+            }
+        }
+    };
+}
+
+#[cfg(not(hard_float))]
+// `handler`返回时,从 `x0` 取出 `sp`,作为栈顶地址
+macro_rules! handler {
+    ($name:ident, $handler:expr) => {
+        #[naked]
+        extern "C" fn $name(ctx: &Context) {
+        unsafe {
+        naked_asm!(
+            save_x_spsr!(),
+            save_pc_sp!(),
+            "mov    x0, sp",
+            "BL 	{handle}",
+            restore_pc_sp!(),
+            restore_x_spsr!(),
+            "eret",
+            handle = sym $handler,
+                )
+            }
+        }
+    };
+}
+
+handler!(handle_fiq, __handle_fiq);
+handler!(handle_irq, __handle_irq);
+handler!(handle_sync, __handle_sync);
+handler!(handle_serror, __handle_serror);
+
+global_asm!(
+    include_str!("vectors.s"),
+    irq_handler = sym handle_irq,
+    fiq_handler = sym handle_fiq,
+    sync_handler = sym handle_sync,
+    serror_handler = sym handle_serror,
+);
+
+macro_rules! save_task_x {
+    () => {
+        "
+        add x0, x0,   {size}
+        stp X29,X30, [x0,#-0x10]!
+        stp X27,X28, [x0,#-0x10]!
+        stp X25,X26, [x0,#-0x10]!
+        stp X23,X24, [x0,#-0x10]!
+        stp X21,X22, [x0,#-0x10]!
+        stp X19,X20, [x0,#-0x10]!
+        sub x0, x0,  #0x90
+        mrs	x9, SPSR_EL1
+        stp x9, x10,  [x0,#-0x10]!
+                "
+    };
+}
+
+macro_rules! save_task_q {
+    () => {
+        "
+            stp q30, q31,  [x0,#-0x20]!
+            stp q28, q29,  [x0,#-0x20]!
+            stp q26, q27,  [x0,#-0x20]!
+            stp q24, q25,  [x0,#-0x20]!
+            stp q22, q23,  [x0,#-0x20]!
+            stp q20, q21,  [x0,#-0x20]!
+            stp q18, q19,  [x0,#-0x20]!
+            stp q16, q17,  [x0,#-0x20]!
+            stp q14, q15,  [x0,#-0x20]!
+            stp q12, q13,  [x0,#-0x20]!
+            stp q10, q11,  [x0,#-0x20]!
+            stp q8,  q9,   [x0,#-0x20]!
+            stp q6,  q7,   [x0,#-0x20]!
+            stp q4,  q5,   [x0,#-0x20]!
+            stp q2,  q3,   [x0,#-0x20]!
+            stp q0,  q1,   [x0,#-0x20]!
+            mrs     x9,  fpcr
+            mrs     x10, fpsr
+            stp x9,  x10,  [x0,#-0x10]!
+                    "
+    };
+}
+
+macro_rules! save_task_lr {
+    () => {
+        "
+        mov x9, sp
+        stp x9, lr,    [x0,#-0x10]!
+            "
+    };
+}
+
+macro_rules! restore_task_x {
+    () => {
+        "
+        add x1, x1,   {size}
+        ldp X29,X30, [x1,#-0x10]!
+        ldp X27,X28, [x1,#-0x10]!
+        ldp X25,X26, [x1,#-0x10]!
+        ldp X23,X24, [x1,#-0x10]!
+        ldp X21,X22, [x1,#-0x10]!
+        ldp X19,X20, [x1,#-0x10]!
+        sub x1, x1,  #0x90
+        ldp x9, x10,  [x1,#-0x10]!
+        msr	SPSR_EL1, x9
+                "
+    };
+}
+
+macro_rules! restore_task_q {
+    () => {
+        "
+            ldp q30, q31,  [x1,#-0x20]!
+            ldp q28, q29,  [x1,#-0x20]!
+            ldp q26, q27,  [x1,#-0x20]!
+            ldp q24, q25,  [x1,#-0x20]!
+            ldp q22, q23,  [x1,#-0x20]!
+            ldp q20, q21,  [x1,#-0x20]!
+            ldp q18, q19,  [x1,#-0x20]!
+            ldp q16, q17,  [x1,#-0x20]!
+            ldp q14, q15,  [x1,#-0x20]!
+            ldp q12, q13,  [x1,#-0x20]!
+            ldp q10, q11,  [x1,#-0x20]!
+            ldp q8,  q9,   [x1,#-0x20]!
+            ldp q6,  q7,   [x1,#-0x20]!
+            ldp q4,  q5,   [x1,#-0x20]!
+            ldp q2,  q3,   [x1,#-0x20]!
+            ldp q0,  q1,   [x1,#-0x20]!
+            ldp x9,  x10,  [x1,#-0x10]!
+            msr      fpcr, x9
+            msr     fpsr, x10
+            "
+    };
+}
+
+macro_rules! restore_task_lr {
+    () => {
+        "
+            ldp x9, lr,    [x1,#-0x10]!
+            mov sp, x9
+            ret"
+    };
+}
+#[cfg(hard_float)]
+#[naked]
+unsafe extern "C" fn context_switch(_current_task: &mut Context, _next_task: &Context) {
+    unsafe {
+        naked_asm!(
+              //x0
+        save_task_x!(),
+        save_task_q!(),
+        save_task_lr!(),
+              //x1
+        restore_task_x!(),
+        restore_task_q!(),
+        restore_task_lr!(),
+              size = const size_of::<Context>()
+          )
+    }
+}
+
+#[cfg(not(hard_float))]
+#[naked]
+unsafe extern "C" fn context_switch(_current_task: &mut Context, _next_task: &Context) {
+    unsafe {
+        naked_asm!(
+              //x0
+        save_task_x!(),
+        save_task_lr!(),
+              //x1
+        restore_task_x!(),
+        restore_task_lr!(),
+              size = const size_of::<Context>()
+          )
     }
 }
diff --git a/crates/sparreal-rt/src/arch/aarch64/vectors.S b/crates/sparreal-rt/src/arch/aarch64/vectors.s
similarity index 72%
rename from crates/sparreal-rt/src/arch/aarch64/vectors.S
rename to crates/sparreal-rt/src/arch/aarch64/vectors.s
index 3d237de..a8d53b8 100644
--- a/crates/sparreal-rt/src/arch/aarch64/vectors.S
+++ b/crates/sparreal-rt/src/arch/aarch64/vectors.s
@@ -64,6 +64,7 @@
 
 // Typical exception vector table code.
 .balign 0x800
+.global vector_table_el1
 vector_table_el1:
     curr_el_sp0_sync: // The exception handler for the synchronous
     B .
@@ -81,16 +82,16 @@ vector_table_el1:
     B .
     .balign 0x80
     curr_el_spx_sync:
-    B SynchronousHandler
+    B {sync_handler}
     .balign 0x80
     curr_el_spx_irq: 
-    B IRQHandler
+	B {irq_handler}
     .balign 0x80
     curr_el_spx_frq: 
-    B FIQInterruptHandler
+    B {fiq_handler}
     .balign 0x80
     curr_el_spx_serror: // The exception handler for the system error 
-    B SErrorInterruptHandler
+    B {serror_handler}
     // exception from the current EL using the
     // current SP.
     .balign 0x80
@@ -122,78 +123,6 @@ vector_table_el1:
 
 // ------------------------------------------------------------
 
-SynchronousHandler:
-	SaveRegister
-	mrs 	x0, CPACR_EL1
-	mrs 	x1, ELR_EL1
-	mrs		x2, SPSR_EL1
-	stp	  x0, x1, [sp,#-0x10]!
-	mov		x21, sp 	
-	add		x21, x21, #704 /*EXCEPTION_FRAME_SIZE 704 = 22*8 + 32*16 + 2*8, except sp and spsr in FExcFrame */
-	stp		x2,x21, [sp,#-0x10]!
-	mov 	x0, sp
-
-	bl		__handle_sync
-
-	eret
-
-IRQHandler:
-  SaveRegister
-	/* Save the status of SPSR, ELR and CPTR to stack */
-	mrs 	x0, CPACR_EL1
-	mrs 	x1, ELR_EL1
-	mrs		x2, SPSR_EL1
-
-	stp	x0, x1, [sp,#-0x10]!
-	str	x2, [sp,#-0x10]!
-
-	bl	__handle_irq
-
-	/* Restore the status of SPSR, ELR and CPTR from stack */
-	ldr	x2,[sp],0x10
-	ldp	x0, x1, [sp],0x10
-
-	msr	CPACR_EL1, x0
-	msr	ELR_EL1, x1
-	msr	SPSR_EL1, x2
-
-	RestoreRegister
-	eret
-
-
-
-FIQInterruptHandler:
-
-	SaveRegister
-
-	bl	__handle_frq
-
-	RestoreRegister
-
-	eret
-
-
-SErrorInterruptHandler:
-
-	SaveRegister
-	/* Save the status of SPSR, ELR and CPTR to stack */
-	mrs 	x0, CPACR_EL1
-	mrs 	x1, ELR_EL1
-	mrs		x2, SPSR_EL1
-	stp	    x0, x1, [sp,#-0x10]!
-	mov		x21, sp 	
-	add		x21, x21, #704 /*EXCEPTION_FRAME_SIZE 704 = 22*8 + 32*16 + 2*8, except sp and spsr in FExcFrame */
-	stp		x21,x21, [sp,#-0x10]!
-	mov 	x0, sp
-
-	mov 	x0, sp
-	bl    __handle_serror
-
-	RestoreRegister
-
-	eret
-
-
 .align 8
 
 
diff --git a/crates/sparreal-rt/src/config.rs b/crates/sparreal-rt/src/config.rs
new file mode 100644
index 0000000..f850b9a
--- /dev/null
+++ b/crates/sparreal-rt/src/config.rs
@@ -0,0 +1,3 @@
+#![allow(unused)]
+
+include!(concat!(env!("OUT_DIR"), "/constant.rs"));
diff --git a/crates/sparreal-rt/src/consts.rs b/crates/sparreal-rt/src/consts.rs
deleted file mode 100644
index 90e948d..0000000
--- a/crates/sparreal-rt/src/consts.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![allow(unused)]
-
-include!(concat!(env!("OUT_DIR"), "/constant.rs"));
-
-pub const MAX_HART_ID: usize = SMP - 1;
-pub const STACK_SIZE: usize = HART_STACK_SIZE * SMP;
diff --git a/crates/sparreal-rt/src/debug/aux_mini.rs b/crates/sparreal-rt/src/debug/aux_mini.rs
new file mode 100644
index 0000000..7a9987e
--- /dev/null
+++ b/crates/sparreal-rt/src/debug/aux_mini.rs
@@ -0,0 +1,23 @@
+use core::sync::atomic::{Ordering, fence};
+
+pub struct AuxMini {}
+
+impl AuxMini {
+    pub fn write(&self, base: usize, byte: u8) {
+        const TXFF: u32 = 1 << 5;
+
+        unsafe {
+            let state = (base + 0x24) as *const u32;
+            loop {
+                let lsr = state.read_volatile();
+
+                fence(Ordering::Release);
+                if lsr & TXFF == 0 {
+                    break;
+                }
+            }
+            let data = base as *mut u32;
+            data.write_volatile(byte as _);
+        }
+    }
+}
diff --git a/crates/sparreal-rt/src/debug/mod.rs b/crates/sparreal-rt/src/debug/mod.rs
new file mode 100644
index 0000000..40c3481
--- /dev/null
+++ b/crates/sparreal-rt/src/debug/mod.rs
@@ -0,0 +1,70 @@
+use core::cell::UnsafeCell;
+
+use aux_mini::AuxMini;
+use pl011::Pl011;
+use sparreal_kernel::platform::SerialPort;
+
+mod aux_mini;
+mod pl011;
+
+static mut REG_BASE: usize = 0;
+static UART: UartWapper = UartWapper(UnsafeCell::new(Uart::None));
+
+struct UartWapper(UnsafeCell<Uart>);
+
+unsafe impl Send for UartWapper {}
+unsafe impl Sync for UartWapper {}
+
+impl UartWapper {
+    fn set(&self, uart: Uart) {
+        unsafe {
+            *self.0.get() = uart;
+        }
+    }
+}
+
+fn uart() -> &'static Uart {
+    unsafe { &*UART.0.get() }
+}
+
+pub unsafe fn mmu_add_offset(va_offset: usize) {
+    unsafe { REG_BASE += va_offset };
+}
+
+pub fn put(byte: u8) {
+    unsafe {
+        match uart() {
+            Uart::Pl011(uart) => uart.write(REG_BASE, byte),
+            Uart::AuxMini(uart) => uart.write(REG_BASE, byte),
+            Uart::None => {}
+        }
+    }
+}
+pub fn init_by_info(s: SerialPort) -> Option<()> {
+    unsafe { REG_BASE = s.addr.as_usize() };
+
+    for c in s.compatibles() {
+        if c.contains("brcm,bcm2835-aux-uart") {
+            UART.set(Uart::AuxMini(aux_mini::AuxMini {}));
+            break;
+        }
+
+        if c.contains("arm,pl011") {
+            UART.set(Uart::Pl011(Pl011 {}));
+            break;
+        }
+
+        if c.contains("arm,primecell") {
+            UART.set(Uart::Pl011(Pl011 {}));
+            break;
+        }
+    }
+
+    Some(())
+}
+
+enum Uart {
+    None,
+    Pl011(Pl011),
+    AuxMini(AuxMini),
+}
diff --git a/crates/sparreal-rt/src/debug/pl011.rs b/crates/sparreal-rt/src/debug/pl011.rs
new file mode 100644
index 0000000..7e40875
--- /dev/null
+++ b/crates/sparreal-rt/src/debug/pl011.rs
@@ -0,0 +1,17 @@
+use core::sync::atomic::{Ordering, fence};
+
+pub struct Pl011 {}
+
+impl Pl011 {
+    pub fn write(&self, base: usize, byte: u8) {
+        const TXFF: u8 = 1 << 5;
+
+        unsafe {
+            let state = (base + 0x18) as *mut u8;
+            let put = (base) as *mut u8;
+            while (state.read_volatile() & TXFF) != 0 {}
+            fence(Ordering::SeqCst);
+            put.write_volatile(byte);
+        }
+    }
+}
diff --git a/crates/sparreal-rt/src/drivers/gic.rs b/crates/sparreal-rt/src/drivers/gic.rs
deleted file mode 100644
index f87469f..0000000
--- a/crates/sparreal-rt/src/drivers/gic.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-use alloc::{
-    boxed::Box,
-    format,
-    {vec, vec::Vec},
-};
-use arm_gic_driver::*;
-use driver_interface::*;
-
-use futures::{future::LocalBoxFuture, FutureExt};
-pub fn register_v2() -> Register {
-    Register::new(
-        "GICv2",
-        vec!["arm,cortex-a15-gic"],
-        DriverKind::InteruptChip,
-        RegisterGicV2 {},
-    )
-}
-pub fn register_v3() -> Register {
-    Register::new(
-        "GICv3",
-        vec!["arm,gic-v3"],
-        DriverKind::InteruptChip,
-        RegisterGicV3 {},
-    )
-}
-struct RegisterGicV2 {}
-
-impl Probe for RegisterGicV2 {
-    fn probe<'a>(&self, config: ProbeConfig) -> LocalBoxFuture<'a, DriverResult<DriverSpecific>> {
-        async move {
-            let gic = GicV2::new(config.reg[0], config.reg[1])
-                .map_err(|e| DriverError::Init(format!("{:?}", e)))?;
-            let b: irq::BoxDriver = Box::new(DriverGicV2(gic));
-
-            Ok(DriverSpecific::InteruptChip(b))
-        }
-        .boxed_local()
-    }
-}
-struct RegisterGicV3 {}
-
-impl Probe for RegisterGicV3 {
-    fn probe<'a>(&self, config: ProbeConfig) -> LocalBoxFuture<'a, DriverResult<DriverSpecific>> {
-        async move {
-            let gic = GicV3::new(config.reg[0], config.reg[1])
-                .map_err(|e| DriverError::Init(format!("{:?}", e)))?;
-
-            let b: irq::BoxDriver = Box::new(DriverGicV3(gic));
-            Ok(DriverSpecific::InteruptChip(b))
-        }
-        .boxed_local()
-    }
-}
-
-macro_rules! impl_driver_gic {
-    ($name:ident, $inner:ident) => {
-        struct $name($inner);
-        impl DriverGeneric for $name {}
-        impl irq::Driver for $name {
-            fn get_and_acknowledge_interrupt(&self) -> Option<usize> {
-                self.0.get_and_acknowledge_interrupt().map(|id| {
-                    let id: u32 = id.into();
-                    id as _
-                })
-            }
-
-            fn end_interrupt(&self, irq_id: usize) {
-                self.0.end_interrupt(unsafe { IntId::raw(irq_id as _) });
-            }
-
-            fn irq_max_size(&self) -> usize {
-                self.0.irq_max_size()
-            }
-
-            fn irq_disable(&mut self, irq_id: usize) {
-                self.0.irq_disable(unsafe { IntId::raw(irq_id as _) });
-            }
-
-            fn current_cpu_setup(&self) {
-                self.0.current_cpu_setup();
-            }
-
-            fn fdt_parse_config(&self, itr: &[usize]) -> IrqProbeConfig {
-                fdt_itr_to_config(itr)
-            }
-
-            fn set_priority(&mut self, irq: usize, priority: usize) {
-                self.0
-                    .set_priority(unsafe { IntId::raw(irq as _) }, priority);
-            }
-
-            fn set_trigger(&mut self, irq: usize, trigger: irq::Trigger) {
-                self.0.set_trigger(
-                    unsafe { IntId::raw(irq as _) },
-                    match trigger {
-                        irq::Trigger::EdgeBoth => Trigger::Edge,
-                        irq::Trigger::EdgeRising => Trigger::Edge,
-                        irq::Trigger::EdgeFailling => Trigger::Edge,
-                        irq::Trigger::LevelHigh => Trigger::Level,
-                        irq::Trigger::LevelLow => Trigger::Level,
-                    },
-                );
-            }
-
-            fn set_bind_cpu(&mut self, irq: usize, cpu_list: &[u64]) {
-                let list = cpu_list_to_target_list(cpu_list);
-                self.0.set_bind_cpu(unsafe { IntId::raw(irq as _) }, &list);
-            }
-
-            fn irq_enable(&mut self, irq: usize) {
-                self.0.irq_enable(unsafe { IntId::raw(irq as _) });
-            }
-        }
-    };
-}
-
-impl_driver_gic!(DriverGicV2, GicV2);
-impl_driver_gic!(DriverGicV3, GicV3);
-
-fn cpu_list_to_target_list(cpu_list: &[u64]) -> Vec<CPUTarget> {
-    cpu_list
-        .iter()
-        .map(|id| cpu_id_u64_to_cpu_id(*id))
-        .collect()
-}
-fn cpu_id_u64_to_cpu_id(cpu_id: u64) -> CPUTarget {
-    let mpid: MPID = cpu_id.into();
-    mpid.into()
-}
-
-use bitflags::bitflags;
-
-// The `bitflags!` macro generates `struct`s that manage a set of flags.
-bitflags! {
-    /// Represents a set of flags.
-    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-    struct TriggerFlag: usize {
-        const NONE = 0;
-        const EDGE_RISING = 1;
-        const EDGE_FALLING = 2;
-        const EDGE_BOTH = Self::EDGE_RISING.bits()| Self::EDGE_FALLING.bits();
-        const LEVEL_HIGH = 4;
-        const LEVEL_LOW = 8;
-    }
-}
-
-fn fdt_itr_to_config(itr: &[usize]) -> IrqProbeConfig {
-    const SPI: usize = 0;
-    const PPI: usize = 1;
-
-    let num = itr[1] as u32;
-
-    let irq_id: u32 = match itr[0] {
-        SPI => IntId::spi(num),
-        PPI => IntId::ppi(num),
-        _ => panic!("Invalid irq type {}", itr[0]),
-    }
-    .into();
-
-    let flag = TriggerFlag::from_bits_truncate(itr[2]);
-
-    let trigger = if flag.contains(TriggerFlag::EDGE_BOTH) {
-        irq::Trigger::EdgeBoth
-    } else if flag.contains(TriggerFlag::EDGE_RISING) {
-        irq::Trigger::EdgeRising
-    } else if flag.contains(TriggerFlag::EDGE_FALLING) {
-        irq::Trigger::EdgeFailling
-    } else if flag.contains(TriggerFlag::LEVEL_HIGH) {
-        irq::Trigger::LevelHigh
-    } else if flag.contains(TriggerFlag::LEVEL_LOW) {
-        irq::Trigger::LevelLow
-    } else {
-        panic!("Invalid irq type {}", itr[2])
-    };
-
-    IrqProbeConfig {
-        irq: irq_id as _,
-        trigger,
-    }
-}
diff --git a/crates/sparreal-rt/src/drivers/mod.rs b/crates/sparreal-rt/src/drivers/mod.rs
deleted file mode 100644
index 48a8e49..0000000
--- a/crates/sparreal-rt/src/drivers/mod.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use alloc::{vec, vec::Vec};
-use driver_interface::Register;
-
-mod gic;
-mod timer;
-mod uart;
-
-pub fn registers() -> Vec<Register> {
-    vec![
-        gic::register_v2(),
-        gic::register_v3(),
-        timer::armv8::register(),
-        uart::pl011::register(),
-    ]
-}
diff --git a/crates/sparreal-rt/src/drivers/timer/armv8.rs b/crates/sparreal-rt/src/drivers/timer/armv8.rs
deleted file mode 100644
index 38b83df..0000000
--- a/crates/sparreal-rt/src/drivers/timer/armv8.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-use aarch64_cpu::registers::*;
-use alloc::{boxed::Box, vec};
-use driver_interface::*;
-use futures::{future::LocalBoxFuture, FutureExt};
-use sparreal_kernel::irq::irq_setup;
-use timer::Driver;
-use tock_registers::interfaces::ReadWriteable;
-
-pub fn register() -> Register {
-    Register::new(
-        "Timer Armv8",
-        vec!["arm,armv8-timer"],
-        DriverKind::Timer,
-        ProbeTimerArmv8 {},
-    )
-}
-
-struct ProbeTimerArmv8 {}
-
-impl Probe for ProbeTimerArmv8 {
-    fn probe<'a>(&self, config: ProbeConfig) -> LocalBoxFuture<'a, DriverResult<DriverSpecific>> {
-        async move {
-            let irq_ns = &config.irq[1];
-            irq_setup(irq_ns.irq, config.id, irq_ns.trigger);
-            // register_irq(
-            //     IrqConfig {
-            //         irq: irq_ns.irq,
-            //         trigger: irq_ns.trigger,
-            //         priority: 0,
-            //         cpu_list: vec![],
-            //     },
-            //     config.id,
-            //     move |_irq| {
-            //         let clr = CNTP_CTL_EL0.is_set(CNTP_CTL_EL0::ISTATUS);
-            //         info!("armv8 timer irq! {}", clr);
-
-            //         CNTP_CTL_EL0.write(CNTP_CTL_EL0::IMASK::SET);
-            //         IrqHandle::Handled
-            //     },
-            // );
-
-            let mut timer = Box::new(DriverTimerArmv8 {
-                irq: irq_ns.irq as _,
-            });
-            // timer.set_enable(true);
-            // timer.set_irq_enable(true);
-            timer.set_irq_enable(false);
-            // let freq = timer.tick_hz();
-            // let ticks = 2 * freq;
-            // timer.set_interval(ticks);
-            Ok(DriverSpecific::Timer(timer))
-        }
-        .boxed_local()
-    }
-}
-
-struct DriverTimerArmv8 {
-    irq: u64,
-}
-
-impl DriverGeneric for DriverTimerArmv8 {}
-impl timer::Driver for DriverTimerArmv8 {
-    fn current_ticks(&self) -> u64 {
-        CNTFRQ_EL0.get()
-    }
-
-    fn tick_hz(&self) -> u64 {
-        CNTPCT_EL0.get()
-    }
-
-    fn set_interval(&mut self, ticks: u64) {
-        CNTP_TVAL_EL0.set(ticks);
-    }
-
-    fn set_enable(&mut self, enable: bool) {
-        CNTP_CTL_EL0.modify(if enable {
-            CNTP_CTL_EL0::ENABLE::SET
-        } else {
-            CNTP_CTL_EL0::ENABLE::CLEAR
-        });
-    }
-
-    fn set_irq_enable(&mut self, enable: bool) {
-        CNTP_CTL_EL0.modify(if enable {
-            CNTP_CTL_EL0::IMASK::CLEAR
-        } else {
-            CNTP_CTL_EL0::IMASK::SET
-        });
-    }
-
-    fn read_irq_status(&self) -> bool {
-        CNTP_CTL_EL0.is_set(CNTP_CTL_EL0::ISTATUS)
-    }
-
-    fn irq_num(&self) -> u64 {
-        self.irq
-    }
-}
diff --git a/crates/sparreal-rt/src/drivers/timer/mod.rs b/crates/sparreal-rt/src/drivers/timer/mod.rs
deleted file mode 100644
index 19c6d59..0000000
--- a/crates/sparreal-rt/src/drivers/timer/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod armv8;
diff --git a/crates/sparreal-rt/src/drivers/uart/mod.rs b/crates/sparreal-rt/src/drivers/uart/mod.rs
deleted file mode 100644
index 50c33c8..0000000
--- a/crates/sparreal-rt/src/drivers/uart/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod pl011;
diff --git a/crates/sparreal-rt/src/drivers/uart/pl011.rs b/crates/sparreal-rt/src/drivers/uart/pl011.rs
deleted file mode 100644
index e8e9a32..0000000
--- a/crates/sparreal-rt/src/drivers/uart/pl011.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-use alloc::{boxed::Box, vec};
-
-use arm_pl011_rs::Pl011;
-use driver_interface::*;
-use embedded_io::*;
-use future::{FutureExt, LocalBoxFuture};
-use futures::prelude::*;
-use log::debug;
-
-pub fn register() -> Register {
-    Register::new(
-        "PL011",
-        vec!["arm,pl011"],
-        DriverKind::Uart,
-        RegisterPl011 {},
-    )
-}
-
-struct RegisterPl011 {}
-
-struct DriverPl011(Pl011);
-
-unsafe impl Send for DriverPl011 {}
-unsafe impl Sync for DriverPl011 {}
-
-impl uart::Driver for DriverPl011 {}
-impl io::Write for DriverPl011 {
-    fn write(&mut self, buf: &[u8]) -> io::IOResult<usize> {
-        match self.0.write(buf) {
-            Ok(n) => Ok(n),
-            Err(e) => Err(e.kind()),
-        }
-    }
-
-    fn flush(&mut self) -> io::IOResult {
-        Ok(())
-    }
-}
-
-impl DriverGeneric for DriverPl011 {}
-
-// impl RegisterPl011 {
-//     fn conv_config(config: uart::Config) -> arm_pl011_rs::Config {
-//         arm_pl011_rs::Config {
-//             baud_rate: config.baud_rate,
-//             clock_freq: config.clock_freq,
-//             data_bits: match config.data_bits {
-//                 uart::DataBits::Bits5 => arm_pl011_rs::DataBits::Bits5,
-//                 uart::DataBits::Bits6 => arm_pl011_rs::DataBits::Bits6,
-//                 uart::DataBits::Bits7 => arm_pl011_rs::DataBits::Bits7,
-//                 uart::DataBits::Bits8 => arm_pl011_rs::DataBits::Bits8,
-//             },
-//             stop_bits: match config.stop_bits {
-//                 uart::StopBits::STOP1 => arm_pl011_rs::StopBits::STOP1,
-//                 uart::StopBits::STOP2 => arm_pl011_rs::StopBits::STOP2,
-//             },
-//             parity: match config.parity {
-//                 uart::Parity::None => arm_pl011_rs::Parity::None,
-//                 uart::Parity::Even => arm_pl011_rs::Parity::Even,
-//                 uart::Parity::Odd => arm_pl011_rs::Parity::Odd,
-//             },
-//         }
-//     }
-// }
-
-impl Probe for RegisterPl011 {
-    fn probe<'a>(&self, config: ProbeConfig) -> LocalBoxFuture<'a, DriverResult<DriverSpecific>> {
-        let clock_freq = config.clock_freq[0];
-        debug!(
-            "Interupt: {}, {:?}, clk: {}Mhz",
-            config.irq[0].irq,
-            config.irq[0].trigger,
-            clock_freq / 1_000_000,
-        );
-
-        async move {
-            let uart = Pl011::new(
-                config.reg[0],
-                Some(arm_pl011_rs::Config {
-                    baud_rate: 115200,
-                    clock_freq,
-                    data_bits: arm_pl011_rs::DataBits::Bits8,
-                    stop_bits: arm_pl011_rs::StopBits::STOP1,
-                    parity: arm_pl011_rs::Parity::None,
-                }),
-            )
-            .await;
-
-            let d = DriverSpecific::Uart(Box::new(DriverPl011(uart)));
-
-            Ok(d)
-        }
-        .boxed_local()
-    }
-}
diff --git a/crates/sparreal-rt/src/lib.rs b/crates/sparreal-rt/src/lib.rs
index 1e65652..2b9f5a5 100644
--- a/crates/sparreal-rt/src/lib.rs
+++ b/crates/sparreal-rt/src/lib.rs
@@ -1,24 +1,24 @@
 #![no_std]
+#![no_main]
 #![feature(naked_functions)]
+#![feature(used_with_arg)]
+#![feature(stmt_expr_attributes)]
 
 extern crate alloc;
 
+extern crate sparreal_kernel;
+
 #[cfg_attr(target_arch = "aarch64", path = "arch/aarch64/mod.rs")]
 pub mod arch;
-mod consts;
-mod drivers;
-
-pub use sparreal_kernel::*;
-
-unsafe fn boot(kconfig: kernel::KernelConfig) -> ! {
-    kernel::init_log_and_memory(&kconfig);
-    kernel::driver_register_append(drivers::registers());
-    kernel::run()
-}
+mod config;
+mod debug;
+pub(crate) mod mem;
+pub mod prelude;
 
-pub fn shutdown() -> ! {
-    unsafe {
-        arch::PlatformImpl::shutdown();
-    }
-    unreachable!()
-}
+// We export this static with an informative name so that if an application attempts to link
+// two copies of cortex-m-rt together, linking will fail. We also declare a links key in
+// Cargo.toml which is the more modern way to solve the same problem, but we have to keep
+// __ONCE__ around to prevent linking with versions before the links key was added.
+#[unsafe(export_name = "error: sparreal-rt appears more than once in the dependency graph")]
+#[doc(hidden)]
+pub static __ONCE__: () = ();
diff --git a/crates/sparreal-rt/src/mem.rs b/crates/sparreal-rt/src/mem.rs
new file mode 100644
index 0000000..eb87775
--- /dev/null
+++ b/crates/sparreal-rt/src/mem.rs
@@ -0,0 +1,55 @@
+use core::ptr::{slice_from_raw_parts, slice_from_raw_parts_mut};
+
+use sparreal_kernel::mem::{CMemRange, KernelRegions};
+
+pub unsafe fn clear_bss() {
+    unsafe {
+        unsafe extern "C" {
+            fn _sbss();
+            fn _ebss();
+        }
+        let bss = &mut *slice_from_raw_parts_mut(_sbss as *mut u8, _ebss as usize - _sbss as usize);
+        bss.fill(0);
+    }
+}
+
+pub(crate) fn kernel_regions() -> KernelRegions {
+    unsafe extern "C" {
+        fn _stext();
+        fn _etext();
+        fn _srodata();
+        fn _erodata();
+        fn _sdata();
+        fn _edata();
+        fn _sbss();
+        fn _ebss();
+    }
+
+    KernelRegions {
+        text: CMemRange {
+            start: _stext as usize,
+            end: _etext as usize,
+        },
+        rodata: CMemRange {
+            start: _srodata as usize,
+            end: _erodata as usize,
+        },
+        data: CMemRange {
+            start: _sdata as usize,
+            end: _edata as usize,
+        },
+        bss: CMemRange {
+            start: _sbss as usize,
+            end: _ebss as usize,
+        },
+    }
+}
+
+pub fn driver_registers() -> &'static [u8] {
+    unsafe extern "C" {
+        fn _sdriver();
+        fn _edriver();
+    }
+
+    unsafe { &*slice_from_raw_parts(_sdriver as *const u8, _edriver as usize - _sdriver as usize) }
+}
diff --git a/crates/sparreal-rt/src/prelude.rs b/crates/sparreal-rt/src/prelude.rs
new file mode 100644
index 0000000..796f46a
--- /dev/null
+++ b/crates/sparreal-rt/src/prelude.rs
@@ -0,0 +1 @@
+pub use sparreal_macros::entry;
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 32adaef..53d075f 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,4 +1,3 @@
 [toolchain]
 channel = "nightly"
-components = ["rust-src", "rustfmt", "clippy"]
-targets = ["aarch64-unknown-none"]
+components = ["rust-src", "rustfmt", "clippy"]
\ No newline at end of file