diff --git a/ch1/implementors/core/marker/trait.Freeze.js b/ch1/implementors/core/marker/trait.Freeze.js index 632d1646..a5ea12f6 100644 --- a/ch1/implementors/core/marker/trait.Freeze.js +++ b/ch1/implementors/core/marker/trait.Freeze.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["os"] = [{"text":"impl Freeze for Stdout","synthetic":true,"types":["os::console::Stdout"]}]; +implementors["os"] = [{"text":"impl Freeze for Stdout","synthetic":true,"types":["os::console::Stdout"]},{"text":"impl Freeze for RISCV64","synthetic":true,"types":["os::board::RISCV64"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/implementors/core/marker/trait.Send.js b/ch1/implementors/core/marker/trait.Send.js index 9e6ded73..1c8f92c3 100644 --- a/ch1/implementors/core/marker/trait.Send.js +++ b/ch1/implementors/core/marker/trait.Send.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["os"] = [{"text":"impl Send for Stdout","synthetic":true,"types":["os::console::Stdout"]}]; +implementors["os"] = [{"text":"impl Send for Stdout","synthetic":true,"types":["os::console::Stdout"]},{"text":"impl Send for RISCV64","synthetic":true,"types":["os::board::RISCV64"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/implementors/core/marker/trait.Sync.js b/ch1/implementors/core/marker/trait.Sync.js index ce7a96d1..794d4787 100644 --- a/ch1/implementors/core/marker/trait.Sync.js +++ b/ch1/implementors/core/marker/trait.Sync.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["os"] = [{"text":"impl Sync for Stdout","synthetic":true,"types":["os::console::Stdout"]}]; +implementors["os"] = [{"text":"impl Sync for Stdout","synthetic":true,"types":["os::console::Stdout"]},{"text":"impl Sync for RISCV64","synthetic":true,"types":["os::board::RISCV64"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/implementors/core/marker/trait.Unpin.js b/ch1/implementors/core/marker/trait.Unpin.js index 70c97ed6..06f1810c 100644 --- a/ch1/implementors/core/marker/trait.Unpin.js +++ b/ch1/implementors/core/marker/trait.Unpin.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["os"] = [{"text":"impl Unpin for Stdout","synthetic":true,"types":["os::console::Stdout"]}]; +implementors["os"] = [{"text":"impl Unpin for Stdout","synthetic":true,"types":["os::console::Stdout"]},{"text":"impl Unpin for RISCV64","synthetic":true,"types":["os::board::RISCV64"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/ch1/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js index 7b03dd2d..f88d03be 100644 --- a/ch1/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js +++ b/ch1/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["os"] = [{"text":"impl RefUnwindSafe for Stdout","synthetic":true,"types":["os::console::Stdout"]}]; +implementors["os"] = [{"text":"impl RefUnwindSafe for Stdout","synthetic":true,"types":["os::console::Stdout"]},{"text":"impl RefUnwindSafe for RISCV64","synthetic":true,"types":["os::board::RISCV64"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/ch1/implementors/core/panic/unwind_safe/trait.UnwindSafe.js index 73a09331..b51b221d 100644 --- a/ch1/implementors/core/panic/unwind_safe/trait.UnwindSafe.js +++ b/ch1/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -1,3 +1,3 @@ (function() {var implementors = {}; -implementors["os"] = [{"text":"impl UnwindSafe for Stdout","synthetic":true,"types":["os::console::Stdout"]}]; +implementors["os"] = [{"text":"impl UnwindSafe for Stdout","synthetic":true,"types":["os::console::Stdout"]},{"text":"impl UnwindSafe for RISCV64","synthetic":true,"types":["os::board::RISCV64"]}]; if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/implementors/os/board/trait.QEMUExit.js b/ch1/implementors/os/board/trait.QEMUExit.js new file mode 100644 index 00000000..34fffcbd --- /dev/null +++ b/ch1/implementors/os/board/trait.QEMUExit.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["os"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/ch1/os/all.html b/ch1/os/all.html index c9400141..fdb949ad 100644 --- a/ch1/os/all.html +++ b/ch1/os/all.html @@ -3,5 +3,5 @@

List of all items

Structs

Macros

Functions

Constants

+

Crate os

List of all items

Structs

Traits

Macros

Functions

Constants

\ No newline at end of file diff --git a/ch1/os/board/constant.EXIT_FAILURE.html b/ch1/os/board/constant.EXIT_FAILURE.html new file mode 100644 index 00000000..a37e6639 --- /dev/null +++ b/ch1/os/board/constant.EXIT_FAILURE.html @@ -0,0 +1,8 @@ +EXIT_FAILURE in os::board - Rust + +
+

Constant os::board::EXIT_FAILURE

source · []
const EXIT_FAILURE: u32 = exit_code_encode(1); // 78_643u32
+ \ No newline at end of file diff --git a/ch1/os/board/constant.EXIT_FAILURE_FLAG.html b/ch1/os/board/constant.EXIT_FAILURE_FLAG.html new file mode 100644 index 00000000..8e92fef0 --- /dev/null +++ b/ch1/os/board/constant.EXIT_FAILURE_FLAG.html @@ -0,0 +1,8 @@ +EXIT_FAILURE_FLAG in os::board - Rust + +
const EXIT_FAILURE_FLAG: u32 = 0x3333;
+ \ No newline at end of file diff --git a/ch1/os/board/constant.EXIT_RESET.html b/ch1/os/board/constant.EXIT_RESET.html new file mode 100644 index 00000000..caf6eda3 --- /dev/null +++ b/ch1/os/board/constant.EXIT_RESET.html @@ -0,0 +1,8 @@ +EXIT_RESET in os::board - Rust + +
+

Constant os::board::EXIT_RESET

source · []
const EXIT_RESET: u32 = 0x7777;
+ \ No newline at end of file diff --git a/ch1/os/board/constant.EXIT_SUCCESS.html b/ch1/os/board/constant.EXIT_SUCCESS.html new file mode 100644 index 00000000..b499adfb --- /dev/null +++ b/ch1/os/board/constant.EXIT_SUCCESS.html @@ -0,0 +1,8 @@ +EXIT_SUCCESS in os::board - Rust + +
+

Constant os::board::EXIT_SUCCESS

source · []
const EXIT_SUCCESS: u32 = 0x5555;
+ \ No newline at end of file diff --git a/ch1/os/board/constant.QEMU_EXIT_HANDLE.html b/ch1/os/board/constant.QEMU_EXIT_HANDLE.html new file mode 100644 index 00000000..6b7c64cb --- /dev/null +++ b/ch1/os/board/constant.QEMU_EXIT_HANDLE.html @@ -0,0 +1,8 @@ +QEMU_EXIT_HANDLE in os::board - Rust + +
pub const QEMU_EXIT_HANDLE: RISCV64;
+ \ No newline at end of file diff --git a/ch1/os/board/constant.VIRT_TEST.html b/ch1/os/board/constant.VIRT_TEST.html new file mode 100644 index 00000000..67a2213c --- /dev/null +++ b/ch1/os/board/constant.VIRT_TEST.html @@ -0,0 +1,8 @@ +VIRT_TEST in os::board - Rust + +
+

Constant os::board::VIRT_TEST

source · []
const VIRT_TEST: u64 = 0x100000;
+ \ No newline at end of file diff --git a/ch1/os/board/fn.exit_code_encode.html b/ch1/os/board/fn.exit_code_encode.html new file mode 100644 index 00000000..46cb6619 --- /dev/null +++ b/ch1/os/board/fn.exit_code_encode.html @@ -0,0 +1,9 @@ +exit_code_encode in os::board - Rust + +
const fn exit_code_encode(code: u32) -> u32
Expand description

Encode the exit code using EXIT_FAILURE_FLAG.

+
+ \ No newline at end of file diff --git a/ch1/os/board/index.html b/ch1/os/board/index.html new file mode 100644 index 00000000..4cf36550 --- /dev/null +++ b/ch1/os/board/index.html @@ -0,0 +1,14 @@ +os::board - Rust + +
+

Module os::board

source · []

Structs

+

RISCV64 configuration

+

Constants

+

Traits

+

Functions

+

Encode the exit code using EXIT_FAILURE_FLAG.

+
+ \ No newline at end of file diff --git a/ch1/os/board/sidebar-items.js b/ch1/os/board/sidebar-items.js new file mode 100644 index 00000000..c150cf12 --- /dev/null +++ b/ch1/os/board/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"constant":[["EXIT_FAILURE",""],["EXIT_FAILURE_FLAG",""],["EXIT_RESET",""],["EXIT_SUCCESS",""],["QEMU_EXIT_HANDLE",""],["VIRT_TEST",""]],"fn":[["exit_code_encode","Encode the exit code using EXIT_FAILURE_FLAG."]],"struct":[["RISCV64","RISCV64 configuration"]],"trait":[["QEMUExit",""]]}); \ No newline at end of file diff --git a/ch1/os/board/struct.RISCV64.html b/ch1/os/board/struct.RISCV64.html new file mode 100644 index 00000000..c551dc8c --- /dev/null +++ b/ch1/os/board/struct.RISCV64.html @@ -0,0 +1,27 @@ +RISCV64 in os::board - Rust + +
+

Struct os::board::RISCV64

source · []
pub struct RISCV64 {
+    addr: u64,
+}
Expand description

RISCV64 configuration

+

Fields

addr: u64

Address of the sifive_test mapped device.

+

Implementations

Create an instance.

+

Trait Implementations

Exit qemu with specified exit code.

+

Exit QEMU using EXIT_SUCCESS, aka 0, if possible. Read more

+

Exit QEMU using EXIT_FAILURE, aka 1.

+

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

+

Immutably borrows from an owned value. Read more

+

Mutably borrows from an owned value. Read more

+

Returns the argument unchanged.

+

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+

The type returned in the event of a conversion error.

+

Performs the conversion.

+

The type returned in the event of a conversion error.

+

Performs the conversion.

+
+ \ No newline at end of file diff --git a/ch1/os/board/trait.QEMUExit.html b/ch1/os/board/trait.QEMUExit.html new file mode 100644 index 00000000..cc5329d2 --- /dev/null +++ b/ch1/os/board/trait.QEMUExit.html @@ -0,0 +1,17 @@ +QEMUExit in os::board - Rust + +
pub trait QEMUExit {
+    fn exit(&self, code: u32) -> !;
+    fn exit_success(&self) -> !;
+    fn exit_failure(&self) -> !;
+}

Required methods

Exit with specified return code.

+

Note: For X86, code is binary-OR’ed with 0x1 inside QEMU.

+

Exit QEMU using EXIT_SUCCESS, aka 0, if possible.

+

Note: Not possible for X86.

+

Exit QEMU using EXIT_FAILURE, aka 1.

+

Implementors

+ \ No newline at end of file diff --git a/ch1/os/fn.clear_bss.html b/ch1/os/fn.clear_bss.html index afa7d2a1..0e9f236d 100644 --- a/ch1/os/fn.clear_bss.html +++ b/ch1/os/fn.clear_bss.html @@ -4,6 +4,6 @@
-

Function os::clear_bss

source · []
pub fn clear_bss()
Expand description

clear BSS segment

+

Function os::clear_bss

source · []
pub fn clear_bss()
Expand description

clear BSS segment

\ No newline at end of file diff --git a/ch1/os/fn.rust_main.html b/ch1/os/fn.rust_main.html index b520bf3f..45e5af7b 100644 --- a/ch1/os/fn.rust_main.html +++ b/ch1/os/fn.rust_main.html @@ -4,7 +4,7 @@
-

Function os::rust_main

source · []
#[no_mangle]
+    

Function os::rust_main

source · []
#[no_mangle]
 pub fn rust_main() -> !
Expand description

the rust entry-point of os

\ No newline at end of file diff --git a/ch1/os/index.html b/ch1/os/index.html index dd038570..3e8b790a 100644 --- a/ch1/os/index.html +++ b/ch1/os/index.html @@ -4,14 +4,14 @@
-

Crate os

source · []
Expand description

The main module and entrypoint

+

Crate os

source · []
Expand description

The main module and entrypoint

The operating system and app also starts in this module. Kernel code starts executing from entry.asm, after which rust_main() is called to initialize various pieces of functionality clear_bss(). (See its source code for details.)

We then call println! to display Hello, world!.

Modules

-
console 🔒

SBI console driver, for text output

+
board 🔒
console 🔒

SBI console driver, for text output

lang_items 🔒

The panic handler

sbi 🔒

Macros

print string macro

diff --git a/ch1/os/sbi/fn.shutdown.html b/ch1/os/sbi/fn.shutdown.html index bdcc1dab..094af0f4 100644 --- a/ch1/os/sbi/fn.shutdown.html +++ b/ch1/os/sbi/fn.shutdown.html @@ -4,6 +4,6 @@
-

Function os::sbi::shutdown

source · []
pub fn shutdown() -> !
Expand description

use sbi call to shutdown the kernel

+

Function os::sbi::shutdown

source · []
pub fn shutdown() -> !
Expand description

use sbi call to shutdown the kernel

\ No newline at end of file diff --git a/ch1/os/sbi/index.html b/ch1/os/sbi/index.html index 9b5f3294..81bfa682 100644 --- a/ch1/os/sbi/index.html +++ b/ch1/os/sbi/index.html @@ -4,7 +4,7 @@
-

Module os::sbi

source · []

Constants

+

Module os::sbi

source · []

Constants

Functions

use sbi call to getchar from console (qemu uart handler)

use sbi call to putchar in console (qemu uart handler)

diff --git a/ch1/os/sidebar-items.js b/ch1/os/sidebar-items.js index dd6f2db9..279b8ddb 100644 --- a/ch1/os/sidebar-items.js +++ b/ch1/os/sidebar-items.js @@ -1 +1 @@ -initSidebarItems({"fn":[["clear_bss","clear BSS segment"],["rust_main","the rust entry-point of os"]],"macro":[["print","print string macro"],["println","println string macro"]],"mod":[["console","SBI console driver, for text output"],["lang_items","The panic handler"],["sbi",""]]}); \ No newline at end of file +initSidebarItems({"fn":[["clear_bss","clear BSS segment"],["rust_main","the rust entry-point of os"]],"macro":[["print","print string macro"],["println","println string macro"]],"mod":[["board",""],["console","SBI console driver, for text output"],["lang_items","The panic handler"],["sbi",""]]}); \ No newline at end of file diff --git a/ch1/search-index.js b/ch1/search-index.js index 4f1051ae..677e38ea 100644 --- a/ch1/search-index.js +++ b/ch1/search-index.js @@ -1,4 +1,4 @@ var searchIndex = JSON.parse('{\ -"os":{"doc":"The main module and entrypoint","t":[5,0,0,14,14,5,0,3,11,11,11,11,5,11,11,11,11,5,17,17,17,17,17,17,17,17,17,5,5,5,5],"n":["clear_bss","console","lang_items","print","println","rust_main","sbi","Stdout","borrow","borrow_mut","from","into","print","try_from","try_into","type_id","write_str","panic","SBI_CLEAR_IPI","SBI_CONSOLE_GETCHAR","SBI_CONSOLE_PUTCHAR","SBI_REMOTE_FENCE_I","SBI_REMOTE_SFENCE_VMA","SBI_REMOTE_SFENCE_VMA_ASID","SBI_SEND_IPI","SBI_SET_TIMER","SBI_SHUTDOWN","console_getchar","console_putchar","sbi_call","shutdown"],"q":["os","","","","","","","os::console","","","","","","","","","","os::lang_items","os::sbi","","","","","","","","","","","",""],"d":["clear BSS segment","SBI console driver, for text output","The panic handler","print string macro","println string macro","the rust entry-point of os","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","","","","","","","","","","","use sbi call to getchar from console (qemu uart handler)","use sbi call to putchar in console (qemu uart handler)","","use sbi call to shutdown the kernel"],"i":[0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"f":[[[]],null,null,null,null,[[],["never",0]],null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[]],[[]],[[["arguments",3]]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0],["str",0]],["result",6]],[[["panicinfo",3]],["never",0]],null,null,null,null,null,null,null,null,null,[[],["usize",0]],[[["usize",0]]],[[["usize",0],["usize",0],["usize",0],["usize",0]],["usize",0]],[[],["never",0]]],"p":[[3,"Stdout"]]}\ +"os":{"doc":"The main module and entrypoint","t":[0,5,0,0,14,14,5,0,17,17,17,17,8,17,3,17,12,11,11,10,11,5,10,11,10,11,11,11,11,11,11,11,3,11,11,11,11,5,11,11,11,11,5,17,17,17,17,17,17,17,17,17,5,5,5,5],"n":["board","clear_bss","console","lang_items","print","println","rust_main","sbi","EXIT_FAILURE","EXIT_FAILURE_FLAG","EXIT_RESET","EXIT_SUCCESS","QEMUExit","QEMU_EXIT_HANDLE","RISCV64","VIRT_TEST","addr","borrow","borrow_mut","exit","exit","exit_code_encode","exit_failure","exit_failure","exit_success","exit_success","from","into","new","try_from","try_into","type_id","Stdout","borrow","borrow_mut","from","into","print","try_from","try_into","type_id","write_str","panic","SBI_CLEAR_IPI","SBI_CONSOLE_GETCHAR","SBI_CONSOLE_PUTCHAR","SBI_REMOTE_FENCE_I","SBI_REMOTE_SFENCE_VMA","SBI_REMOTE_SFENCE_VMA_ASID","SBI_SEND_IPI","SBI_SET_TIMER","SBI_SHUTDOWN","console_getchar","console_putchar","sbi_call","shutdown"],"q":["os","","","","","","","","os::board","","","","","","","","","","","","","","","","","","","","","","","","os::console","","","","","","","","","","os::lang_items","os::sbi","","","","","","","","","","","",""],"d":["","clear BSS segment","SBI console driver, for text output","The panic handler","print string macro","println string macro","the rust entry-point of os","","","","","","","","RISCV64 configuration","","Address of the sifive_test mapped device.","","","Exit with specified return code.","Exit qemu with specified exit code.","Encode the exit code using EXIT_FAILURE_FLAG.","Exit QEMU using EXIT_FAILURE, aka 1.","","Exit QEMU using EXIT_SUCCESS, aka 0, if possible.","","Returns the argument unchanged.","Calls U::from(self).","Create an instance.","","","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","","","","","","","","","","","use sbi call to getchar from console (qemu uart handler)","use sbi call to putchar in console (qemu uart handler)","","use sbi call to shutdown the kernel"],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,1,0,2,1,2,1,1,1,1,1,1,1,0,3,3,3,3,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"f":[null,[[]],null,null,null,null,[[],["never",0]],null,null,null,null,null,null,null,null,null,null,[[["",0]],["",0]],[[["",0]],["",0]],[[["",0],["u32",0]],["never",0]],[[["",0],["u32",0]],["never",0]],[[["u32",0]],["u32",0]],[[["",0]],["never",0]],[[["",0]],["never",0]],[[["",0]],["never",0]],[[["",0]],["never",0]],[[]],[[]],[[["u64",0]]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],null,[[["",0]],["",0]],[[["",0]],["",0]],[[]],[[]],[[["arguments",3]]],[[],["result",4]],[[],["result",4]],[[["",0]],["typeid",3]],[[["",0],["str",0]],["result",6]],[[["panicinfo",3]],["never",0]],null,null,null,null,null,null,null,null,null,[[],["usize",0]],[[["usize",0]]],[[["usize",0],["usize",0],["usize",0],["usize",0]],["usize",0]],[[],["never",0]]],"p":[[3,"RISCV64"],[8,"QEMUExit"],[3,"Stdout"]]}\ }'); if (window.initSearch) {window.initSearch(searchIndex)}; \ No newline at end of file diff --git a/ch1/source-files.js b/ch1/source-files.js index c740a21c..55f3de2f 100644 --- a/ch1/source-files.js +++ b/ch1/source-files.js @@ -1,3 +1,3 @@ var N = null;var sourcesIndex = {}; -sourcesIndex["os"] = {"name":"","files":["console.rs","lang_items.rs","main.rs","sbi.rs"]}; +sourcesIndex["os"] = {"name":"","dirs":[{"name":"boards","files":["qemu.rs"]}],"files":["console.rs","lang_items.rs","main.rs","sbi.rs"]}; createSourceSidebar(); diff --git a/ch1/src/os/boards/qemu.rs.html b/ch1/src/os/boards/qemu.rs.html new file mode 100644 index 00000000..56ad759d --- /dev/null +++ b/ch1/src/os/boards/qemu.rs.html @@ -0,0 +1,166 @@ +qemu.rs - source + +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+
//ref:: https://github.com/andre-richter/qemu-exit
+use core::arch::asm;
+
+const EXIT_SUCCESS: u32 = 0x5555; // Equals `exit(0)`. qemu successful exit
+
+const EXIT_FAILURE_FLAG: u32 = 0x3333;
+const EXIT_FAILURE: u32 = exit_code_encode(1); // Equals `exit(1)`. qemu failed exit
+const EXIT_RESET: u32 = 0x7777; // qemu reset
+
+pub trait QEMUExit {
+    /// Exit with specified return code.
+    ///
+    /// Note: For `X86`, code is binary-OR'ed with `0x1` inside QEMU.
+    fn exit(&self, code: u32) -> !;
+
+    /// Exit QEMU using `EXIT_SUCCESS`, aka `0`, if possible.
+    ///
+    /// Note: Not possible for `X86`.
+    fn exit_success(&self) -> !;
+
+    /// Exit QEMU using `EXIT_FAILURE`, aka `1`.
+    fn exit_failure(&self) -> !;
+}
+
+/// RISCV64 configuration
+pub struct RISCV64 {
+    /// Address of the sifive_test mapped device.
+    addr: u64,
+}
+
+/// Encode the exit code using EXIT_FAILURE_FLAG.
+const fn exit_code_encode(code: u32) -> u32 {
+    (code << 16) | EXIT_FAILURE_FLAG
+}
+
+impl RISCV64 {
+    /// Create an instance.
+    pub const fn new(addr: u64) -> Self {
+        RISCV64 { addr }
+    }
+}
+
+impl QEMUExit for RISCV64 {
+    /// Exit qemu with specified exit code.
+    fn exit(&self, code: u32) -> ! {
+        // If code is not a special value, we need to encode it with EXIT_FAILURE_FLAG.
+        let code_new = match code {
+            EXIT_SUCCESS | EXIT_FAILURE | EXIT_RESET => code,
+            _ => exit_code_encode(code),
+        };
+
+        unsafe {
+            asm!(
+                "sw {0}, 0({1})",
+                in(reg)code_new, in(reg)self.addr
+            );
+
+            // For the case that the QEMU exit attempt did not work, transition into an infinite
+            // loop. Calling `panic!()` here is unfeasible, since there is a good chance
+            // this function here is the last expression in the `panic!()` handler
+            // itself. This prevents a possible infinite loop.
+            loop {
+                asm!("wfi", options(nomem, nostack));
+            }
+        }
+    }
+
+    fn exit_success(&self) -> ! {
+        self.exit(EXIT_SUCCESS);
+    }
+
+    fn exit_failure(&self) -> ! {
+        self.exit(EXIT_FAILURE);
+    }
+}
+
+const VIRT_TEST: u64 = 0x100000;
+
+pub const QEMU_EXIT_HANDLE: RISCV64 = RISCV64::new(VIRT_TEST);
+
+
+ \ No newline at end of file diff --git a/ch1/src/os/main.rs.html b/ch1/src/os/main.rs.html index 092b8032..a75074e5 100644 --- a/ch1/src/os/main.rs.html +++ b/ch1/src/os/main.rs.html @@ -63,6 +63,19 @@ 58 59 60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73
//! The main module and entrypoint
 //!
 //! The operating system and app also starts in this module. Kernel code starts
@@ -85,6 +98,10 @@
 mod lang_items;
 mod sbi;
 
+#[cfg(feature = "board_qemu")]
+#[path = "boards/qemu.rs"]
+mod board;
+
 global_asm!(include_str!("entry.asm"));
 
 /// clear BSS segment
@@ -100,16 +117,16 @@
 #[no_mangle]
 pub fn rust_main() -> ! {
     extern "C" {
-        fn stext();               // begin addr of text segment
-        fn etext();               // end addr of text segment
-        fn srodata();             // start addr of Read-Only data segment
-        fn erodata();             // end addr of Read-Only data ssegment
-        fn sdata();               // start addr of data segment
-        fn edata();               // end addr of data segment
-        fn sbss();                // start addr of BSS segment
-        fn ebss();                // end addr of BSS segment
-        fn boot_stack();          // stack bottom
-        fn boot_stack_top();      // stack top
+        fn stext(); // begin addr of text segment
+        fn etext(); // end addr of text segment
+        fn srodata(); // start addr of Read-Only data segment
+        fn erodata(); // end addr of Read-Only data ssegment
+        fn sdata(); // start addr of data segment
+        fn edata(); // end addr of data segment
+        fn sbss(); // start addr of BSS segment
+        fn ebss(); // end addr of BSS segment
+        fn boot_stack(); // stack bottom
+        fn boot_stack_top(); // stack top
     }
     clear_bss();
     println!("Hello, world!");
@@ -121,8 +138,16 @@
         boot_stack as usize, boot_stack_top as usize
     );
     println!(".bss [{:#x}, {:#x})", sbss as usize, ebss as usize);
-    panic!("Shutdown machine!");
-}
-
+ + #[cfg(feature = "board_qemu")] + use crate::board::QEMUExit; + + #[cfg(feature = "board_qemu")] + crate::board::QEMU_EXIT_HANDLE.exit_success(); // CI autotest success + //crate::board::QEMU_EXIT_HANDLE.exit_failure(); // CI autoest failed + + #[cfg(feature = "board_k210")] + panic!("Unreachable in rust_main!"); +}
\ No newline at end of file diff --git a/ch1/src/os/sbi.rs.html b/ch1/src/os/sbi.rs.html index 7b313c80..87e2649f 100644 --- a/ch1/src/os/sbi.rs.html +++ b/ch1/src/os/sbi.rs.html @@ -48,6 +48,12 @@ 43 44 45 +46 +47 +48 +49 +50 +51
#![allow(unused)]
 
 use core::arch::asm;
@@ -88,9 +94,15 @@
     sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0)
 }
 
+use crate::board::QEMUExit;
 /// use sbi call to shutdown the kernel
 pub fn shutdown() -> ! {
+    #[cfg(feature = "board_k210")]
     sbi_call(SBI_SHUTDOWN, 0, 0, 0);
+
+    #[cfg(feature = "board_qemu")]
+    crate::board::QEMU_EXIT_HANDLE.exit_failure();
+
     panic!("It should shutdown!");
 }