├── .github └── workflows │ └── readme.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bootloader ├── rustsbi-k210.bin └── rustsbi-qemu.bin ├── dependency ├── .keep ├── k210-hal-temp2 │ ├── .cargo-checksum.json │ ├── .github │ │ └── workflows │ │ │ ├── clippy-check.yml │ │ │ ├── cross-compile.yml │ │ │ └── security-audit.yml │ ├── CODE_OF_CONDUCT.md │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── aes.rs │ │ ├── apu.rs │ │ ├── cache.rs │ │ ├── clint.rs │ │ ├── clock.rs │ │ ├── dmac.rs │ │ ├── fft.rs │ │ ├── fpioa.rs │ │ ├── gpio.rs │ │ ├── gpiohs.rs │ │ ├── lib.rs │ │ ├── plic.rs │ │ ├── serial.rs │ │ ├── sha256.rs │ │ ├── spi.rs │ │ ├── stdout.rs │ │ ├── sysctl.rs │ │ └── time.rs ├── k210-hal │ ├── .github │ │ └── workflows │ │ │ ├── clippy-check.yml │ │ │ ├── cross-compile.yml │ │ │ └── security-audit.yml │ ├── .gitignore │ ├── CODE_OF_CONDUCT.md │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── aes.rs │ │ ├── apu.rs │ │ ├── cache.rs │ │ ├── clint.rs │ │ ├── clock.rs │ │ ├── dmac.rs │ │ ├── fft.rs │ │ ├── fpioa.rs │ │ ├── gpio.rs │ │ ├── gpiohs.rs │ │ ├── lib.rs │ │ ├── plic.rs │ │ ├── serial.rs │ │ ├── sha256.rs │ │ ├── spi.rs │ │ ├── stdout.rs │ │ ├── sysctl.rs │ │ └── time.rs ├── k210-pac │ ├── .gitignore │ ├── .travis.yml │ ├── CODE_OF_CONDUCT.md │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── ci │ │ ├── install.sh │ │ └── script.sh │ ├── k210.svd │ ├── memory-k210.x │ ├── src │ │ └── lib.rs │ └── update.sh ├── k210-soc │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── dmac.rs │ │ ├── fpioa.rs │ │ ├── gpio.rs │ │ ├── gpiohs.rs │ │ ├── lib.rs │ │ ├── sleep.rs │ │ ├── spi.rs │ │ ├── sysctl.rs │ │ ├── sysctl │ │ └── pll_compute.rs │ │ └── utils.rs ├── riscv │ ├── .github │ │ ├── CODEOWNERS │ │ └── bors.toml │ ├── .gitignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── CODE_OF_CONDUCT.md │ ├── Cargo.toml │ ├── README.md │ ├── asm.S │ ├── asm.h │ ├── assemble.ps1 │ ├── assemble.sh │ ├── bin │ │ ├── riscv32i-unknown-none-elf.a │ │ ├── riscv32ic-unknown-none-elf.a │ │ ├── riscv64i-unknown-none-elf.a │ │ └── riscv64ic-unknown-none-elf.a │ ├── build.rs │ ├── check-blobs.sh │ ├── ci │ │ ├── install.sh │ │ └── script.sh │ ├── descriptor │ │ ├── generate_hypervisor_csr.sh │ │ ├── generator.rs │ │ ├── hcounteren.txt │ │ ├── hedeleg.txt │ │ ├── hgatp.txt │ │ ├── hgeie.txt │ │ ├── hgeip.txt │ │ ├── hideleg.txt │ │ ├── hie.txt │ │ ├── hip.txt │ │ ├── hstatus.txt │ │ ├── htimedelta.txt │ │ ├── htimedeltah.txt │ │ ├── htinst.txt │ │ ├── htval.txt │ │ ├── hvip.txt │ │ ├── vsatp.txt │ │ ├── vscause.txt │ │ ├── vsepc.txt │ │ ├── vsie.txt │ │ ├── vsip.txt │ │ ├── vsscratch.txt │ │ ├── vsstatus.txt │ │ ├── vstval.txt │ │ └── vstvec.txt │ └── src │ │ ├── addr │ │ ├── gpax4.rs │ │ ├── mod.rs │ │ ├── page.rs │ │ ├── sv32.rs │ │ ├── sv39.rs │ │ └── sv48.rs │ │ ├── asm.rs │ │ ├── interrupt.rs │ │ ├── lib.rs │ │ ├── paging │ │ ├── frame_alloc.rs │ │ ├── mapper.rs │ │ ├── mod.rs │ │ ├── multi_level.rs │ │ ├── multi_level_x4.rs │ │ ├── page_table.rs │ │ └── page_table_x4.rs │ │ └── register │ │ ├── fcsr.rs │ │ ├── hpmcounterx.rs │ │ ├── hypervisorx64 │ │ ├── hcounteren.rs │ │ ├── hedeleg.rs │ │ ├── hgatp.rs │ │ ├── hgeie.rs │ │ ├── hgeip.rs │ │ ├── hideleg.rs │ │ ├── hie.rs │ │ ├── hip.rs │ │ ├── hstatus.rs │ │ ├── htimedelta.rs │ │ ├── htimedeltah.rs │ │ ├── htinst.rs │ │ ├── htval.rs │ │ ├── hvip.rs │ │ ├── mod.rs │ │ ├── vsatp.rs │ │ ├── vscause.rs │ │ ├── vsepc.rs │ │ ├── vsie.rs │ │ ├── vsip.rs │ │ ├── vsscratch.rs │ │ ├── vsstatus.rs │ │ ├── vstval.rs │ │ └── vstvec.rs │ │ ├── macros.rs │ │ ├── marchid.rs │ │ ├── mcause.rs │ │ ├── mcycle.rs │ │ ├── mcycleh.rs │ │ ├── medeleg.rs │ │ ├── mepc.rs │ │ ├── mhartid.rs │ │ ├── mhpmcounterx.rs │ │ ├── mhpmeventx.rs │ │ ├── mideleg.rs │ │ ├── mie.rs │ │ ├── mimpid.rs │ │ ├── minstret.rs │ │ ├── minstreth.rs │ │ ├── mip.rs │ │ ├── misa.rs │ │ ├── mod.rs │ │ ├── mscratch.rs │ │ ├── mstatus.rs │ │ ├── mtval.rs │ │ ├── mtvec.rs │ │ ├── mvendorid.rs │ │ ├── pmpaddrx.rs │ │ ├── pmpcfgx.rs │ │ ├── satp.rs │ │ ├── scause.rs │ │ ├── sepc.rs │ │ ├── sie.rs │ │ ├── sip.rs │ │ ├── sscratch.rs │ │ ├── sstatus.rs │ │ ├── stval.rs │ │ ├── stvec.rs │ │ ├── time.rs │ │ ├── timeh.rs │ │ ├── ucause.rs │ │ ├── uepc.rs │ │ ├── uie.rs │ │ ├── uip.rs │ │ ├── uscratch.rs │ │ ├── ustatus.rs │ │ ├── utval.rs │ │ └── utvec.rs └── virtio-drivers │ ├── .gitignore │ ├── .keep │ ├── Cargo.lock │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── examples │ └── riscv │ │ ├── .cargo │ │ └── config │ │ ├── Cargo.toml │ │ ├── Makefile │ │ ├── linker32.ld │ │ ├── linker64.ld │ │ ├── rust-toolchain │ │ └── src │ │ ├── main.rs │ │ └── virtio_impl.rs │ └── src │ ├── blk.rs │ ├── console.rs │ ├── gpu.rs │ ├── hal.rs │ ├── header.rs │ ├── input.rs │ ├── lib.rs │ ├── net.rs │ └── queue.rs ├── document ├── 总文档.md ├── 系统调用.md └── 进程系统调用说明.md ├── easy_fs ├── Cargo.toml └── src │ ├── bitmap.rs │ ├── block_cache.rs │ ├── blockdevice.rs │ ├── console.rs │ ├── efs.rs │ ├── layout.rs │ ├── lib.rs │ ├── sbi.rs │ └── vfs.rs ├── fat32-fuse ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── mnt.sh ├── qemu_fs.sh ├── sd_mnt2 │ ├── System Volume Information │ │ ├── IndexerVolumeGuid │ │ └── WPSettings.dat │ ├── cat │ ├── cmdline_args │ ├── dir0 │ │ ├── dir1 │ │ │ └── file2 │ │ └── file1 │ ├── exit │ ├── fantastic_text │ ├── filea │ ├── filetest_simple │ ├── forktest │ ├── forktest2 │ ├── forktest_simple │ ├── forktree │ ├── hello2 │ ├── hello_world │ ├── initproc │ ├── ls │ ├── matrix │ ├── mnt │ │ └── test_openat.txt │ ├── pipe_large_test │ ├── pipetest │ ├── run_pipe_test │ ├── sleep │ ├── sleep_simple │ ├── stack_overflow │ ├── testsuites_brk │ ├── testsuites_chdir │ ├── testsuites_clone │ ├── testsuites_close │ ├── testsuites_dup │ ├── testsuites_dup2 │ ├── testsuites_execve │ ├── testsuites_exit │ ├── testsuites_fork │ ├── testsuites_fstat │ ├── testsuites_getcwd │ ├── testsuites_getdents │ ├── testsuites_getpid │ ├── testsuites_getppid │ ├── testsuites_gettimeofday │ ├── testsuites_ls │ ├── testsuites_mkdir_ │ ├── testsuites_mmap │ ├── testsuites_mount │ ├── testsuites_munmap │ ├── testsuites_open │ ├── testsuites_openat │ ├── testsuites_pipe │ ├── testsuites_read │ ├── testsuites_run-all.sh │ ├── testsuites_sleep │ ├── testsuites_test_echo │ ├── testsuites_text.txt │ ├── testsuites_times │ ├── testsuites_umount │ ├── testsuites_uname │ ├── testsuites_unlink │ ├── testsuites_wait │ ├── testsuites_waitpid │ ├── testsuites_write │ ├── testsuites_yield.sh │ ├── testsuites_yield_A │ ├── testsuites_yield_B │ ├── testsuites_yield_C │ ├── text.txt │ ├── user_shell │ ├── usertests │ └── yield └── src │ └── main.rs ├── os.bin ├── pic ├── FAT manager.png ├── P_CallRelation.png ├── P_Exit.png ├── P_KernelSpace.png ├── P_StructRelation.png ├── P_UserSpace.png ├── P_Waitpid.png ├── P_Yield.png ├── README_CN.md ├── block cache.png ├── copy on write.bmp ├── copy on write.png ├── copy on write1.png ├── framework.png ├── heap.png ├── kernel space.png ├── layout.bmp ├── space layout.png ├── space layout1.png ├── task_manager.png └── user space.png ├── tools ├── .gitignore ├── LICENSE ├── README.rst ├── kflash.py ├── package.json └── setup.py ├── toyos ├── .cargo │ └── config ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Makefile ├── build.rs ├── buildfs.sh ├── last-qemu ├── riscv64-unknown-elf-gdb └── src │ ├── config.rs │ ├── console.rs │ ├── drivers │ ├── block │ │ ├── mod.rs │ │ ├── sdcard.rs │ │ └── virtio_blk.rs │ ├── mod.rs │ └── serial │ │ ├── mod.rs │ │ └── ns16550a.rs │ ├── entry.asm │ ├── fs │ ├── finfo.rs │ ├── inode.rs │ ├── iovec.rs │ ├── mod.rs │ ├── mount.rs │ ├── pipe.rs │ └── stdio.rs │ ├── lang_items.rs │ ├── link_app.S │ ├── linker-k210.ld │ ├── linker-qemu.ld │ ├── loader.rs │ ├── main.rs │ ├── memory │ ├── address.rs │ ├── heap_allocator.rs │ ├── kernel_stack.rs │ ├── memory_manager.rs │ ├── mod.rs │ ├── page_table.rs │ └── phy_frame.rs │ ├── monitor.rs │ ├── sbi.rs │ ├── sync │ ├── mod.rs │ ├── mutex.rs │ └── up.rs │ ├── syscall │ ├── config.rs │ ├── fs.rs │ ├── interface.rs │ ├── mod.rs │ ├── process.rs │ └── system_call.rs │ ├── task │ ├── mod.rs │ ├── pid.rs │ ├── processor.rs │ ├── switch.S │ ├── task_context.rs │ ├── task_control.rs │ └── task_manager.rs │ ├── timer.rs │ └── trap │ ├── mod.rs │ ├── trap.S │ ├── trap_context.rs │ └── trap_handle.rs ├── user ├── .cargo │ └── config ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Makefile └── src │ ├── bin │ └── initproc.rs │ ├── console.rs │ ├── lang_items.rs │ ├── lib.rs │ ├── linker.ld │ └── syscall.rs ├── user_C_program ├── README.md ├── check_tests.py ├── res │ └── kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz └── user │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Makefile │ ├── build-oscomp.sh │ ├── include │ ├── stddef.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ └── unistd.h │ ├── lib │ ├── arch │ │ └── riscv │ │ │ ├── crt.S │ │ │ ├── syscall_arch.h │ │ │ ├── syscall_ids.h.in │ │ │ └── user.ld │ ├── main.c │ ├── stdio.c │ ├── stdlib.c │ ├── string.c │ ├── syscall.c │ ├── syscall.h │ └── syscall_ids.h │ ├── riscv64 │ └── src │ └── oscomp │ ├── brk.c │ ├── brk_test.py │ ├── build-single-testcase.sh │ ├── chdir.c │ ├── chdir_test.py │ ├── clone.c │ ├── clone.s │ ├── clone_test.py │ ├── close.c │ ├── close_test.py │ ├── dup.c │ ├── dup2.c │ ├── dup2_test.py │ ├── dup_test.py │ ├── execve.c │ ├── execve_test.py │ ├── exit.c │ ├── exit_test.py │ ├── fork.c │ ├── fork_test.py │ ├── fstat.c │ ├── fstat_test.py │ ├── getcwd.c │ ├── getcwd_test.py │ ├── getdents.c │ ├── getdents_test.py │ ├── getpid.c │ ├── getpid_test.py │ ├── getppid.c │ ├── getppid_test.py │ ├── gettimeofday.c │ ├── gettimeofday_test.py │ ├── ktool.py │ ├── mkdir_.c │ ├── mkdir_test.py │ ├── mmap.c │ ├── mmap_test.py │ ├── mount.c │ ├── mount_test.py │ ├── munmap.c │ ├── munmap_test.py │ ├── open.c │ ├── open_test.py │ ├── openat.c │ ├── openat_test.py │ ├── pipe.c │ ├── pipe_test.py │ ├── read.c │ ├── read_test.py │ ├── run-all.sh │ ├── sleep.c │ ├── ssh_run.py │ ├── test_base.py │ ├── test_echo.c │ ├── test_runner.py │ ├── text.txt │ ├── times.c │ ├── times_test.py │ ├── umount.c │ ├── umount_test.py │ ├── uname.c │ ├── uname_test.py │ ├── unlink.c │ ├── unlink_test.py │ ├── wait.c │ ├── wait_test.py │ ├── waitpid.c │ ├── waitpid_test.py │ ├── write.c │ ├── write_test.py │ ├── yield.c │ └── yield_test.py └── 修改日志 /.github/workflows/readme.yml: -------------------------------------------------------------------------------- 1 | name: Translate README 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Setup Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 12.x 17 | # ISO Langusge Codes: https://cloud.google.com/translate/docs/languages 18 | - name: Adding README - Chinese Simplified 19 | uses: dephraiim/translate-readme@main 20 | with: 21 | LANG: English -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | fat32-fuse/fat32.img -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 MZT-srcount 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | # rustup target add riscv64gc-unknown-none-elf 3 | cd user && make elf 4 | cd toyos && make all BOARD=k210 5 | -------------------------------------------------------------------------------- /bootloader/rustsbi-k210.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/bootloader/rustsbi-k210.bin -------------------------------------------------------------------------------- /bootloader/rustsbi-qemu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/bootloader/rustsbi-qemu.bin -------------------------------------------------------------------------------- /dependency/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/dependency/.keep -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/.github/workflows/clippy-check.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Clippy Check 3 | 4 | jobs: 5 | clippy_check: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | - uses: actions-rs/toolchain@v1 10 | with: 11 | toolchain: nightly 12 | components: clippy 13 | override: true 14 | - uses: actions-rs/clippy-check@v1 15 | with: 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/.github/workflows/cross-compile.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Cross Compile 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions-rs/toolchain@v1 11 | with: 12 | toolchain: stable 13 | target: riscv64gc-unknown-none-elf 14 | override: true 15 | - uses: actions-rs/cargo@v1 16 | with: 17 | use-cross: true 18 | command: build 19 | args: --target riscv64gc-unknown-none-elf 20 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/.github/workflows/security-audit.yml: -------------------------------------------------------------------------------- 1 | name: Security Audit 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | jobs: 6 | audit: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - uses: actions-rs/audit-check@v1 11 | with: 12 | token: ${{ secrets.GITHUB_TOKEN }} 13 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "k210-hal" 3 | version = "0.2.0" 4 | authors = ["The RISC-V Team "] 5 | categories = ["embedded", "hardware-support", "no-std"] 6 | description = "Hardware Abstract Layer (HAL) support for K210, dual-core RV64GC SoC" 7 | repository = "https://github.com/riscv-rust/k210-hal" 8 | keywords = ["riscv", "k210", "hal"] 9 | license = "ISC" 10 | edition = "2018" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["riscv64imac-unknown-none-elf"] 14 | 15 | [dependencies] 16 | embedded-hal = {version = "1.0.0-alpha.1"} 17 | nb = "0.1.1" 18 | k210-pac = { path = "../k210-pac" } 19 | bitflags = "1.2.1" 20 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/apu.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) Audio Processor Unit (APU) 2 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/clint.rs: -------------------------------------------------------------------------------- 1 | //! Core Local Interruptor (CLINT) 2 | //! 3 | //! TODO: Should this module designed in a somehow IP-core peripheral create? 4 | 5 | /// mtime register 6 | pub mod mtime { 7 | use crate::pac; 8 | /// Read mtime register. 9 | pub fn read() -> u64 { 10 | unsafe { (*pac::CLINT::ptr()).mtime.read().bits() } 11 | } 12 | } 13 | 14 | /// msip register 15 | pub mod msip { 16 | use crate::pac; 17 | 18 | /// set IPI interrupt flag for one given hart 19 | pub fn set_ipi(hart_id: usize) { 20 | unsafe { 21 | (*pac::CLINT::ptr()).msip[hart_id].write(|w| 22 | w.bits(1)) 23 | } 24 | } 25 | /// clear IPI interrupt flag for one given hart 26 | pub fn clear_ipi(hart_id: usize) { 27 | unsafe { 28 | (*pac::CLINT::ptr()).msip[hart_id].write(|w| 29 | w.bits(0)) 30 | } 31 | } 32 | } 33 | 34 | /// mtimecmp register 35 | pub mod mtimecmp { 36 | use crate::pac; 37 | 38 | /// Read 64-bit mtimecmp register for certain hart id 39 | pub fn read(hart_id: usize) -> u64 { 40 | unsafe { (*pac::CLINT::ptr()).mtimecmp[hart_id].read().bits() } 41 | } 42 | 43 | /// Write 64-bit mtimecmp register for certain hart id 44 | pub fn write(hart_id: usize, bits: u64) { 45 | // Volume II: RISC-V Privileged Architectures V1.10 p.31, figure 3.15 46 | unsafe { (*pac::CLINT::ptr()).mtimecmp[hart_id].write(|w| 47 | w.bits(bits)) }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/clock.rs: -------------------------------------------------------------------------------- 1 | //! Clock configuration 2 | //use crate::pac::PRCI; 3 | use crate::time::Hertz; 4 | 5 | /// Frozen clock frequencies 6 | /// 7 | /// The existence of this value indicates that the clock configuration can no 8 | /// longer be changed. 9 | #[derive(Clone, Copy)] 10 | pub struct Clocks { 11 | cpu: Hertz, 12 | apb0: Hertz, 13 | } 14 | 15 | impl Clocks { 16 | #[doc(hidden)] 17 | pub fn new() -> Self { 18 | /* 19 | [MAIXPY]Pll0:freq:806000000 20 | [MAIXPY]Pll1:freq:398666666 21 | [MAIXPY]Pll2:freq:45066666 22 | [MAIXPY]cpu:freq:403000000 23 | [MAIXPY]kpu:freq:398666666 24 | in freq: 26000000 25 | cpu_freq: 390000000 26 | */ 27 | Self { 28 | cpu: Hertz(403_000_000), 29 | apb0: Hertz(195_000_000), 30 | } 31 | } 32 | 33 | /// Returns CPU frequency 34 | pub fn cpu(&self) -> Hertz { 35 | Hertz(self.cpu.0) 36 | } 37 | 38 | /// Returns APB0 frequency 39 | pub fn apb0(&self) -> Hertz { 40 | self.apb0 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/dmac.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) Direct Memory Access Controller (DMAC) 2 | use crate::{pac, sysctl}; 3 | 4 | pub fn dmac_id() -> u64 { 5 | unsafe { (*pac::DMAC::ptr()).id.read().bits() } 6 | } 7 | 8 | pub fn dmac_version() -> u64 { 9 | unsafe { (*pac::DMAC::ptr()).compver.read().bits() } 10 | } 11 | 12 | pub trait DmacExt { 13 | fn configure(self, /* sysctl ACLK clock */) -> Dmac; 14 | } 15 | 16 | impl DmacExt for pac::DMAC { 17 | fn configure(self, /* sysctl ACLK clock */) -> Dmac { 18 | // enable 19 | sysctl::clk_en_peri().modify(|_, w| w.dma_clk_en().set_bit()); 20 | // todo: reset 21 | Dmac {} // todo 22 | } 23 | } 24 | 25 | pub struct Dmac { 26 | 27 | } 28 | 29 | // pub struct C0 { 30 | // // todo 31 | // pub async fn poll() { 32 | 33 | // } 34 | // } 35 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/fft.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) Fast Fourier Transform (FFT) 2 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/sha256.rs: -------------------------------------------------------------------------------- 1 | //! Secure Hash Algorithm-256 (SHA256) 2 | 3 | use crate::pac::SHA256; 4 | use crate::sysctl::{self, APB0}; 5 | 6 | /// SHA256 module abstraction 7 | pub struct Sha256 { 8 | sha256: SHA256, 9 | } 10 | 11 | impl Sha256 { 12 | pub fn sha256(sha256: SHA256, apb0: &mut APB0) -> Sha256 { 13 | apb0.enable(); 14 | sysctl::clk_en_peri().modify(|_r, w| 15 | w.sha_clk_en().set_bit()); 16 | sysctl::peri_reset().modify(|_r, w| 17 | w.sha_reset().set_bit()); 18 | sysctl::peri_reset().modify(|_r, w| 19 | w.sha_reset().clear_bit()); 20 | Sha256 { sha256 } 21 | } 22 | 23 | pub fn new_digest(self) -> Digest { 24 | todo!() 25 | } 26 | 27 | pub fn release(self) -> SHA256 { 28 | sysctl::clk_en_peri().modify(|_r, w| 29 | w.sha_clk_en().clear_bit()); 30 | self.sha256 31 | } 32 | } 33 | 34 | pub struct Digest { 35 | sha256: SHA256, 36 | } 37 | 38 | impl Digest { 39 | pub fn write_u32(&mut self, n: u32) { 40 | let _todo = n; 41 | todo!() 42 | } 43 | 44 | pub fn finish(&self, out: &mut [u8; 32]) { 45 | let _todo = out; 46 | todo!() 47 | } 48 | 49 | pub fn free(self) -> Sha256 { 50 | Sha256 { sha256: self.sha256 } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/stdout.rs: -------------------------------------------------------------------------------- 1 | //! Stdout 2 | pub use core::fmt::Write; 3 | use nb::block; 4 | 5 | /// Stdout implements the core::fmt::Write trait for hal::serial::Write 6 | /// implementations. 7 | pub struct Stdout<'p, T>(pub &'p mut T); 8 | 9 | impl<'p, T> Write for Stdout<'p, T> 10 | where 11 | T: embedded_hal::serial::nb::Write, 12 | { 13 | fn write_str(&mut self, s: &str) -> core::fmt::Result { 14 | for byte in s.as_bytes() { 15 | if *byte == b'\n' { 16 | let res = block!(self.0.try_write(b'\r')); 17 | 18 | if res.is_err() { 19 | return Err(core::fmt::Error); 20 | } 21 | } 22 | 23 | let res = block!(self.0.try_write(*byte)); 24 | 25 | if res.is_err() { 26 | return Err(core::fmt::Error); 27 | } 28 | } 29 | Ok(()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/sysctl.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) System Controller (SYSCTL) 2 | 3 | use crate::pac::{sysctl, SYSCTL}; 4 | 5 | pub(crate) fn sysctl<'a>() -> &'a sysctl::RegisterBlock { 6 | unsafe { &*(SYSCTL::ptr()) } 7 | } 8 | 9 | pub(crate) fn clk_en_cent<'a>() -> &'a sysctl::CLK_EN_CENT { 10 | &sysctl().clk_en_cent 11 | } 12 | 13 | pub(crate) fn clk_en_peri<'a>() -> &'a sysctl::CLK_EN_PERI { 14 | &sysctl().clk_en_peri 15 | } 16 | 17 | pub(crate) fn peri_reset<'a>() -> &'a sysctl::PERI_RESET { 18 | &sysctl().peri_reset 19 | } 20 | 21 | pub trait SysctlExt { 22 | fn constrain(self) -> Parts; 23 | } 24 | 25 | impl SysctlExt for SYSCTL { 26 | fn constrain(self) -> Parts { 27 | Parts { 28 | apb0: APB0 { _ownership: () }, 29 | } 30 | } 31 | } 32 | 33 | // ref: sysctl.c 34 | pub struct Parts { 35 | // todo: PLL0, PLL1, PLL2 36 | // todo: CPU, SRAM, APB-bus, ROM, DMA, AI 37 | pub apb0: APB0, 38 | // pub apb1: APB1, 39 | // pub apb2: APB2, 40 | } 41 | 42 | pub struct APB0 { 43 | _ownership: () 44 | } 45 | 46 | impl APB0 { 47 | pub(crate) fn enable(&mut self) { 48 | clk_en_cent().modify( 49 | |_r, w| 50 | w.apb0_clk_en().set_bit() 51 | ); 52 | } 53 | } 54 | 55 | // pub struct APB1 { 56 | // _ownership: () 57 | // } 58 | 59 | // pub struct APB2 { 60 | // _ownership: () 61 | // } 62 | -------------------------------------------------------------------------------- /dependency/k210-hal-temp2/src/time.rs: -------------------------------------------------------------------------------- 1 | //! Time units 2 | 3 | /// Bits per second 4 | #[derive(Clone, Copy)] 5 | pub struct Bps(pub u32); 6 | 7 | /// Hertz 8 | #[derive(Clone, Copy)] 9 | pub struct Hertz(pub u32); 10 | 11 | /// KiloHertz 12 | #[derive(Clone, Copy)] 13 | pub struct KiloHertz(pub u32); 14 | 15 | /// MegaHertz 16 | #[derive(Clone, Copy)] 17 | pub struct MegaHertz(pub u32); 18 | 19 | /// Extension trait that adds convenience methods to the `u32` type 20 | pub trait U32Ext { 21 | /// Wrap in `Bps` 22 | fn bps(self) -> Bps; 23 | 24 | /// Wrap in `Hertz` 25 | fn hz(self) -> Hertz; 26 | 27 | /// Wrap in `KiloHertz` 28 | fn khz(self) -> KiloHertz; 29 | 30 | /// Wrap in `MegaHertz` 31 | fn mhz(self) -> MegaHertz; 32 | } 33 | 34 | impl U32Ext for u32 { 35 | fn bps(self) -> Bps { 36 | Bps(self) 37 | } 38 | 39 | fn hz(self) -> Hertz { 40 | Hertz(self) 41 | } 42 | 43 | fn khz(self) -> KiloHertz { 44 | KiloHertz(self) 45 | } 46 | 47 | fn mhz(self) -> MegaHertz { 48 | MegaHertz(self) 49 | } 50 | } 51 | 52 | impl Into for KiloHertz { 53 | fn into(self) -> Hertz { 54 | Hertz(self.0 * 1_000) 55 | } 56 | } 57 | 58 | impl Into for MegaHertz { 59 | fn into(self) -> Hertz { 60 | Hertz(self.0 * 1_000_000) 61 | } 62 | } 63 | 64 | impl Into for MegaHertz { 65 | fn into(self) -> KiloHertz { 66 | KiloHertz(self.0 * 1_000) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /dependency/k210-hal/.github/workflows/clippy-check.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Clippy Check 3 | 4 | jobs: 5 | clippy_check: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | - uses: actions-rs/toolchain@v1 10 | with: 11 | toolchain: nightly 12 | components: clippy 13 | override: true 14 | - uses: actions-rs/clippy-check@v1 15 | with: 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /dependency/k210-hal/.github/workflows/cross-compile.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Cross Compile 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions-rs/toolchain@v1 11 | with: 12 | toolchain: stable 13 | target: riscv64gc-unknown-none-elf 14 | override: true 15 | - uses: actions-rs/cargo@v1 16 | with: 17 | use-cross: true 18 | command: build 19 | args: --target riscv64gc-unknown-none-elf 20 | -------------------------------------------------------------------------------- /dependency/k210-hal/.github/workflows/security-audit.yml: -------------------------------------------------------------------------------- 1 | name: Security Audit 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | jobs: 6 | audit: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - uses: actions-rs/audit-check@v1 11 | with: 12 | token: ${{ secrets.GITHUB_TOKEN }} 13 | -------------------------------------------------------------------------------- /dependency/k210-hal/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | .idea 5 | -------------------------------------------------------------------------------- /dependency/k210-hal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "k210-hal" 3 | version = "0.2.0" 4 | authors = ["The RISC-V Team "] 5 | categories = ["embedded", "hardware-support", "no-std"] 6 | description = "Hardware Abstract Layer (HAL) support for K210, dual-core RV64GC SoC" 7 | repository = "https://github.com/riscv-rust/k210-hal" 8 | keywords = ["riscv", "k210", "hal"] 9 | license = "ISC" 10 | edition = "2018" 11 | 12 | [package.metadata.docs.rs] 13 | targets = ["riscv64imac-unknown-none-elf"] 14 | 15 | [dependencies] 16 | embedded-hal = {version="0.2.7", features = ["unproven"] } 17 | nb = "0.1.1" 18 | k210-pac = { path = "../k210-pac" } 19 | bitflags = "1.2.1" 20 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/apu.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) Audio Processor Unit (APU) 2 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/clint.rs: -------------------------------------------------------------------------------- 1 | //! Core Local Interruptor (CLINT) 2 | //! 3 | //! TODO: Should this module designed in a somehow IP-core peripheral create? 4 | 5 | /// mtime register 6 | pub mod mtime { 7 | use crate::pac; 8 | /// Read mtime register. 9 | pub fn read() -> u64 { 10 | unsafe { (*pac::CLINT::ptr()).mtime.read().bits() } 11 | } 12 | } 13 | 14 | /// msip register 15 | pub mod msip { 16 | use crate::pac; 17 | 18 | /// set IPI interrupt flag for one given hart 19 | pub fn set_ipi(hart_id: usize) { 20 | unsafe { (*pac::CLINT::ptr()).msip[hart_id].write(|w| w.bits(1)) } 21 | } 22 | /// clear IPI interrupt flag for one given hart 23 | pub fn clear_ipi(hart_id: usize) { 24 | unsafe { (*pac::CLINT::ptr()).msip[hart_id].write(|w| w.bits(0)) } 25 | } 26 | } 27 | 28 | /// mtimecmp register 29 | pub mod mtimecmp { 30 | use crate::pac; 31 | 32 | /// Read 64-bit mtimecmp register for certain hart id 33 | pub fn read(hart_id: usize) -> u64 { 34 | unsafe { (*pac::CLINT::ptr()).mtimecmp[hart_id].read().bits() } 35 | } 36 | 37 | /// Write 64-bit mtimecmp register for certain hart id 38 | pub fn write(hart_id: usize, bits: u64) { 39 | // Volume II: RISC-V Privileged Architectures V1.10 p.31, figure 3.15 40 | unsafe { (*pac::CLINT::ptr()).mtimecmp[hart_id].write(|w| w.bits(bits)) }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/clock.rs: -------------------------------------------------------------------------------- 1 | //! Clock configuration 2 | //use crate::pac::PRCI; 3 | // use crate::sysctl::ACLK; 4 | use crate::time::Hertz; 5 | 6 | /// Frozen clock frequencies 7 | /// 8 | /// The existence of this value indicates that the clock configuration can no 9 | /// longer be changed. 10 | #[derive(Clone, Copy)] 11 | pub struct Clocks { 12 | pub(crate) aclk: Hertz, 13 | pub(crate) apb0: Hertz, 14 | } 15 | 16 | impl Clocks { 17 | #[doc(hidden)] 18 | pub fn new() -> Self { 19 | /* 20 | [MAIXPY]Pll0:freq:806000000 21 | [MAIXPY]Pll1:freq:398666666 22 | [MAIXPY]Pll2:freq:45066666 23 | [MAIXPY]cpu:freq:403000000 24 | [MAIXPY]kpu:freq:398666666 25 | in freq: 26000000 26 | cpu_freq: 390000000 27 | */ 28 | Self { 29 | aclk: Hertz(390_000_000), 30 | apb0: Hertz(195_000_000), 31 | } 32 | } 33 | 34 | /// Returns CPU frequency 35 | pub fn cpu(&self) -> Hertz { 36 | Hertz(self.aclk.0) 37 | } 38 | 39 | /// Returns APB0 frequency 40 | pub fn apb0(&self) -> Hertz { 41 | self.apb0 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/dmac.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) Direct Memory Access Controller (DMAC) 2 | use crate::{pac, sysctl}; 3 | 4 | pub fn dmac_id() -> u64 { 5 | unsafe { (*pac::DMAC::ptr()).id.read().bits() } 6 | } 7 | 8 | pub fn dmac_version() -> u64 { 9 | unsafe { (*pac::DMAC::ptr()).compver.read().bits() } 10 | } 11 | 12 | pub trait DmacExt { 13 | fn configure(self /* sysctl ACLK clock */) -> Dmac; 14 | } 15 | 16 | impl DmacExt for pac::DMAC { 17 | fn configure(self /* sysctl ACLK clock */) -> Dmac { 18 | // enable 19 | sysctl::clk_en_peri().modify(|_, w| w.dma_clk_en().set_bit()); 20 | // todo: reset 21 | Dmac {} // todo 22 | } 23 | } 24 | 25 | pub struct Dmac {} 26 | 27 | // pub struct C0 { 28 | // // todo 29 | // pub async fn poll() { 30 | 31 | // } 32 | // } 33 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/fft.rs: -------------------------------------------------------------------------------- 1 | //! (TODO) Fast Fourier Transform (FFT) 2 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/sha256.rs: -------------------------------------------------------------------------------- 1 | //! Secure Hash Algorithm-256 (SHA256) 2 | 3 | use crate::pac::SHA256; 4 | use crate::sysctl::{self, APB0}; 5 | 6 | /// SHA256 module abstraction 7 | pub struct Sha256 { 8 | sha256: SHA256, 9 | } 10 | 11 | impl Sha256 { 12 | pub fn new(sha256: SHA256, apb0: &mut APB0) -> Sha256 { 13 | apb0.enable(); 14 | sysctl::clk_en_peri().modify(|_r, w| w.sha_clk_en().set_bit()); 15 | sysctl::peri_reset().modify(|_r, w| w.sha_reset().set_bit()); 16 | sysctl::peri_reset().modify(|_r, w| w.sha_reset().clear_bit()); 17 | Sha256 { sha256 } 18 | } 19 | 20 | pub fn new_digest(self) -> Digest { 21 | todo!() 22 | } 23 | 24 | pub fn release(self) -> SHA256 { 25 | sysctl::clk_en_peri().modify(|_r, w| w.sha_clk_en().clear_bit()); 26 | self.sha256 27 | } 28 | } 29 | 30 | pub struct Digest { 31 | sha256: SHA256, 32 | } 33 | 34 | impl Digest { 35 | pub fn write_u32(&mut self, n: u32) { 36 | let _todo = n; 37 | todo!() 38 | } 39 | 40 | pub fn finish(&self, out: &mut [u8; 32]) { 41 | let _todo = out; 42 | todo!() 43 | } 44 | 45 | pub fn free(self) -> Sha256 { 46 | Sha256 { 47 | sha256: self.sha256, 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/stdout.rs: -------------------------------------------------------------------------------- 1 | //! Stdout 2 | pub use core::fmt::Write; 3 | use nb::block; 4 | 5 | /// Stdout implements the core::fmt::Write trait for hal::serial::Write 6 | /// implementations. 7 | pub struct Stdout<'p, T>(pub &'p mut T); 8 | 9 | impl<'p, T> Write for Stdout<'p, T> 10 | where 11 | T: embedded_hal::serial::Write, 12 | { 13 | fn write_str(&mut self, s: &str) -> core::fmt::Result { 14 | for byte in s.as_bytes() { 15 | if *byte == b'\n' { 16 | let res = block!(self.0.write(b'\r')); 17 | 18 | if res.is_err() { 19 | return Err(core::fmt::Error); 20 | } 21 | } 22 | 23 | let res = block!(self.0.write(*byte)); 24 | 25 | if res.is_err() { 26 | return Err(core::fmt::Error); 27 | } 28 | } 29 | Ok(()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dependency/k210-hal/src/time.rs: -------------------------------------------------------------------------------- 1 | //! Time units 2 | 3 | /// Bits per second 4 | #[derive(Clone, Copy)] 5 | pub struct Bps(pub u32); 6 | 7 | /// Hertz 8 | #[derive(Clone, Copy)] 9 | pub struct Hertz(pub u32); 10 | 11 | /// KiloHertz 12 | #[derive(Clone, Copy)] 13 | pub struct KiloHertz(pub u32); 14 | 15 | /// MegaHertz 16 | #[derive(Clone, Copy)] 17 | pub struct MegaHertz(pub u32); 18 | 19 | /// Extension trait that adds convenience methods to the `u32` type 20 | pub trait U32Ext { 21 | /// Wrap in `Bps` 22 | fn bps(self) -> Bps; 23 | 24 | /// Wrap in `Hertz` 25 | fn hz(self) -> Hertz; 26 | 27 | /// Wrap in `KiloHertz` 28 | fn khz(self) -> KiloHertz; 29 | 30 | /// Wrap in `MegaHertz` 31 | fn mhz(self) -> MegaHertz; 32 | } 33 | 34 | impl U32Ext for u32 { 35 | fn bps(self) -> Bps { 36 | Bps(self) 37 | } 38 | 39 | fn hz(self) -> Hertz { 40 | Hertz(self) 41 | } 42 | 43 | fn khz(self) -> KiloHertz { 44 | KiloHertz(self) 45 | } 46 | 47 | fn mhz(self) -> MegaHertz { 48 | MegaHertz(self) 49 | } 50 | } 51 | 52 | impl From for Hertz { 53 | fn from(src: KiloHertz) -> Hertz { 54 | Hertz(src.0 * 1_000) 55 | } 56 | } 57 | 58 | impl From for Hertz { 59 | fn from(src: MegaHertz) -> Hertz { 60 | Hertz(src.0 * 1_000_000) 61 | } 62 | } 63 | 64 | impl From for KiloHertz { 65 | fn from(src: MegaHertz) -> KiloHertz { 66 | KiloHertz(src.0 * 1_000) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /dependency/k210-pac/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock -------------------------------------------------------------------------------- /dependency/k210-pac/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | 3 | env: 4 | - TARGET=x86_64-unknown-linux-gnu 5 | - TARGET=riscv64gc-unknown-none-elf 6 | 7 | rust: 8 | - nightly 9 | - stable 10 | 11 | if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) 12 | 13 | 14 | install: 15 | - ci/install.sh 16 | 17 | script: 18 | - ci/script.sh 19 | 20 | branches: 21 | only: 22 | - master 23 | - staging 24 | - trying 25 | 26 | notifications: 27 | email: 28 | on_success: never 29 | -------------------------------------------------------------------------------- /dependency/k210-pac/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "k210-pac" 3 | version = "0.2.0" 4 | authors = ["The RISC-V Team "] 5 | categories = ["embedded", "hardware-support", "no-std"] 6 | description = "Peripheral access API for K210 SoC" 7 | repository = "https://github.com/riscv-rust/k210-pac" 8 | keywords = ["riscv", "k210", "register", "peripheral"] 9 | license = "ISC" 10 | edition = "2018" 11 | 12 | [dependencies] 13 | bare-metal = "0.2.4" 14 | riscv = "0.6.0" 15 | riscv-rt = { version = "0.8", optional = true } 16 | vcell = "0.1.2" 17 | 18 | -------------------------------------------------------------------------------- /dependency/k210-pac/README.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/d/k210-pac.svg)](https://crates.io/crates/k210-pac) 2 | [![crates.io](https://img.shields.io/crates/v/k210-pac.svg)](https://crates.io/crates/k210-pac) 3 | [![Build Status](https://travis-ci.org/riscv-rust/k210-pac.svg?branch=master)](https://travis-ci.org/riscv-rust/k210-pac) 4 | 5 | # `k210-pac` 6 | 7 | > Peripheral access API for K210 SoC 8 | 9 | This project is developed and maintained by the [RISC-V team][team]. 10 | 11 | ## [Documentation](https://docs.rs/crate/k210-pac) 12 | 13 | ## License 14 | 15 | Copyright 2019 [RISC-V team][team] 16 | 17 | Permission to use, copy, modify, and/or distribute this software for any 18 | purpose with or without fee is hereby granted, provided that the above 19 | copyright notice and this permission notice appear in all copies. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 22 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 24 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 25 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 26 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 27 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28 | 29 | ## Code of Conduct 30 | 31 | Contribution to this crate is organized under the terms of the [Rust Code of 32 | Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises 33 | to intervene to uphold that code of conduct. 34 | 35 | [CoC]: CODE_OF_CONDUCT.md 36 | [team]: https://github.com/rust-embedded/wg#the-risc-v-team 37 | -------------------------------------------------------------------------------- /dependency/k210-pac/build.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; 2 | use std::path::PathBuf; 3 | use std::{env, fs}; 4 | 5 | fn main() { 6 | // Put the linker script somewhere the linker can find it 7 | let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); 8 | println!("cargo:rustc-link-search={}", out_dir.display()); 9 | 10 | fs::File::create(out_dir.join("memory-k210.x")) 11 | .unwrap() 12 | .write_all(include_bytes!("memory-k210.x")) 13 | .unwrap(); 14 | println!("cargo:rerun-if-changed=memory-k210.x"); 15 | } 16 | -------------------------------------------------------------------------------- /dependency/k210-pac/ci/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | rustup target add $TARGET 6 | -------------------------------------------------------------------------------- /dependency/k210-pac/ci/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | cargo check --target $TARGET 6 | cargo check --target $TARGET --features rt 7 | -------------------------------------------------------------------------------- /dependency/k210-pac/memory-k210.x: -------------------------------------------------------------------------------- 1 | _max_hart_id = 1; 2 | 3 | MEMORY 4 | { 5 | SRAM : ORIGIN = 0x80000000, LENGTH = 6M 6 | AI_SRAM : ORIGIN = 0x80600000, LENGTH = 2M 7 | SRAM_NOCACHE : ORIGIN = 0x40000000, LENGTH = 6M 8 | AI_SRAM_NOCACHE : ORIGIN = 0x40600000, LENGTH = 2M 9 | } 10 | -------------------------------------------------------------------------------- /dependency/k210-pac/update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -x 3 | set -e 4 | 5 | rm -rf src 6 | mkdir src 7 | svd2rust --target riscv -i k210.svd 8 | mv lib.rs src/ 9 | cargo fmt 10 | -------------------------------------------------------------------------------- /dependency/k210-soc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "k210-soc" 3 | version = "0.1.0" 4 | authors = ["Yifan Wu "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | k210-hal = { path = "../k210-hal" } 11 | k210-pac = { path = "../k210-pac" } 12 | riscv = { path = "../riscv", features = ["inline-asm"] } 13 | -------------------------------------------------------------------------------- /dependency/k210-soc/README.md: -------------------------------------------------------------------------------- 1 | From [here](https://github.com/laanwj/k210-sdk-stuff/tree/master/rust/k210-shared/src/soc). -------------------------------------------------------------------------------- /dependency/k210-soc/src/gpio.rs: -------------------------------------------------------------------------------- 1 | //! GPIO peripheral 2 | 3 | #![allow(non_camel_case_types)] 4 | 5 | #[derive(Copy, Clone, PartialEq, Eq)] 6 | pub enum direction { 7 | INPUT, 8 | OUTPUT, 9 | } 10 | 11 | // TODO -------------------------------------------------------------------------------- /dependency/k210-soc/src/gpiohs.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | 3 | //! GPIOHS peripheral 4 | //use k210_hal::pac; 5 | use k210_pac as pac; 6 | 7 | use super::gpio; 8 | use super::utils::{set_bit,get_bit}; 9 | 10 | // TODO embedded-hal::digital::v2::{InputPin, OutputPin} 11 | 12 | /** Set input/output direction for a GPIOHS pin */ 13 | pub fn set_direction(pin: u8, direction: gpio::direction) { 14 | unsafe { 15 | let ptr = pac::GPIOHS::ptr(); 16 | (*ptr) 17 | .output_en 18 | .modify(|r, w| w.bits(set_bit(r.bits(), pin, direction == gpio::direction::OUTPUT))); 19 | (*ptr) 20 | .input_en 21 | .modify(|r, w| w.bits(set_bit(r.bits(), pin, direction == gpio::direction::INPUT))); 22 | } 23 | } 24 | 25 | /** Set output value for a GPIOHS pin */ 26 | pub fn set_pin(pin: u8, value: bool) { 27 | unsafe { 28 | let ptr = pac::GPIOHS::ptr(); 29 | (*ptr) 30 | .output_val 31 | .modify(|r, w| w.bits(set_bit(r.bits(), pin, value))); 32 | } 33 | } 34 | 35 | /** Get input value for a GPIOHS pin */ 36 | pub fn get_pin(pin: u8) -> bool { 37 | unsafe { 38 | let ptr = pac::GPIOHS::ptr(); 39 | get_bit((*ptr).input_val.read().bits(), pin) 40 | } 41 | } -------------------------------------------------------------------------------- /dependency/k210-soc/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | 3 | pub mod dmac; 4 | pub mod fpioa; 5 | pub mod gpio; 6 | pub mod gpiohs; 7 | pub mod sleep; 8 | pub mod spi; 9 | pub mod sysctl; 10 | pub mod utils; 11 | -------------------------------------------------------------------------------- /dependency/k210-soc/src/sleep.rs: -------------------------------------------------------------------------------- 1 | use super::sysctl; 2 | use riscv::register::time; 3 | 4 | pub fn time_sleep(n: usize) { 5 | let start = time::read(); 6 | while time::read() < start + n {} 7 | } 8 | 9 | pub fn usleep(n: usize) { 10 | let freq = sysctl::clock_get_freq(sysctl::clock::CPU) as usize / 62; 11 | time_sleep(freq * n / 1000000); 12 | } 13 | -------------------------------------------------------------------------------- /dependency/k210-soc/src/utils.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | 3 | //! Miscelleneous utilities for SoC functions (private) 4 | 5 | pub fn set_bit(inval: u32, bit: u8, state: bool) -> u32 { 6 | if state { 7 | inval | (1 << u32::from(bit)) 8 | } else { 9 | inval & !(1 << u32::from(bit)) 10 | } 11 | } 12 | 13 | pub fn get_bit(inval: u32, bit: u8) -> bool { 14 | (inval & (1 << u32::from(bit))) != 0 15 | } -------------------------------------------------------------------------------- /dependency/riscv/.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @rust-embedded/riscv -------------------------------------------------------------------------------- /dependency/riscv/.github/bors.toml: -------------------------------------------------------------------------------- 1 | block_labels = ["needs-decision"] 2 | delete_merged_branches = true 3 | required_approvals = 1 4 | status = ["continuous-integration/travis-ci/push"] 5 | -------------------------------------------------------------------------------- /dependency/riscv/.gitignore: -------------------------------------------------------------------------------- 1 | Cargo.lock 2 | target/ 3 | bin/*.after 4 | bin/*.before 5 | bin/*.o 6 | -------------------------------------------------------------------------------- /dependency/riscv/.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | 3 | env: 4 | - TARGET=x86_64-unknown-linux-gnu 5 | - TARGET=riscv32imac-unknown-none-elf 6 | - TARGET=riscv64imac-unknown-none-elf 7 | - TARGET=riscv64gc-unknown-none-elf 8 | 9 | rust: 10 | - nightly 11 | - stable 12 | - 1.42.0 # MSRV 13 | 14 | if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) 15 | 16 | matrix: 17 | allow_failures: 18 | - rust: nightly 19 | 20 | include: 21 | - env: CHECK_BLOBS=1 22 | rust: 23 | language: bash 24 | if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) 25 | 26 | - env: RUSTFMT=1 27 | rust: stable 28 | if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) 29 | 30 | 31 | install: 32 | - ci/install.sh 33 | 34 | script: 35 | - ci/script.sh 36 | 37 | 38 | cache: 39 | cargo: true 40 | directories: 41 | - gcc 42 | 43 | branches: 44 | only: 45 | - master 46 | - staging 47 | - trying 48 | 49 | notifications: 50 | email: 51 | on_success: never 52 | -------------------------------------------------------------------------------- /dependency/riscv/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [Unreleased] 9 | 10 | ## [v0.6.0] - 2020-06-20 11 | 12 | ### Changed 13 | 14 | - `Mtvec::trap_mode()`, `Stvec::trap_mode()` and `Utvec::trap_mode()` functions now return `Option` (breaking change) 15 | - Updated Minimum Supported Rust Version to 1.42.0 16 | - Use `llvm_asm!` instead of `asm!` 17 | 18 | ### Removed 19 | 20 | - vexriscv-specific registers were moved to the `vexriscv` crate 21 | 22 | ## [v0.5.6] - 2020-03-14 23 | 24 | ### Added 25 | 26 | - Added vexriscv-specific registers 27 | 28 | ## [v0.5.5] - 2020-02-28 29 | 30 | ### Added 31 | 32 | - Added `riscv32i-unknown-none-elf` target support 33 | - Added user trap setup and handling registers 34 | - Added write methods for the `mip` and `satp` registers 35 | - Added `mideleg` register 36 | - Added Changelog 37 | 38 | ### Changed 39 | 40 | - Fixed MSRV by restricting the upper bound of `bare-metal` version 41 | 42 | [Unreleased]: https://github.com/rust-embedded/riscv/compare/v0.6.0...HEAD 43 | [v0.6.0]: https://github.com/rust-embedded/riscv/compare/v0.5.6...v0.6.0 44 | [v0.5.6]: https://github.com/rust-embedded/riscv/compare/v0.5.5...v0.5.6 45 | [v0.5.5]: https://github.com/rust-embedded/riscv/compare/v0.5.4...v0.5.5 46 | -------------------------------------------------------------------------------- /dependency/riscv/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "riscv" 3 | version = "0.6.0" 4 | repository = "https://github.com/rust-embedded/riscv" 5 | authors = ["The RISC-V Team "] 6 | categories = ["embedded", "hardware-support", "no-std"] 7 | description = "Low level access to RISC-V processors" 8 | keywords = ["riscv", "register", "peripheral"] 9 | license = "ISC" 10 | 11 | [dependencies] 12 | bare-metal = "0.2.5" 13 | bitflags = "1.0" 14 | bit_field = "0.10.0" 15 | log = "0.4" 16 | 17 | [build-dependencies] 18 | riscv-target = "0.1.2" 19 | 20 | [features] 21 | inline-asm = [] 22 | -------------------------------------------------------------------------------- /dependency/riscv/asm.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASM_H 2 | #define __ASM_H 3 | 4 | #define REG_READ(name, offset) \ 5 | .section .text.__read_ ## name; \ 6 | .global __read_ ## name; \ 7 | __read_ ## name: \ 8 | csrrs a0, offset, x0; \ 9 | ret 10 | 11 | #define REG_WRITE(name, offset) \ 12 | .section .text.__write_ ## name; \ 13 | .global __write_ ## name; \ 14 | __write_ ## name: \ 15 | csrrw x0, offset, a0; \ 16 | ret 17 | 18 | #define REG_SET(name, offset) \ 19 | .section .text.__set_ ## name; \ 20 | .global __set_ ## name; \ 21 | __set_ ## name: \ 22 | csrrs x0, offset, a0; \ 23 | ret 24 | 25 | #define REG_CLEAR(name, offset) \ 26 | .section .text.__clear_ ## name; \ 27 | .global __clear_ ## name; \ 28 | __clear_ ## name: \ 29 | csrrc x0, offset, a0; \ 30 | ret 31 | 32 | 33 | #define REG_READ_WRITE(name, offset) REG_READ(name, offset); REG_WRITE(name, offset) 34 | #define REG_SET_CLEAR(name, offset) REG_SET(name, offset); REG_CLEAR(name, offset) 35 | 36 | #define RW(offset, name) REG_READ_WRITE(name, offset); REG_SET_CLEAR(name, offset) 37 | #define RO(offset, name) REG_READ(name, offset) 38 | 39 | #if __riscv_xlen == 32 40 | #define RW32(offset, name) RW(offset, name) 41 | #define RO32(offset, name) RO(offset, name) 42 | #else 43 | #define RW32(offset, name) 44 | #define RO32(offset, name) 45 | #endif 46 | 47 | #endif /* __ASM_H */ 48 | 49 | -------------------------------------------------------------------------------- /dependency/riscv/assemble.ps1: -------------------------------------------------------------------------------- 1 | New-Item -Force -Name bin -Type Directory 2 | 3 | # remove existing blobs because otherwise this will append object files to the old blobs 4 | Remove-Item -Force bin/*.a 5 | 6 | $crate = "riscv" 7 | 8 | riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32i asm.S -o bin/$crate.o 9 | riscv64-unknown-elf-ar crs bin/riscv32i-unknown-none-elf.a bin/$crate.o 10 | 11 | riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32ic asm.S -o bin/$crate.o 12 | riscv64-unknown-elf-ar crs bin/riscv32ic-unknown-none-elf.a bin/$crate.o 13 | 14 | riscv64-unknown-elf-gcc -c -mabi=lp64 -march=rv64i asm.S -o bin/$crate.o 15 | riscv64-unknown-elf-ar crs bin/riscv64i-unknown-none-elf.a bin/$crate.o 16 | 17 | riscv64-unknown-elf-gcc -c -mabi=lp64 -march=rv64ic asm.S -o bin/$crate.o 18 | riscv64-unknown-elf-ar crs bin/riscv64ic-unknown-none-elf.a bin/$crate.o 19 | 20 | Remove-Item bin/$crate.o 21 | -------------------------------------------------------------------------------- /dependency/riscv/assemble.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | crate=riscv 6 | 7 | # remove existing blobs because otherwise this will append object files to the old blobs 8 | rm -f bin/*.a 9 | 10 | riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32i asm.S -o bin/$crate.o 11 | ar crs bin/riscv32i-unknown-none-elf.a bin/$crate.o 12 | 13 | riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32ic asm.S -o bin/$crate.o 14 | ar crs bin/riscv32ic-unknown-none-elf.a bin/$crate.o 15 | 16 | riscv64-unknown-elf-gcc -c -mabi=lp64 -march=rv64i asm.S -o bin/$crate.o 17 | ar crs bin/riscv64i-unknown-none-elf.a bin/$crate.o 18 | 19 | riscv64-unknown-elf-gcc -c -mabi=lp64 -march=rv64ic asm.S -o bin/$crate.o 20 | ar crs bin/riscv64ic-unknown-none-elf.a bin/$crate.o 21 | 22 | rm bin/$crate.o 23 | -------------------------------------------------------------------------------- /dependency/riscv/bin/riscv32i-unknown-none-elf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/dependency/riscv/bin/riscv32i-unknown-none-elf.a -------------------------------------------------------------------------------- /dependency/riscv/bin/riscv32ic-unknown-none-elf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/dependency/riscv/bin/riscv32ic-unknown-none-elf.a -------------------------------------------------------------------------------- /dependency/riscv/bin/riscv64i-unknown-none-elf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/dependency/riscv/bin/riscv64i-unknown-none-elf.a -------------------------------------------------------------------------------- /dependency/riscv/bin/riscv64ic-unknown-none-elf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/dependency/riscv/bin/riscv64ic-unknown-none-elf.a -------------------------------------------------------------------------------- /dependency/riscv/build.rs: -------------------------------------------------------------------------------- 1 | extern crate riscv_target; 2 | 3 | use riscv_target::Target; 4 | use std::path::PathBuf; 5 | use std::{env, fs}; 6 | 7 | fn main() { 8 | let target = env::var("TARGET").unwrap(); 9 | let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); 10 | let name = env::var("CARGO_PKG_NAME").unwrap(); 11 | 12 | if target.starts_with("riscv") && env::var_os("CARGO_FEATURE_INLINE_ASM").is_none() { 13 | let mut target = Target::from_target_str(&target); 14 | target.retain_extensions("ic"); 15 | 16 | let target = target.to_string(); 17 | 18 | fs::copy( 19 | format!("bin/{}.a", target), 20 | out_dir.join(format!("lib{}.a", name)), 21 | ) 22 | .unwrap(); 23 | 24 | println!("cargo:rustc-link-lib=static={}", name); 25 | println!("cargo:rustc-link-search={}", out_dir.display()); 26 | } 27 | 28 | if target.contains("riscv32") { 29 | println!("cargo:rustc-cfg=riscv"); 30 | println!("cargo:rustc-cfg=riscv32"); 31 | } else if target.contains("riscv64") { 32 | println!("cargo:rustc-cfg=riscv"); 33 | println!("cargo:rustc-cfg=riscv64"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dependency/riscv/check-blobs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Checks that the blobs are up to date with the committed assembly files 4 | 5 | set -euxo pipefail 6 | 7 | for lib in $(ls bin/*.a); do 8 | filename=$(basename $lib) 9 | riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.before 10 | done 11 | 12 | ./assemble.sh 13 | 14 | for lib in $(ls bin/*.a); do 15 | filename=$(basename $lib) 16 | riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.after 17 | done 18 | 19 | for cksum in $(ls bin/*.after); do 20 | diff -u $cksum ${cksum%.after}.before 21 | done 22 | -------------------------------------------------------------------------------- /dependency/riscv/ci/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | if [ -n "${TARGET:-}" ]; then 6 | rustup target add $TARGET 7 | fi 8 | 9 | if [ -n "${CHECK_BLOBS:-}" ]; then 10 | if [ ! -d gcc/bin ]; then 11 | mkdir -p gcc 12 | curl -L https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.1.0-2018.12.0-x86_64-linux-ubuntu14.tar.gz | tar --strip-components=1 -C gcc -xz 13 | fi 14 | fi 15 | 16 | if [ -n "${RUSTFMT:-}" ]; then 17 | rustup component add rustfmt 18 | fi 19 | -------------------------------------------------------------------------------- /dependency/riscv/ci/script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | export PATH=$PATH:~/.cargo/bin 6 | 7 | if [ -n "${TARGET:-}" ]; then 8 | cargo check --target $TARGET 9 | 10 | if [ $TRAVIS_RUST_VERSION = nightly ]; then 11 | cargo check --target $TARGET --features inline-asm 12 | fi 13 | fi 14 | 15 | if [ -n "${CHECK_BLOBS:-}" ]; then 16 | PATH="$PATH:$PWD/gcc/bin" 17 | ./check-blobs.sh 18 | fi 19 | 20 | if [ -n "${RUSTFMT:-}" ]; then 21 | cargo fmt -- --check 22 | fi 23 | -------------------------------------------------------------------------------- /dependency/riscv/descriptor/generate_hypervisor_csr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rustc generator.rs 3 | rm -f ../src/register/hypervisorx64/mod.rs; 4 | for i in *.txt; do 5 | ./generator <$i > ../src/register/hypervisorx64/`basename -s .txt $i`.rs; 6 | echo "pub mod $(basename -s .txt $i);" >> ../src/register/hypervisorx64/mod.rs; 7 | done 8 | rm -f generator -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hcounteren.txt: -------------------------------------------------------------------------------- 1 | Hcounteren 2 | 3602 3 | cy,0,0,number, 4 | tm,1,1,number, 5 | ir,2,2,number, 6 | hpm3,3,3,number, 7 | hpm4,4,4,number, 8 | hpm5,5,5,number, 9 | hpm6,6,6,number, 10 | hpm7,7,7,number, 11 | hpm8,8,8,number, 12 | hpm9,9,9,number, 13 | hpm10,10,10,number, 14 | hpm11,11,11,number, 15 | hpm12,12,12,number, 16 | hpm13,13,13,number, 17 | hpm14,14,14,number, 18 | hpm15,15,15,number, 19 | hpm16,16,16,number, 20 | hpm17,17,17,number, 21 | hpm18,18,18,number, 22 | hpm19,19,19,number, 23 | hpm20,20,20,number, 24 | hpm21,21,21,number, 25 | hpm22,22,22,number, 26 | hpm23,23,23,number, 27 | hpm24,24,24,number, 28 | hpm25,25,25,number, 29 | hpm26,26,26,number, 30 | hpm27,27,27,number, 31 | hpm28,28,28,number, 32 | hpm29,29,29,number, 33 | hpm30,30,30,number, 34 | hpm31,31,31,number, 35 | end 36 | Hypervisor Guest External Interrupt Pending Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hedeleg.txt: -------------------------------------------------------------------------------- 1 | Hedeleg 2 | 1538 3 | ex0,0,0,number,Instruction address misaligned 4 | ex1,1,1,number,Instruction access fault 5 | ex2,2,2,number,Illegal instruction 6 | ex3,3,3,number,Breakpoint 7 | ex4,4,4,number,Load address misaligned 8 | ex5,5,5,number,Load access fault 9 | ex6,6,6,number,Store/AMO address misaligned 10 | ex7,7,7,number,Store/AMO access fault 11 | ex8,8,8,number,Environment call from U-mode or VU-mode 12 | ex12,12,12,number,Instruction page fault 13 | ex13,13,13,number,Load page fault 14 | ex15,15,15,number,Store/AMO page fault 15 | end 16 | Hypervisor Exception Delegation Register. 17 | -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hgatp.txt: -------------------------------------------------------------------------------- 1 | Hgatp 2 | 1664 3 | mode,63,60,HgatpValues,Bare=0;Sv39x4=8;Sv48x4=9,Guest address translation mode. 4 | vmid,57,44,number,Virtual machine ID. 5 | ppn,43,0,number,Physical Page Number for root page table. 6 | end 7 | Hypervisor Guest Address Translation and Protection Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hgeie.txt: -------------------------------------------------------------------------------- 1 | Hgeie 2 | 1543 3 | end 4 | Hypervisor Guest External Interrupt Enable Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hgeip.txt: -------------------------------------------------------------------------------- 1 | Hgeip 2 | 3602 3 | end 4 | Hypervisor Guest External Interrupt Pending Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hideleg.txt: -------------------------------------------------------------------------------- 1 | Hideleg 2 | 1539 3 | sip,2,2,number,Software Interrupt 4 | tip,6,6,number,Timer Interrupt 5 | eip,10,10,number,External Interrupt 6 | end 7 | Hypervisor Interrupt Delegation Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hie.txt: -------------------------------------------------------------------------------- 1 | Hie 2 | 1540 3 | vssie,2,2,number,Software Interrupt 4 | vstie,6,6,number,Timer Interrupt 5 | vseie,10,10,number,External Interrupt 6 | sgeie,12,12,number,Guest External Interrupt 7 | end 8 | Hypervisor Interrupt Enable Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hip.txt: -------------------------------------------------------------------------------- 1 | Hip 2 | 1604 3 | vssip,2,2,number,Software Interrupt 4 | vstip,6,6,number,Timer Interrupt 5 | vseip,10,10,number,External Interrupt 6 | sgeip,12,12,number,Guest External Interrupt 7 | end 8 | Hypervisor Interrupt Pending Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hstatus.txt: -------------------------------------------------------------------------------- 1 | Hstatus 2 | 1536 3 | vsxl,33,32,VsxlValues,Vsxl32=1;Vsxl64;Vsxl128,Effective XLEN for VM. 4 | vtsr,22,22,number,TSR for VM. 5 | vtw,21,21,number,TW for VM. 6 | vtvm,20,20,number,TVM for VM. 7 | vgein,17,12,number,Virtual Guest External Interrupt Number. 8 | hu,9,9,number,Hypervisor User mode. 9 | spvp,8,8,number,Supervisor Previous Virtual Privilege. 10 | spv,7,7,number,Supervisor Previous Virtualization mode. 11 | gva,6,6,number,Guest Virtual Address. 12 | vsbe,5,5,number,VS access endianness. 13 | end 14 | HStatus Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/htimedelta.txt: -------------------------------------------------------------------------------- 1 | Htimedelta 2 | 1541 3 | end 4 | Hypervisor Time Delta Register. 5 | read_composite_csr!(super::htimedeltah::read(), read()); -------------------------------------------------------------------------------- /dependency/riscv/descriptor/htimedeltah.txt: -------------------------------------------------------------------------------- 1 | Htimedeltah 2 | 1557 3 | end 4 | Hypervisor Time Delta Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/htinst.txt: -------------------------------------------------------------------------------- 1 | Htinst 2 | 1610 3 | end 4 | Hypervisor Trap Instruction Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/htval.txt: -------------------------------------------------------------------------------- 1 | Htval 2 | 1603 3 | end 4 | Hypervisor Trap Value Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/hvip.txt: -------------------------------------------------------------------------------- 1 | Hvip 2 | 1605 3 | vssip,2,2,number,Software Interrupt 4 | vstip,6,6,number,Timer Interrupt 5 | vseip,10,10,number,External Interrupt 6 | end 7 | Hypervisor Virtual Interrupt Pending Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vsatp.txt: -------------------------------------------------------------------------------- 1 | Vsatp 2 | 640 3 | mode,63,60,HgatpValues,Bare=0;Sv39x4=8;Sv48x4=9,Guest address translation mode. 4 | asid,59,44,number,ASID. 5 | ppn,43,0,number,Physical Page Number for root page table. 6 | end 7 | Virtual Supervisor Guest Address Translation and Protection Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vscause.txt: -------------------------------------------------------------------------------- 1 | Vscause 2 | 578 3 | interrupt,63,63,number,Is cause interrupt. 4 | code,62,0,number,Exception code 5 | end 6 | Virtual Supervisor Cause Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vsepc.txt: -------------------------------------------------------------------------------- 1 | Vsepc 2 | 577 3 | end 4 | Virtual Supervisor Exception Program Counter. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vsie.txt: -------------------------------------------------------------------------------- 1 | Vsie 2 | 516 3 | ssie,1,1,number,Software Interrupt 4 | stie,5,5,number,Timer Interrupt 5 | seie,9,9,number,External Interrupt 6 | end 7 | Virtual Supevisor Interrupt Enable Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vsip.txt: -------------------------------------------------------------------------------- 1 | Vsip 2 | 580 3 | ssip,1,1,number,Software Interrupt 4 | stip,5,5,number,Timer Interrupt 5 | seip,9,9,number,External Interrupt 6 | end 7 | Virtual Supevisor Interrupt Pending Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vsscratch.txt: -------------------------------------------------------------------------------- 1 | Vsscratch 2 | 576 3 | end 4 | Virtual Supervisor Scratch Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vsstatus.txt: -------------------------------------------------------------------------------- 1 | Vsstatus 2 | 512 3 | sd,63,60,number, 4 | uxl,33,32,UxlValues,Uxl32=1;Uxl64;Uxl128,Effective User XLEN. 5 | mxr,19,19,number, 6 | sum,18,18,number, 7 | xs,16,15,number, 8 | fs,14,13,number, 9 | spp,8,8,number, 10 | ube,6,6,number, 11 | spie,5,5,number, 12 | sie,1,1,number, 13 | end 14 | Hypervisor Guest External Interrupt Pending Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vstval.txt: -------------------------------------------------------------------------------- 1 | Vstval 2 | 579 3 | end 4 | Virtual Supervisor Trap Value Register. -------------------------------------------------------------------------------- /dependency/riscv/descriptor/vstvec.txt: -------------------------------------------------------------------------------- 1 | Vstvec 2 | 517 3 | base,63,2,number, 4 | mode,1,0,number, 5 | end 6 | Virtual Supervisor Trap Vector Base Address Register. -------------------------------------------------------------------------------- /dependency/riscv/src/interrupt.rs: -------------------------------------------------------------------------------- 1 | //! Interrupts 2 | 3 | // NOTE: Adapted from cortex-m/src/interrupt.rs 4 | pub use bare_metal::{CriticalSection, Mutex, Nr}; 5 | use register::mstatus; 6 | 7 | /// Disables all interrupts 8 | #[inline] 9 | pub unsafe fn disable() { 10 | match () { 11 | #[cfg(riscv)] 12 | () => mstatus::clear_mie(), 13 | #[cfg(not(riscv))] 14 | () => unimplemented!(), 15 | } 16 | } 17 | 18 | /// Enables all the interrupts 19 | /// 20 | /// # Safety 21 | /// 22 | /// - Do not call this function inside an `interrupt::free` critical section 23 | #[inline] 24 | pub unsafe fn enable() { 25 | match () { 26 | #[cfg(riscv)] 27 | () => mstatus::set_mie(), 28 | #[cfg(not(riscv))] 29 | () => unimplemented!(), 30 | } 31 | } 32 | 33 | /// Execute closure `f` in an interrupt-free context. 34 | /// 35 | /// This as also known as a "critical section". 36 | pub fn free(f: F) -> R 37 | where 38 | F: FnOnce(&CriticalSection) -> R, 39 | { 40 | let mstatus = mstatus::read(); 41 | 42 | // disable interrupts 43 | unsafe { 44 | disable(); 45 | } 46 | 47 | let r = f(unsafe { &CriticalSection::new() }); 48 | 49 | // If the interrupts were active before our `disable` call, then re-enable 50 | // them. Otherwise, keep them disabled 51 | if mstatus.mie() { 52 | unsafe { 53 | enable(); 54 | } 55 | } 56 | 57 | r 58 | } 59 | -------------------------------------------------------------------------------- /dependency/riscv/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Low level access to RISC-V processors 2 | //! 3 | //! # Minimum Supported Rust Version (MSRV) 4 | //! 5 | //! This crate is guaranteed to compile on stable Rust 1.42 and up. It *might* 6 | //! compile with older versions but that may change in any new patch release. 7 | //! 8 | //! # Features 9 | //! 10 | //! This crate provides: 11 | //! 12 | //! - Access to core registers like `mstatus` or `mcause`. 13 | //! - Interrupt manipulation mechanisms. 14 | //! - Wrappers around assembly instructions like `WFI`. 15 | 16 | #![no_std] 17 | #![cfg_attr(feature = "inline-asm", feature(llvm_asm))] 18 | extern crate bare_metal; 19 | #[macro_use] 20 | extern crate bitflags; 21 | extern crate bit_field; 22 | 23 | pub mod addr; 24 | pub mod asm; 25 | pub mod interrupt; 26 | pub mod paging; 27 | pub mod register; 28 | -------------------------------------------------------------------------------- /dependency/riscv/src/paging/frame_alloc.rs: -------------------------------------------------------------------------------- 1 | //! Traits for abstracting away frame allocation and deallocation. 2 | 3 | use addr::*; 4 | /// A trait for types that can allocate a frame of memory. 5 | pub trait FrameAllocatorFor { 6 | /// Allocate a frame of the appropriate size and return it if possible. 7 | fn alloc(&mut self) -> Option>; 8 | } 9 | 10 | /// A trait for types that can deallocate a frame of memory. 11 | pub trait FrameDeallocatorFor { 12 | /// Deallocate the given frame of memory. 13 | fn dealloc(&mut self, frame: FrameWith

); 14 | } 15 | 16 | /// Polyfill for default use cases. 17 | 18 | #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] 19 | pub trait FrameAllocator { 20 | fn alloc(&mut self) -> Option; 21 | } 22 | #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] 23 | pub trait FrameDeallocator { 24 | fn dealloc(&mut self, frame: Frame); 25 | } 26 | 27 | #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] 28 | impl FrameAllocatorFor for T { 29 | #[inline] 30 | fn alloc(&mut self) -> Option { 31 | FrameAllocator::alloc(self) 32 | } 33 | } 34 | #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] 35 | impl FrameDeallocatorFor for T { 36 | #[inline] 37 | fn dealloc(&mut self, frame: Frame) { 38 | FrameDeallocator::dealloc(self, frame) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dependency/riscv/src/paging/mod.rs: -------------------------------------------------------------------------------- 1 | mod frame_alloc; 2 | mod mapper; 3 | mod multi_level; 4 | mod multi_level_x4; 5 | mod page_table; 6 | mod page_table_x4; 7 | 8 | pub use self::frame_alloc::*; 9 | pub use self::mapper::*; 10 | pub use self::multi_level::*; 11 | pub use self::multi_level_x4::*; 12 | pub use self::page_table::*; 13 | pub use self::page_table_x4::*; 14 | -------------------------------------------------------------------------------- /dependency/riscv/src/paging/multi_level_x4.rs: -------------------------------------------------------------------------------- 1 | use crate::addr::*; 2 | use crate::asm::{hfence_gvma, hfence_vvma}; 3 | use crate::paging::mapper::MapperFlushable; 4 | use crate::paging::multi_level::Rv32PageTableWith; 5 | use crate::paging::multi_level::{Rv39PageTableWith, Rv48PageTableWith}; 6 | 7 | #[must_use = "Guest Physical Address Table changes must be flushed or ignored."] 8 | pub struct MapperFlushGPA(usize); 9 | 10 | impl MapperFlushable for MapperFlushGPA { 11 | fn new(page: PageWith) -> Self { 12 | MapperFlushGPA(page.start_address().as_usize()) 13 | } 14 | fn flush(self) { 15 | unsafe { 16 | hfence_gvma(self.0, 0); 17 | } 18 | } 19 | fn ignore(self) {} 20 | } 21 | 22 | #[must_use = "Guest Page Table changes must be flushed or ignored."] 23 | pub struct MapperFlushGPT(usize); 24 | 25 | impl MapperFlushable for MapperFlushGPT { 26 | fn new(page: PageWith) -> Self { 27 | MapperFlushGPT(page.start_address().as_usize()) 28 | } 29 | fn flush(self) { 30 | unsafe { 31 | hfence_vvma(self.0, 0); 32 | } 33 | } 34 | fn ignore(self) {} 35 | } 36 | 37 | pub type Rv32PageTableX4<'a> = Rv32PageTableWith<'a, GPAddrSv32X4, MapperFlushGPA>; 38 | pub type Rv39PageTableX4<'a> = Rv39PageTableWith<'a, GPAddrSv39X4, MapperFlushGPA>; 39 | pub type Rv48PageTableX4<'a> = Rv48PageTableWith<'a, GPAddrSv48X4, MapperFlushGPA>; 40 | pub type Rv32PageTableGuest<'a> = Rv32PageTableWith<'a, VirtAddrSv32, MapperFlushGPT>; 41 | pub type Rv39PageTableGuest<'a> = Rv39PageTableWith<'a, VirtAddrSv39, MapperFlushGPT>; 42 | pub type Rv48PageTableGuest<'a> = Rv48PageTableWith<'a, VirtAddrSv48, MapperFlushGPT>; 43 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/hgeie.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Guest External Interrupt Enable Register. 2 | read_csr_as_usize!(1543, __read_hgeie); 3 | write_csr_as_usize!(1543, __write_hgeie); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/hgeip.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Guest External Interrupt Pending Register. 2 | read_csr_as_usize!(3602, __read_hgeip); 3 | write_csr_as_usize!(3602, __write_hgeip); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/hideleg.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Interrupt Delegation Register. 2 | 3 | use bit_field::BitField; 4 | 5 | #[derive(Copy, Clone, Debug)] 6 | pub struct Hideleg { 7 | bits: usize, 8 | } 9 | impl Hideleg { 10 | #[inline] 11 | pub fn bits(&self) -> usize { 12 | return self.bits; 13 | } 14 | #[inline] 15 | pub fn from_bits(x: usize) -> Self { 16 | return Hideleg { bits: x }; 17 | } 18 | #[inline] 19 | pub unsafe fn write(&self) { 20 | _write(self.bits); 21 | } 22 | /// Software Interrupt 23 | #[inline] 24 | pub fn sip(&self) -> bool { 25 | self.bits.get_bit(2) 26 | } 27 | #[inline] 28 | pub fn set_sip(&mut self, val: bool) { 29 | self.bits.set_bit(2, val); 30 | } 31 | /// Timer Interrupt 32 | #[inline] 33 | pub fn tip(&self) -> bool { 34 | self.bits.get_bit(6) 35 | } 36 | #[inline] 37 | pub fn set_tip(&mut self, val: bool) { 38 | self.bits.set_bit(6, val); 39 | } 40 | /// External Interrupt 41 | #[inline] 42 | pub fn eip(&self) -> bool { 43 | self.bits.get_bit(10) 44 | } 45 | #[inline] 46 | pub fn set_eip(&mut self, val: bool) { 47 | self.bits.set_bit(10, val); 48 | } 49 | } 50 | read_csr_as!(Hideleg, 1539, __read_hideleg); 51 | write_csr!(1539, __write_hideleg); 52 | set!(1539, __set_hideleg); 53 | clear!(1539, __clear_hideleg); 54 | // bit ops 55 | set_clear_csr!( 56 | ///Software Interrupt 57 | , set_sip, clear_sip, 1 << 2); 58 | set_clear_csr!( 59 | ///Timer Interrupt 60 | , set_tip, clear_tip, 1 << 6); 61 | set_clear_csr!( 62 | ///External Interrupt 63 | , set_eip, clear_eip, 1 << 10); 64 | 65 | // enums 66 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/htimedelta.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Time Delta Register. 2 | read_composite_csr!(super::htimedeltah::read(), read()); 3 | read_csr_as_usize!(1541, __read_htimedelta); 4 | write_csr_as_usize!(1541, __write_htimedelta); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/htimedeltah.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Time Delta Register. 2 | read_csr_as_usize!(1557, __read_htimedeltah); 3 | write_csr_as_usize!(1557, __write_htimedeltah); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/htinst.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Trap Instruction Register. 2 | read_csr_as_usize!(1610, __read_htinst); 3 | write_csr_as_usize!(1610, __write_htinst); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/htval.rs: -------------------------------------------------------------------------------- 1 | //! Hypervisor Trap Value Register. 2 | read_csr_as_usize!(1603, __read_htval); 3 | write_csr_as_usize!(1603, __write_htval); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod hcounteren; 2 | pub mod hedeleg; 3 | pub mod hgatp; 4 | pub mod hgeie; 5 | pub mod hgeip; 6 | pub mod hideleg; 7 | pub mod hie; 8 | pub mod hip; 9 | pub mod hstatus; 10 | pub mod htimedelta; 11 | pub mod htimedeltah; 12 | pub mod htinst; 13 | pub mod htval; 14 | pub mod hvip; 15 | pub mod vsatp; 16 | pub mod vscause; 17 | pub mod vsepc; 18 | pub mod vsie; 19 | pub mod vsip; 20 | pub mod vsscratch; 21 | pub mod vsstatus; 22 | pub mod vstval; 23 | pub mod vstvec; 24 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vscause.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supervisor Cause Register. 2 | 3 | use bit_field::BitField; 4 | 5 | #[derive(Copy, Clone, Debug)] 6 | pub struct Vscause { 7 | bits: usize, 8 | } 9 | impl Vscause { 10 | #[inline] 11 | pub fn bits(&self) -> usize { 12 | return self.bits; 13 | } 14 | #[inline] 15 | pub fn from_bits(x: usize) -> Self { 16 | return Vscause { bits: x }; 17 | } 18 | #[inline] 19 | pub unsafe fn write(&self) { 20 | _write(self.bits); 21 | } 22 | /// Is cause interrupt. 23 | #[inline] 24 | pub fn interrupt(&self) -> bool { 25 | self.bits.get_bit(63) 26 | } 27 | #[inline] 28 | pub fn set_interrupt(&mut self, val: bool) { 29 | self.bits.set_bit(63, val); 30 | } 31 | /// Exception code 32 | #[inline] 33 | pub fn code(&self) -> usize { 34 | self.bits.get_bits(0..63) 35 | } 36 | #[inline] 37 | pub fn set_code(&mut self, val: usize) { 38 | self.bits.set_bits(0..63, val); 39 | } 40 | } 41 | read_csr_as!(Vscause, 578, __read_vscause); 42 | write_csr!(578, __write_vscause); 43 | set!(578, __set_vscause); 44 | clear!(578, __clear_vscause); 45 | // bit ops 46 | set_clear_csr!( 47 | ///Is cause interrupt. 48 | , set_interrupt, clear_interrupt, 1 << 63); 49 | 50 | // enums 51 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vsepc.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supervisor Exception Program Counter. 2 | read_csr_as_usize!(577, __read_vsepc); 3 | write_csr_as_usize!(577, __write_vsepc); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vsie.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supevisor Interrupt Enable Register. 2 | 3 | use bit_field::BitField; 4 | 5 | #[derive(Copy, Clone, Debug)] 6 | pub struct Vsie { 7 | bits: usize, 8 | } 9 | impl Vsie { 10 | #[inline] 11 | pub fn bits(&self) -> usize { 12 | return self.bits; 13 | } 14 | #[inline] 15 | pub fn from_bits(x: usize) -> Self { 16 | return Vsie { bits: x }; 17 | } 18 | #[inline] 19 | pub unsafe fn write(&self) { 20 | _write(self.bits); 21 | } 22 | /// Software Interrupt 23 | #[inline] 24 | pub fn ssie(&self) -> bool { 25 | self.bits.get_bit(1) 26 | } 27 | #[inline] 28 | pub fn set_ssie(&mut self, val: bool) { 29 | self.bits.set_bit(1, val); 30 | } 31 | /// Timer Interrupt 32 | #[inline] 33 | pub fn stie(&self) -> bool { 34 | self.bits.get_bit(5) 35 | } 36 | #[inline] 37 | pub fn set_stie(&mut self, val: bool) { 38 | self.bits.set_bit(5, val); 39 | } 40 | /// External Interrupt 41 | #[inline] 42 | pub fn seie(&self) -> bool { 43 | self.bits.get_bit(9) 44 | } 45 | #[inline] 46 | pub fn set_seie(&mut self, val: bool) { 47 | self.bits.set_bit(9, val); 48 | } 49 | } 50 | read_csr_as!(Vsie, 516, __read_vsie); 51 | write_csr!(516, __write_vsie); 52 | set!(516, __set_vsie); 53 | clear!(516, __clear_vsie); 54 | // bit ops 55 | set_clear_csr!( 56 | ///Software Interrupt 57 | , set_ssie, clear_ssie, 1 << 1); 58 | set_clear_csr!( 59 | ///Timer Interrupt 60 | , set_stie, clear_stie, 1 << 5); 61 | set_clear_csr!( 62 | ///External Interrupt 63 | , set_seie, clear_seie, 1 << 9); 64 | 65 | // enums 66 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vsip.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supevisor Interrupt Pending Register. 2 | 3 | use bit_field::BitField; 4 | 5 | #[derive(Copy, Clone, Debug)] 6 | pub struct Vsip { 7 | bits: usize, 8 | } 9 | impl Vsip { 10 | #[inline] 11 | pub fn bits(&self) -> usize { 12 | return self.bits; 13 | } 14 | #[inline] 15 | pub fn from_bits(x: usize) -> Self { 16 | return Vsip { bits: x }; 17 | } 18 | #[inline] 19 | pub unsafe fn write(&self) { 20 | _write(self.bits); 21 | } 22 | /// Software Interrupt 23 | #[inline] 24 | pub fn ssip(&self) -> bool { 25 | self.bits.get_bit(1) 26 | } 27 | #[inline] 28 | pub fn set_ssip(&mut self, val: bool) { 29 | self.bits.set_bit(1, val); 30 | } 31 | /// Timer Interrupt 32 | #[inline] 33 | pub fn stip(&self) -> bool { 34 | self.bits.get_bit(5) 35 | } 36 | #[inline] 37 | pub fn set_stip(&mut self, val: bool) { 38 | self.bits.set_bit(5, val); 39 | } 40 | /// External Interrupt 41 | #[inline] 42 | pub fn seip(&self) -> bool { 43 | self.bits.get_bit(9) 44 | } 45 | #[inline] 46 | pub fn set_seip(&mut self, val: bool) { 47 | self.bits.set_bit(9, val); 48 | } 49 | } 50 | read_csr_as!(Vsip, 580, __read_vsip); 51 | write_csr!(580, __write_vsip); 52 | set!(580, __set_vsip); 53 | clear!(580, __clear_vsip); 54 | // bit ops 55 | set_clear_csr!( 56 | ///Software Interrupt 57 | , set_ssip, clear_ssip, 1 << 1); 58 | set_clear_csr!( 59 | ///Timer Interrupt 60 | , set_stip, clear_stip, 1 << 5); 61 | set_clear_csr!( 62 | ///External Interrupt 63 | , set_seip, clear_seip, 1 << 9); 64 | 65 | // enums 66 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vsscratch.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supervisor Scratch Register. 2 | read_csr_as_usize!(576, __read_vsscratch); 3 | write_csr_as_usize!(576, __write_vsscratch); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vstval.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supervisor Trap Value Register. 2 | read_csr_as_usize!(579, __read_vstval); 3 | write_csr_as_usize!(579, __write_vstval); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/hypervisorx64/vstvec.rs: -------------------------------------------------------------------------------- 1 | //! Virtual Supervisor Trap Vector Base Address Register. 2 | 3 | use bit_field::BitField; 4 | 5 | #[derive(Copy, Clone, Debug)] 6 | pub struct Vstvec { 7 | bits: usize, 8 | } 9 | impl Vstvec { 10 | #[inline] 11 | pub fn bits(&self) -> usize { 12 | return self.bits; 13 | } 14 | #[inline] 15 | pub fn from_bits(x: usize) -> Self { 16 | return Vstvec { bits: x }; 17 | } 18 | #[inline] 19 | pub unsafe fn write(&self) { 20 | _write(self.bits); 21 | } 22 | /// 23 | #[inline] 24 | pub fn base(&self) -> usize { 25 | self.bits.get_bits(2..64) 26 | } 27 | #[inline] 28 | pub fn set_base(&mut self, val: usize) { 29 | self.bits.set_bits(2..64, val); 30 | } 31 | /// 32 | #[inline] 33 | pub fn mode(&self) -> usize { 34 | self.bits.get_bits(0..2) 35 | } 36 | #[inline] 37 | pub fn set_mode(&mut self, val: usize) { 38 | self.bits.set_bits(0..2, val); 39 | } 40 | } 41 | read_csr_as!(Vstvec, 517, __read_vstvec); 42 | write_csr!(517, __write_vstvec); 43 | set!(517, __set_vstvec); 44 | clear!(517, __clear_vstvec); 45 | // bit ops 46 | 47 | // enums 48 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/marchid.rs: -------------------------------------------------------------------------------- 1 | //! marchid register 2 | 3 | use core::num::NonZeroUsize; 4 | 5 | /// marchid register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Marchid { 8 | bits: NonZeroUsize, 9 | } 10 | 11 | impl Marchid { 12 | /// Returns the contents of the register as raw bits 13 | pub fn bits(&self) -> usize { 14 | self.bits.get() 15 | } 16 | } 17 | 18 | read_csr!(0xF11, __read_marchid); 19 | 20 | /// Reads the CSR 21 | #[inline] 22 | pub fn read() -> Option { 23 | let r = unsafe { _read() }; 24 | // When marchid is hardwired to zero it means that the marchid 25 | // csr isn't implemented. 26 | NonZeroUsize::new(r).map(|bits| Marchid { bits }) 27 | } 28 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mcycle.rs: -------------------------------------------------------------------------------- 1 | //! mcycle register 2 | 3 | read_csr_as_usize!(0xB00, __read_mcycle); 4 | read_composite_csr!(super::mcycleh::read(), read()); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mcycleh.rs: -------------------------------------------------------------------------------- 1 | //! mcycleh register 2 | 3 | read_csr_as_usize_rv32!(0xB80, __read_mcycleh); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mepc.rs: -------------------------------------------------------------------------------- 1 | //! mepc register 2 | 3 | read_csr_as_usize!(0x341, __read_mepc); 4 | write_csr_as_usize!(0x341, __write_mepc); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mhartid.rs: -------------------------------------------------------------------------------- 1 | //! mhartid register 2 | 3 | read_csr_as_usize!(0xf14, __read_mhartid); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mimpid.rs: -------------------------------------------------------------------------------- 1 | //! mimpid register 2 | 3 | use core::num::NonZeroUsize; 4 | 5 | /// mimpid register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Mimpid { 8 | bits: NonZeroUsize, 9 | } 10 | 11 | impl Mimpid { 12 | /// Returns the contents of the register as raw bits 13 | pub fn bits(&self) -> usize { 14 | self.bits.get() 15 | } 16 | } 17 | 18 | read_csr!(0xF11, __read_mimpid); 19 | 20 | /// Reads the CSR 21 | #[inline] 22 | pub fn read() -> Option { 23 | let r = unsafe { _read() }; 24 | // When mimpid is hardwired to zero it means that the mimpid 25 | // csr isn't implemented. 26 | NonZeroUsize::new(r).map(|bits| Mimpid { bits }) 27 | } 28 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/minstret.rs: -------------------------------------------------------------------------------- 1 | //! minstret register 2 | 3 | read_csr_as_usize!(0xB02, __read_minstret); 4 | read_composite_csr!(super::minstreth::read(), read()); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/minstreth.rs: -------------------------------------------------------------------------------- 1 | //! minstreth register 2 | 3 | read_csr_as_usize_rv32!(0xB82, __read_minstreth); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/misa.rs: -------------------------------------------------------------------------------- 1 | //! misa register 2 | 3 | use core::num::NonZeroUsize; 4 | 5 | /// misa register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Misa { 8 | bits: NonZeroUsize, 9 | } 10 | 11 | /// Machine XLEN 12 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 13 | pub enum MXL { 14 | XLEN32, 15 | XLEN64, 16 | XLEN128, 17 | } 18 | 19 | impl Misa { 20 | /// Returns the contents of the register as raw bits 21 | pub fn bits(&self) -> usize { 22 | self.bits.get() 23 | } 24 | 25 | /// Returns the machine xlen. 26 | pub fn mxl(&self) -> MXL { 27 | let value = match () { 28 | #[cfg(target_pointer_width = "32")] 29 | () => (self.bits() >> 30) as u8, 30 | #[cfg(target_pointer_width = "64")] 31 | () => (self.bits() >> 62) as u8, 32 | }; 33 | match value { 34 | 1 => MXL::XLEN32, 35 | 2 => MXL::XLEN64, 36 | 3 => MXL::XLEN128, 37 | _ => unreachable!(), 38 | } 39 | } 40 | 41 | /// Returns true when the atomic extension is implemented. 42 | pub fn has_extension(&self, extension: char) -> bool { 43 | let bit = extension as u8 - 65; 44 | if bit > 25 { 45 | return false; 46 | } 47 | self.bits() & (1 << bit) == (1 << bit) 48 | } 49 | } 50 | 51 | read_csr!(0x301, __read_misa); 52 | 53 | /// Reads the CSR 54 | #[inline] 55 | pub fn read() -> Option { 56 | let r = unsafe { _read() }; 57 | // When misa is hardwired to zero it means that the misa csr 58 | // isn't implemented. 59 | NonZeroUsize::new(r).map(|bits| Misa { bits }) 60 | } 61 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mscratch.rs: -------------------------------------------------------------------------------- 1 | //! mscratch register 2 | 3 | read_csr_as_usize!(0x340, __read_mscratch); 4 | write_csr_as_usize!(0x340, __write_mscratch); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mtval.rs: -------------------------------------------------------------------------------- 1 | //! mtval register 2 | 3 | read_csr_as_usize!(0x343, __read_mtval); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mtvec.rs: -------------------------------------------------------------------------------- 1 | //! mtvec register 2 | 3 | /// mtvec register 4 | #[derive(Clone, Copy, Debug)] 5 | pub struct Mtvec { 6 | bits: usize, 7 | } 8 | 9 | /// Trap mode 10 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 11 | pub enum TrapMode { 12 | Direct = 0, 13 | Vectored = 1, 14 | } 15 | 16 | impl Mtvec { 17 | /// Returns the contents of the register as raw bits 18 | pub fn bits(&self) -> usize { 19 | self.bits 20 | } 21 | 22 | /// Returns the trap-vector base-address 23 | pub fn address(&self) -> usize { 24 | self.bits - (self.bits & 0b11) 25 | } 26 | 27 | /// Returns the trap-vector mode 28 | pub fn trap_mode(&self) -> Option { 29 | let mode = self.bits & 0b11; 30 | match mode { 31 | 0 => Some(TrapMode::Direct), 32 | 1 => Some(TrapMode::Vectored), 33 | _ => None, 34 | } 35 | } 36 | } 37 | 38 | read_csr_as!(Mtvec, 0x305, __read_mtvec); 39 | 40 | write_csr!(0x305, __write_mtvec); 41 | 42 | /// Writes the CSR 43 | #[inline] 44 | pub unsafe fn write(addr: usize, mode: TrapMode) { 45 | let bits = addr + mode as usize; 46 | _write(bits); 47 | } 48 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/mvendorid.rs: -------------------------------------------------------------------------------- 1 | //! mvendorid register 2 | 3 | use core::num::NonZeroUsize; 4 | 5 | /// mvendorid register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Mvendorid { 8 | bits: NonZeroUsize, 9 | } 10 | 11 | impl Mvendorid { 12 | /// Returns the contents of the register as raw bits 13 | pub fn bits(&self) -> usize { 14 | self.bits.get() 15 | } 16 | 17 | /// Returns the JEDEC manufacturer ID 18 | pub fn jedec_manufacturer(&self) -> usize { 19 | self.bits() >> 7 20 | } 21 | } 22 | 23 | read_csr!(0xF11, __read_mvendorid); 24 | 25 | /// Reads the CSR 26 | #[inline] 27 | pub fn read() -> Option { 28 | let r = unsafe { _read() }; 29 | // When mvendorid is hardwired to zero it means that the mvendorid 30 | // csr isn't implemented. 31 | NonZeroUsize::new(r).map(|bits| Mvendorid { bits }) 32 | } 33 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/pmpaddrx.rs: -------------------------------------------------------------------------------- 1 | macro_rules! reg { 2 | ( 3 | $addr:expr, $csr:ident, $readf:ident, $writef:ident 4 | ) => { 5 | /// Physical memory protection address register 6 | pub mod $csr { 7 | read_csr_as_usize!($addr, $readf); 8 | write_csr_as_usize!($addr, $writef); 9 | } 10 | }; 11 | } 12 | 13 | reg!(0x3B0, pmpaddr0, __read_pmpaddr0, __write_pmpaddr0); 14 | reg!(0x3B1, pmpaddr1, __read_pmpaddr1, __write_pmpaddr1); 15 | reg!(0x3B2, pmpaddr2, __read_pmpaddr2, __write_pmpaddr2); 16 | reg!(0x3B3, pmpaddr3, __read_pmpaddr3, __write_pmpaddr3); 17 | reg!(0x3B4, pmpaddr4, __read_pmpaddr4, __write_pmpaddr4); 18 | reg!(0x3B5, pmpaddr5, __read_pmpaddr5, __write_pmpaddr5); 19 | reg!(0x3B6, pmpaddr6, __read_pmpaddr6, __write_pmpaddr6); 20 | reg!(0x3B7, pmpaddr7, __read_pmpaddr7, __write_pmpaddr7); 21 | reg!(0x3B8, pmpaddr8, __read_pmpaddr8, __write_pmpaddr8); 22 | reg!(0x3B9, pmpaddr9, __read_pmpaddr9, __write_pmpaddr9); 23 | reg!(0x3BA, pmpaddr10, __read_pmpaddr10, __write_pmpaddr10); 24 | reg!(0x3BB, pmpaddr11, __read_pmpaddr11, __write_pmpaddr11); 25 | reg!(0x3BC, pmpaddr12, __read_pmpaddr12, __write_pmpaddr12); 26 | reg!(0x3BD, pmpaddr13, __read_pmpaddr13, __write_pmpaddr13); 27 | reg!(0x3BE, pmpaddr14, __read_pmpaddr14, __write_pmpaddr14); 28 | reg!(0x3BF, pmpaddr15, __read_pmpaddr15, __write_pmpaddr15); 29 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/pmpcfgx.rs: -------------------------------------------------------------------------------- 1 | /// Physical memory protection configuration 2 | pub mod pmpcfg0 { 3 | read_csr_as_usize!(0x3A0, __read_pmpcfg0); 4 | write_csr_as_usize!(0x3A0, __write_pmpcfg0); 5 | } 6 | 7 | /// Physical memory protection configuration, RV32 only 8 | pub mod pmpcfg1 { 9 | read_csr_as_usize_rv32!(0x3A1, __read_pmpcfg1); 10 | write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1); 11 | } 12 | 13 | /// Physical memory protection configuration 14 | pub mod pmpcfg2 { 15 | read_csr_as_usize!(0x3A2, __read_pmpcfg2); 16 | write_csr_as_usize!(0x3A2, __write_pmpcfg2); 17 | } 18 | 19 | /// Physical memory protection configuration, RV32 only 20 | pub mod pmpcfg3 { 21 | read_csr_as_usize_rv32!(0x3A3, __read_pmpcfg3); 22 | write_csr_as_usize_rv32!(0x3A3, __write_pmpcfg3); 23 | } 24 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/sepc.rs: -------------------------------------------------------------------------------- 1 | //! sepc register 2 | 3 | read_csr_as_usize!(0x141, __read_sepc); 4 | write_csr_as_usize!(0x141, __write_sepc); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/sip.rs: -------------------------------------------------------------------------------- 1 | //! sip register 2 | 3 | use bit_field::BitField; 4 | 5 | /// sip register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Sip { 8 | bits: usize, 9 | } 10 | 11 | impl Sip { 12 | /// Returns the contents of the register as raw bits 13 | #[inline] 14 | pub fn bits(&self) -> usize { 15 | self.bits 16 | } 17 | 18 | /// User Software Interrupt Pending 19 | #[inline] 20 | pub fn usoft(&self) -> bool { 21 | self.bits.get_bit(0) 22 | } 23 | 24 | /// Supervisor Software Interrupt Pending 25 | #[inline] 26 | pub fn ssoft(&self) -> bool { 27 | self.bits.get_bit(1) 28 | } 29 | 30 | /// User Timer Interrupt Pending 31 | #[inline] 32 | pub fn utimer(&self) -> bool { 33 | self.bits.get_bit(4) 34 | } 35 | 36 | /// Supervisor Timer Interrupt Pending 37 | #[inline] 38 | pub fn stimer(&self) -> bool { 39 | self.bits.get_bit(5) 40 | } 41 | 42 | /// User External Interrupt Pending 43 | #[inline] 44 | pub fn uext(&self) -> bool { 45 | self.bits.get_bit(8) 46 | } 47 | 48 | /// Supervisor External Interrupt Pending 49 | #[inline] 50 | pub fn sext(&self) -> bool { 51 | self.bits.get_bit(9) 52 | } 53 | } 54 | 55 | read_csr_as!(Sip, 0x144, __read_sip); 56 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/sscratch.rs: -------------------------------------------------------------------------------- 1 | //! sscratch register 2 | 3 | read_csr_as_usize!(0x140, __read_sscratch); 4 | write_csr_as_usize!(0x140, __write_sscratch); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/stval.rs: -------------------------------------------------------------------------------- 1 | //! stval register 2 | 3 | read_csr_as_usize!(0x143, __read_stval); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/stvec.rs: -------------------------------------------------------------------------------- 1 | //! stvec register 2 | 3 | pub use crate::register::mtvec::TrapMode; 4 | 5 | /// stvec register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Stvec { 8 | bits: usize, 9 | } 10 | 11 | impl Stvec { 12 | /// Returns the contents of the register as raw bits 13 | pub fn bits(&self) -> usize { 14 | self.bits 15 | } 16 | 17 | /// Returns the trap-vector base-address 18 | pub fn address(&self) -> usize { 19 | self.bits - (self.bits & 0b11) 20 | } 21 | 22 | /// Returns the trap-vector mode 23 | pub fn trap_mode(&self) -> Option { 24 | let mode = self.bits & 0b11; 25 | match mode { 26 | 0 => Some(TrapMode::Direct), 27 | 1 => Some(TrapMode::Vectored), 28 | _ => None, 29 | } 30 | } 31 | } 32 | 33 | read_csr_as!(Stvec, 0x105, __read_stvec); 34 | write_csr!(0x105, __write_stvec); 35 | 36 | /// Writes the CSR 37 | #[inline] 38 | pub unsafe fn write(addr: usize, mode: TrapMode) { 39 | _write(addr + mode as usize); 40 | } 41 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/time.rs: -------------------------------------------------------------------------------- 1 | //! time register 2 | 3 | read_csr_as_usize!(0xC01, __read_time); 4 | read_composite_csr!(super::timeh::read(), read()); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/timeh.rs: -------------------------------------------------------------------------------- 1 | //! timeh register 2 | 3 | read_csr_as_usize_rv32!(0xC81, __read_timeh); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/ucause.rs: -------------------------------------------------------------------------------- 1 | //! ucause register 2 | 3 | /// ucause register 4 | #[derive(Clone, Copy, Debug)] 5 | pub struct Ucause { 6 | bits: usize, 7 | } 8 | 9 | impl Ucause { 10 | /// Returns the contents of the register as raw bits 11 | #[inline] 12 | pub fn bits(&self) -> usize { 13 | self.bits 14 | } 15 | } 16 | 17 | read_csr_as!(Ucause, 0x042, __read_ucause); 18 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/uepc.rs: -------------------------------------------------------------------------------- 1 | //! uepc register 2 | 3 | read_csr_as_usize!(0x041, __read_uepc); 4 | write_csr_as_usize!(0x041, __write_uepc); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/uie.rs: -------------------------------------------------------------------------------- 1 | //! uie register 2 | 3 | use bit_field::BitField; 4 | 5 | /// uie register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Uie { 8 | bits: usize, 9 | } 10 | 11 | impl Uie { 12 | /// Returns the contents of the register as raw bits 13 | #[inline] 14 | pub fn bits(&self) -> usize { 15 | self.bits 16 | } 17 | 18 | /// User Software Interrupt Enable 19 | #[inline] 20 | pub fn usoft(&self) -> bool { 21 | self.bits.get_bit(0) 22 | } 23 | 24 | /// User Timer Interrupt Enable 25 | #[inline] 26 | pub fn utimer(&self) -> bool { 27 | self.bits.get_bit(4) 28 | } 29 | 30 | /// User External Interrupt Enable 31 | #[inline] 32 | pub fn uext(&self) -> bool { 33 | self.bits.get_bit(8) 34 | } 35 | } 36 | 37 | read_csr_as!(Uie, 0x004, __read_uie); 38 | set!(0x004, __set_uie); 39 | clear!(0x004, __clear_uie); 40 | 41 | set_clear_csr!( 42 | /// User Software Interrupt Enable 43 | , set_usoft, clear_usoft, 1 << 0); 44 | set_clear_csr!( 45 | /// User Timer Interrupt Enable 46 | , set_utimer, clear_utimer, 1 << 4); 47 | set_clear_csr!( 48 | /// User External Interrupt Enable 49 | , set_uext, clear_uext, 1 << 8); 50 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/uip.rs: -------------------------------------------------------------------------------- 1 | //! uip register 2 | 3 | use bit_field::BitField; 4 | 5 | /// uip register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Uip { 8 | bits: usize, 9 | } 10 | 11 | impl Uip { 12 | /// Returns the contents of the register as raw bits 13 | #[inline] 14 | pub fn bits(&self) -> usize { 15 | self.bits 16 | } 17 | 18 | /// User Software Interrupt Pending 19 | #[inline] 20 | pub fn usoft(&self) -> bool { 21 | self.bits.get_bit(0) 22 | } 23 | 24 | /// User Timer Interrupt Pending 25 | #[inline] 26 | pub fn utimer(&self) -> bool { 27 | self.bits.get_bit(4) 28 | } 29 | 30 | /// User External Interrupt Pending 31 | #[inline] 32 | pub fn uext(&self) -> bool { 33 | self.bits.get_bit(8) 34 | } 35 | } 36 | 37 | read_csr_as!(Uip, 0x044, __read_uip); 38 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/uscratch.rs: -------------------------------------------------------------------------------- 1 | //! uscratch register 2 | 3 | read_csr_as_usize!(0x040, __read_uscratch); 4 | write_csr_as_usize!(0x040, __write_uscratch); 5 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/ustatus.rs: -------------------------------------------------------------------------------- 1 | //! ustatus register 2 | // TODO: Virtualization, Memory Privilege and Extension Context Fields 3 | 4 | use bit_field::BitField; 5 | 6 | /// ustatus register 7 | #[derive(Clone, Copy, Debug)] 8 | pub struct Ustatus { 9 | bits: usize, 10 | } 11 | 12 | impl Ustatus { 13 | /// User Interrupt Enable 14 | #[inline] 15 | pub fn uie(&self) -> bool { 16 | self.bits.get_bit(0) 17 | } 18 | 19 | /// User Previous Interrupt Enable 20 | #[inline] 21 | pub fn upie(&self) -> bool { 22 | self.bits.get_bit(4) 23 | } 24 | } 25 | 26 | read_csr_as!(Ustatus, 0x000, __read_ustatus); 27 | write_csr!(0x000, __write_ustatus); 28 | set!(0x000, __set_ustatus); 29 | clear!(0x000, __clear_ustatus); 30 | 31 | set_clear_csr!( 32 | /// User Interrupt Enable 33 | , set_uie, clear_uie, 1 << 0); 34 | 35 | set_csr!( 36 | /// User Previous Interrupt Enable 37 | , set_upie, 1 << 4); 38 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/utval.rs: -------------------------------------------------------------------------------- 1 | //! utval register 2 | 3 | read_csr_as_usize!(0x043, __read_utval); 4 | -------------------------------------------------------------------------------- /dependency/riscv/src/register/utvec.rs: -------------------------------------------------------------------------------- 1 | //! stvec register 2 | 3 | pub use crate::register::mtvec::TrapMode; 4 | 5 | /// stvec register 6 | #[derive(Clone, Copy, Debug)] 7 | pub struct Utvec { 8 | bits: usize, 9 | } 10 | 11 | impl Utvec { 12 | /// Returns the contents of the register as raw bits 13 | pub fn bits(&self) -> usize { 14 | self.bits 15 | } 16 | 17 | /// Returns the trap-vector base-address 18 | pub fn address(&self) -> usize { 19 | self.bits - (self.bits & 0b11) 20 | } 21 | 22 | /// Returns the trap-vector mode 23 | pub fn trap_mode(&self) -> Option { 24 | let mode = self.bits & 0b11; 25 | match mode { 26 | 0 => Some(TrapMode::Direct), 27 | 1 => Some(TrapMode::Vectored), 28 | _ => None, 29 | } 30 | } 31 | } 32 | 33 | read_csr_as!(Utvec, 0x005, __read_utvec); 34 | write_csr!(0x005, __write_utvec); 35 | 36 | /// Writes the CSR 37 | #[inline] 38 | pub unsafe fn write(addr: usize, mode: TrapMode) { 39 | _write(addr + mode as usize); 40 | } 41 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/.gitignore: -------------------------------------------------------------------------------- 1 | target/ -------------------------------------------------------------------------------- /dependency/virtio-drivers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/dependency/virtio-drivers/.keep -------------------------------------------------------------------------------- /dependency/virtio-drivers/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "bitflags" 5 | version = "1.2.1" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 8 | 9 | [[package]] 10 | name = "cfg-if" 11 | version = "1.0.0" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 14 | 15 | [[package]] 16 | name = "log" 17 | version = "0.4.14" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 20 | dependencies = [ 21 | "cfg-if", 22 | ] 23 | 24 | [[package]] 25 | name = "virtio-drivers" 26 | version = "0.1.0" 27 | dependencies = [ 28 | "bitflags", 29 | "log", 30 | "volatile", 31 | ] 32 | 33 | [[package]] 34 | name = "volatile" 35 | version = "0.2.7" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "f6b06ad3ed06fef1713569d547cdbdb439eafed76341820fb0e0344f29a41945" 38 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "virtio-drivers" 3 | version = "0.1.0" 4 | authors = ["Jiajie Chen ", "Runji Wang "] 5 | edition = "2018" 6 | description = "VirtIO guest drivers." 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | volatile = "0.2" 12 | log = "0.4" 13 | bitflags = "1.2" 14 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2020 rCore Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /dependency/virtio-drivers/README.md: -------------------------------------------------------------------------------- 1 | # VirtIO-drivers-rs 2 | 3 | [![CI](https://github.com/rcore-os/virtio-drivers/workflows/CI/badge.svg?branch=master)](https://github.com/rcore-os/virtio-drivers/actions) 4 | 5 | VirtIO guest drivers in Rust. For **no_std + no_alloc** environment. 6 | 7 | ## Components 8 | 9 | | Device | Status | 10 | | -------- | ------------------- | 11 | | Queue | ✅ | 12 | | Block | ✅ | 13 | | Net | ✅ | 14 | | GPU | ✅ | 15 | | Input | ✅ | 16 | | Console | ✅ | 17 | | ... | ❌ Not implemented | 18 | 19 | ## Examples & Tests 20 | 21 | * x86_64 (TODO) 22 | 23 | * [RISCV](./examples/riscv) 24 | 25 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "riscv64imac-unknown-none-elf" 3 | 4 | [target.riscv32imac-unknown-none-elf] 5 | rustflags = [ 6 | "-C", "link-arg=-Tlinker32.ld", 7 | ] 8 | 9 | [target.riscv64imac-unknown-none-elf] 10 | rustflags = [ 11 | "-C", "link-arg=-Tlinker64.ld", 12 | ] 13 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "riscv" 3 | version = "0.1.0" 4 | authors = ["Runji Wang "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | log = "0.4" 11 | riscv = "0.6" 12 | opensbi-rt = { path = "../../../opensbi-rt.git", rev = "1308cc5" } 13 | device_tree = { path = "../../../device_tree-rs", rev = "2fa8411" } 14 | virtio-drivers = { path = "../.." } 15 | lazy_static = { version = "1.4", features = ["spin_no_std"] } 16 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/Makefile: -------------------------------------------------------------------------------- 1 | arch ?= riscv64 2 | target := $(arch)imac-unknown-none-elf 3 | mode := release 4 | kernel := target/$(target)/$(mode)/riscv 5 | img := target/$(target)/$(mode)/img 6 | 7 | sysroot := $(shell rustc --print sysroot) 8 | objdump := $(shell find $(sysroot) -name llvm-objdump) --arch-name=$(arch) 9 | objcopy := $(shell find $(sysroot) -name llvm-objcopy) 10 | 11 | BUILD_ARGS += --target $(target) 12 | ifeq ($(mode), release) 13 | BUILD_ARGS += --release 14 | endif 15 | 16 | .PHONY: kernel build clean qemu run env 17 | 18 | build: $(bin) 19 | 20 | env: 21 | rustup component add llvm-tools-preview rustfmt 22 | rustup target add $(target) 23 | 24 | kernel: 25 | cargo build $(BUILD_ARGS) 26 | 27 | asm: 28 | $(objdump) -d $(kernel) | less 29 | 30 | sym: 31 | $(objdump) -t $(kernel) | less 32 | 33 | header: 34 | $(objdump) -x $(kernel) | less 35 | 36 | clean: 37 | cargo clean 38 | 39 | qemu: kernel $(img) 40 | qemu-system-$(arch) \ 41 | -machine virt \ 42 | -serial mon:stdio \ 43 | -bios default \ 44 | -kernel $(kernel) \ 45 | -drive file=$(img),if=none,format=raw,id=x0 \ 46 | -device virtio-blk-device,drive=x0 \ 47 | -device virtio-gpu-device \ 48 | -device virtio-mouse-device \ 49 | # -netdev type=tap,id=net0,script=no,downscript=no \ 50 | # -device virtio-net-device,netdev=net0 51 | 52 | $(img): 53 | dd if=/dev/zero of=$@ bs=512 count=32 54 | 55 | run: build qemu 56 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/linker32.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(riscv) 2 | ENTRY(_start) 3 | 4 | BASE_ADDRESS = 0x80400000; 5 | 6 | SECTIONS 7 | { 8 | /* Load the kernel at this address: "." means the current address */ 9 | . = BASE_ADDRESS; 10 | start = .; 11 | 12 | .text : { 13 | stext = .; 14 | *(.text.entry) 15 | *(.text .text.*) 16 | . = ALIGN(4K); 17 | etext = .; 18 | } 19 | 20 | .rodata : { 21 | srodata = .; 22 | *(.rodata .rodata.*) 23 | . = ALIGN(4K); 24 | erodata = .; 25 | } 26 | 27 | .data : { 28 | sdata = .; 29 | *(.data .data.*) 30 | *(.sdata .sdata.*) 31 | edata = .; 32 | } 33 | 34 | .stack : { 35 | *(.bss.stack) 36 | } 37 | 38 | .bss : { 39 | sbss = .; 40 | *(.bss .bss.*) 41 | *(.sbss .sbss.*) 42 | ebss = .; 43 | } 44 | 45 | . = ALIGN(4K); 46 | PROVIDE(end = .); 47 | } 48 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/linker64.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(riscv) 2 | ENTRY(_start) 3 | 4 | BASE_ADDRESS = 0x80200000; 5 | 6 | SECTIONS 7 | { 8 | /* Load the kernel at this address: "." means the current address */ 9 | . = BASE_ADDRESS; 10 | start = .; 11 | 12 | .text : { 13 | stext = .; 14 | *(.text.entry) 15 | *(.text .text.*) 16 | . = ALIGN(4K); 17 | etext = .; 18 | } 19 | 20 | .rodata : { 21 | srodata = .; 22 | *(.rodata .rodata.*) 23 | . = ALIGN(4K); 24 | erodata = .; 25 | } 26 | 27 | .data : { 28 | sdata = .; 29 | *(.data .data.*) 30 | *(.sdata .sdata.*) 31 | edata = .; 32 | } 33 | 34 | .stack : { 35 | *(.bss.stack) 36 | } 37 | 38 | .bss : { 39 | sbss = .; 40 | *(.bss .bss.*) 41 | *(.sbss .sbss.*) 42 | ebss = .; 43 | } 44 | 45 | . = ALIGN(4K); 46 | PROVIDE(end = .); 47 | } 48 | -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/rust-toolchain: -------------------------------------------------------------------------------- 1 | nightly-2021-03-01 -------------------------------------------------------------------------------- /dependency/virtio-drivers/examples/riscv/src/virtio_impl.rs: -------------------------------------------------------------------------------- 1 | use core::sync::atomic::*; 2 | use lazy_static::lazy_static; 3 | 4 | extern "C" { 5 | fn end(); 6 | } 7 | 8 | lazy_static! { 9 | static ref DMA_PADDR: AtomicUsize = AtomicUsize::new(end as usize); 10 | } 11 | 12 | #[no_mangle] 13 | extern "C" fn virtio_dma_alloc(pages: usize) -> PhysAddr { 14 | let paddr = DMA_PADDR.fetch_add(0x1000 * pages, Ordering::SeqCst); 15 | trace!("alloc DMA: paddr={:#x}, pages={}", paddr, pages); 16 | paddr 17 | } 18 | 19 | #[no_mangle] 20 | extern "C" fn virtio_dma_dealloc(paddr: PhysAddr, pages: usize) -> i32 { 21 | trace!("dealloc DMA: paddr={:#x}, pages={}", paddr, pages); 22 | 0 23 | } 24 | 25 | #[no_mangle] 26 | extern "C" fn virtio_phys_to_virt(paddr: PhysAddr) -> VirtAddr { 27 | paddr 28 | } 29 | 30 | #[no_mangle] 31 | extern "C" fn virtio_virt_to_phys(vaddr: VirtAddr) -> PhysAddr { 32 | vaddr 33 | } 34 | 35 | type VirtAddr = usize; 36 | type PhysAddr = usize; 37 | -------------------------------------------------------------------------------- /easy_fs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "easy_fs" 3 | version = "0.0.1" 4 | authors = ["Haochen Gong <1527198893@qq.com>"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | spin = "0.7.0" 9 | lazy_static = { version = "1.4.0", features = ["spin_no_std"] } 10 | riscv = { path = "../dependency/riscv", features = ["inline-asm"] } 11 | -------------------------------------------------------------------------------- /easy_fs/src/blockdevice.rs: -------------------------------------------------------------------------------- 1 | use core::any::Any; 2 | 3 | pub trait BlockDevice : Send + Sync + Any { 4 | fn read_block(&self, block_id: usize, buf: &mut [u8]); 5 | fn write_block(&self, block_id: usize, buf: &[u8]); 6 | } -------------------------------------------------------------------------------- /easy_fs/src/console.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{self, Write}; 2 | use crate::sbi::console_putchar; 3 | 4 | struct Stdout; 5 | impl Write for Stdout { 6 | fn write_str(&mut self, s: &str) -> fmt::Result { 7 | for c in s.chars() { 8 | console_putchar(c as usize); 9 | } 10 | Ok(()) 11 | } 12 | } 13 | 14 | pub fn print(args: fmt::Arguments) { 15 | Stdout.write_fmt(args).unwrap(); 16 | } 17 | 18 | #[macro_export] 19 | macro_rules! print { 20 | ($fmt: literal $(, $($arg: tt)+)?) => { 21 | $crate::console::print(format_args!($fmt $(, $($arg)+)?)); 22 | } 23 | } 24 | #[macro_export] 25 | macro_rules! println { 26 | ($fmt: literal $(, $($arg: tt)+)?) => { 27 | $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)); 28 | } 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /easy_fs/src/sbi.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | const SBI_SET_TIMER: usize = 0; 3 | const SBI_CONSOLE_PUTCHAR: usize = 1; 4 | const SBI_CONSOLE_GETCHAR: usize = 2; 5 | const SBI_CLEAR_IPI: usize = 3; 6 | const SBI_SEND_IPI: usize = 4; 7 | const SBI_REMOTE_FENCE_I: usize = 5; 8 | const SBI_REMOTE_SFENCE_VMA: usize = 6; 9 | const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7; 10 | const SBI_SHUTDOWN: usize = 8; 11 | 12 | #[inline(always)] 13 | fn sbi_call(which: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { 14 | let mut ret; 15 | unsafe { 16 | llvm_asm!("ecall" 17 | : "={x10}" (ret) 18 | : "{x10}" (arg0), "{x11}" (arg1), "{x12}" (arg2), "{x17}" (which) 19 | : "memory" 20 | : "volatile" 21 | ); 22 | } 23 | ret 24 | } 25 | 26 | pub fn sbi_send_ipi(mask: usize) { 27 | sbi_call(SBI_SEND_IPI, mask, 0, 0); 28 | } 29 | 30 | pub fn set_timer(timer: usize) { 31 | sbi_call(SBI_SET_TIMER, timer, 0, 0); 32 | } 33 | 34 | pub fn console_putchar(c: usize) { 35 | sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0); 36 | } 37 | 38 | pub fn console_getchar() -> usize { 39 | sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) 40 | } 41 | 42 | pub fn shutdown() -> ! { 43 | sbi_call(SBI_SHUTDOWN, 0, 0, 0); 44 | panic!("It should shutdown!"); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /fat32-fuse/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | fs/ -------------------------------------------------------------------------------- /fat32-fuse/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "simple-fat32-fuse" 3 | version = "0.1.0" 4 | authors = ["Haochen Gong <1527198893@qq.com>"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | clap = "2.33.3" 11 | simple-fat32 = { path = "../simple_fat32" } 12 | rand = "0.8.0" 13 | -------------------------------------------------------------------------------- /fat32-fuse/mnt.sh: -------------------------------------------------------------------------------- 1 | sudo umount sd_mnt 2 | sudo mkfs.vfat -F 32 /dev/sdb1 3 | sudo chmod 777 /dev/sdb1 4 | sudo mount /dev/sdb1 sd_mnt 5 | sudo chmod 777 sd_mnt -------------------------------------------------------------------------------- /fat32-fuse/qemu_fs.sh: -------------------------------------------------------------------------------- 1 | sudo mkfs.vfat -F 32 fat32.img 2 | sudo chmod 777 fat32.img 3 | #sudo mount fat32.img sd_mnt 4 | #sudo chmod 777 sd_mnt -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/System Volume Information/IndexerVolumeGuid: -------------------------------------------------------------------------------- 1 | {B6676005-EB21-4169-9DA6-1AF262389A9E} -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/System Volume Information/WPSettings.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/System Volume Information/WPSettings.dat -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/cat -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/cmdline_args: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/cmdline_args -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/dir0/dir1/file2: -------------------------------------------------------------------------------- 1 | hello world! 2 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/dir0/file1: -------------------------------------------------------------------------------- 1 | hello world! 2 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/exit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/exit -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/fantastic_text: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/fantastic_text -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/filetest_simple: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/filetest_simple -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/forktest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/forktest -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/forktest2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/forktest2 -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/forktest_simple: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/forktest_simple -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/forktree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/forktree -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/hello2: -------------------------------------------------------------------------------- 1 | hello world! 2 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/hello_world: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/hello_world -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/initproc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/initproc -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/ls -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/matrix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/matrix -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/mnt/test_openat.txt: -------------------------------------------------------------------------------- 1 | test_openat 2 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/pipe_large_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/pipe_large_test -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/pipetest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/pipetest -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/run_pipe_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/run_pipe_test -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/sleep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/sleep -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/sleep_simple: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/sleep_simple -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/stack_overflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/stack_overflow -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_brk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_brk -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_chdir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_chdir -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_clone: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_clone -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_close: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_close -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_dup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_dup -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_dup2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_dup2 -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_execve: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_execve -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_exit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_exit -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_fork: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_fork -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_fstat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_fstat -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_getcwd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_getcwd -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_getdents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_getdents -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_getpid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_getpid -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_getppid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_getppid -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_gettimeofday: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_gettimeofday -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_ls -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_mkdir_: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_mkdir_ -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_mmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_mmap -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_mount: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_mount -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_munmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_munmap -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_open: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_open -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_openat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_openat -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_pipe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_pipe -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_read: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_read -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_run-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tests=" 4 | brk 5 | chdir 6 | clone 7 | close 8 | dup2 9 | dup 10 | execve 11 | exit 12 | fork 13 | fstat 14 | getcwd 15 | getdents 16 | getpid 17 | getppid 18 | gettimeofday 19 | mkdir_ 20 | mmap 21 | mount 22 | munmap 23 | openat 24 | open 25 | pipe 26 | read 27 | times 28 | umount 29 | uname 30 | unlink 31 | wait 32 | waitpid 33 | write 34 | yield.sh 35 | " 36 | for i in $tests 37 | do 38 | echo "Testing $i :" 39 | ./$i 40 | done 41 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_sleep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_sleep -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_test_echo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_test_echo -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_text.txt: -------------------------------------------------------------------------------- 1 | Hi, this is a text file. 2 | syscalls testing success! 3 | 4 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_times: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_times -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_umount: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_umount -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_uname: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_uname -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_unlink: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_unlink -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_wait: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_wait -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_waitpid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_waitpid -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_write: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_write -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_yield.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo '========== START test_yield ==========' 4 | 5 | ./yield_A & 6 | ./yield_B & 7 | ./yield_C & 8 | wait 9 | 10 | echo '========== END test_yield ==========' 11 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_yield_A: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_yield_A -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_yield_B: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_yield_B -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/testsuites_yield_C: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/testsuites_yield_C -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/text.txt: -------------------------------------------------------------------------------- 1 | Hi, this is a text file. 2 | -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/user_shell: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/user_shell -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/usertests: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/usertests -------------------------------------------------------------------------------- /fat32-fuse/sd_mnt2/yield: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/fat32-fuse/sd_mnt2/yield -------------------------------------------------------------------------------- /os.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/os.bin -------------------------------------------------------------------------------- /pic/FAT manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/FAT manager.png -------------------------------------------------------------------------------- /pic/P_CallRelation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_CallRelation.png -------------------------------------------------------------------------------- /pic/P_Exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_Exit.png -------------------------------------------------------------------------------- /pic/P_KernelSpace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_KernelSpace.png -------------------------------------------------------------------------------- /pic/P_StructRelation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_StructRelation.png -------------------------------------------------------------------------------- /pic/P_UserSpace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_UserSpace.png -------------------------------------------------------------------------------- /pic/P_Waitpid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_Waitpid.png -------------------------------------------------------------------------------- /pic/P_Yield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/P_Yield.png -------------------------------------------------------------------------------- /pic/block cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/block cache.png -------------------------------------------------------------------------------- /pic/copy on write.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/copy on write.bmp -------------------------------------------------------------------------------- /pic/copy on write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/copy on write.png -------------------------------------------------------------------------------- /pic/copy on write1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/copy on write1.png -------------------------------------------------------------------------------- /pic/framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/framework.png -------------------------------------------------------------------------------- /pic/heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/heap.png -------------------------------------------------------------------------------- /pic/kernel space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/kernel space.png -------------------------------------------------------------------------------- /pic/layout.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/layout.bmp -------------------------------------------------------------------------------- /pic/space layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/space layout.png -------------------------------------------------------------------------------- /pic/space layout1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/space layout1.png -------------------------------------------------------------------------------- /pic/task_manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/task_manager.png -------------------------------------------------------------------------------- /pic/user space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/pic/user space.png -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | *.egg-info 4 | .vscode 5 | __pycache__ 6 | *.pyc 7 | -------------------------------------------------------------------------------- /tools/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Kendryte 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "kflash, A Python-based Kendryte K210 UART ISP Utility", 3 | "name": "tool-kflash-kendryte210", 4 | "system": "*", 5 | "url": "https://github.com/kendryte/kflash.py", 6 | "version": "1.0.0" 7 | } 8 | -------------------------------------------------------------------------------- /toyos/.cargo/config: -------------------------------------------------------------------------------- 1 | #设置编译环境 2 | [build] 3 | target = "riscv64gc-unknown-none-elf" 4 | 5 | #设置链接脚本 6 | [target.riscv64gc-unknown-none-elf] 7 | rustflags = [ 8 | "-Clink-arg=-Tsrc/linker.ld","-Cforce-frame-pointers=yes" 9 | ] 10 | 11 | #把软件包管理器 cargo 所用的软件包镜像地址 crates.io换成中国科学技术大学的镜像服务器来加速三方库的下载 12 | [source.crates-io] 13 | replace-with = 'tuna' 14 | 15 | [source.tuna] 16 | registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git" 17 | -------------------------------------------------------------------------------- /toyos/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /toyos/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "toyos" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | riscv = { git = "https://gitee.com/rcore-os/riscv", features = ["inline-asm"]} 10 | 11 | buddy_system_allocator = "0.6" 12 | bitflags = "1.2.1" 13 | xmas-elf = "0.7.0" 14 | spin = "0.7.0" 15 | embedded-hal = {version="0.2.7", features = ["unproven"] } 16 | 17 | lazy_static = {version = "1.4.0", features = ["spin_no_std"]} 18 | 19 | k210-pac = { path = "../dependency/k210-pac" } 20 | k210-hal = { path = "../dependency/k210-hal" } 21 | k210-soc = { path = "../dependency/k210-soc" } 22 | 23 | virtio-drivers = { path = "../dependency/virtio-drivers" } 24 | 25 | easy_fs = {path = "../easy_fs"} 26 | 27 | bit_field = "0.10.1" 28 | nb = "1" 29 | 30 | [build-dependencies] 31 | chrono = "0.4" 32 | 33 | [features] 34 | board_qemu = [] 35 | board_k210 = [] 36 | 37 | [profile.release] 38 | debug = true 39 | -------------------------------------------------------------------------------- /toyos/buildfs.sh: -------------------------------------------------------------------------------- 1 | U_FAT32_DIR="../fat32-fuse" 2 | U_FAT32="${U_FAT32_DIR}/fat32.img" 3 | 4 | sudo chmod 777 ${U_FAT32} 5 | sudo umount ${U_FAT32} 6 | #sudo umount ${U_FAT32} 7 | sudo mkfs.vfat -F 32 ${U_FAT32} 8 | 9 | if test -e ${U_FAT32_DIR}/fs 10 | then 11 | sudo rm -r ${U_FAT32_DIR}/fs 12 | mkdir ${U_FAT32_DIR}/fs 13 | else 14 | mkdir ${U_FAT32_DIR}/fs 15 | fi 16 | 17 | 18 | sudo mount ${U_FAT32} ${U_FAT32_DIR}/fs 19 | 20 | #sudo rm ${U_FAT32_DIR}/fs/* 21 | 22 | #for programname in $(ls ../user/src/bin) 23 | #do 24 | # if [ $programname != "initproc.rs" ] #&& [ $programname != "user_shell.rs" ] 25 | # then 26 | # sudo cp ../user/target/riscv64gc-unknown-none-elf/release/${programname%.rs} ../fat32-fuse/fs/${programname%.rs} 27 | # fi 28 | #done 29 | sudo cp ../user_C_program/user/build/riscv64 ../fat32-fuse/fs/ -r 30 | 31 | sudo umount ${U_FAT32_DIR}/fs 32 | -------------------------------------------------------------------------------- /toyos/last-qemu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/toyos/last-qemu -------------------------------------------------------------------------------- /toyos/riscv64-unknown-elf-gdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/toyos/riscv64-unknown-elf-gdb -------------------------------------------------------------------------------- /toyos/src/drivers/block/mod.rs: -------------------------------------------------------------------------------- 1 | mod virtio_blk; 2 | mod sdcard; 3 | 4 | use lazy_static::*; 5 | use alloc::sync::Arc; 6 | use easy_fs::BlockDevice; 7 | use virtio_drivers::*; 8 | 9 | #[cfg(feature = "board_qemu")] 10 | type BlockDeviceImpl = virtio_blk::VirtIOBlock; 11 | 12 | #[cfg(feature = "board_k210")] 13 | type BlockDeviceImpl = sdcard::SDCardWrapper; 14 | 15 | lazy_static! { 16 | pub static ref BLOCK_DEVICE: Arc = Arc::new(BlockDeviceImpl::new()); 17 | } 18 | 19 | #[allow(unused)] 20 | pub fn block_device_test() { 21 | let block_device = BLOCK_DEVICE.clone(); 22 | let mut write_buffer = [0u8; 512]; 23 | let mut read_buffer = [0u8; 512]; 24 | for i in 0..512 { 25 | for byte in write_buffer.iter_mut() { *byte = i as u8; } 26 | block_device.write_block(i as usize, &write_buffer); 27 | block_device.read_block(i as usize, &mut read_buffer); 28 | assert_eq!(write_buffer, read_buffer); 29 | } 30 | println!("block device test passed!"); 31 | } 32 | -------------------------------------------------------------------------------- /toyos/src/drivers/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod block; 2 | pub mod serial; 3 | 4 | pub use block::BLOCK_DEVICE; 5 | pub use serial::ns16550a::Ns16550a; -------------------------------------------------------------------------------- /toyos/src/drivers/serial/mod.rs: -------------------------------------------------------------------------------- 1 | /* ns16550a is used for qemu. 2 | For K210, we use k210-pac directly. 3 | */ 4 | pub mod ns16550a; 5 | //mod uart; 6 | 7 | 8 | -------------------------------------------------------------------------------- /toyos/src/entry.asm: -------------------------------------------------------------------------------- 1 | .section .text.entry 2 | .globl _start 3 | _start: 4 | # tp:hart_id 5 | #mv a0,tp # RustSBI 6 | mv tp, a0 # OpenSBI 7 | la a1, boot_stack_top 8 | slli a0, a0, 15 # hart_id* stacksize 9 | add a0, a0, a1 10 | # a0 = boot_stack_top + hart_id* stacksize 11 | mv sp, a0 12 | call os_main 13 | 14 | .section .bss.stack 15 | .globl boot_stack 16 | boot_stack: 17 | .space 4096 * 8 18 | .globl boot_stack_top 19 | boot_stack_top: 20 | boot_stack2: 21 | .space 4096 * 8 22 | .globl boot_stack_top2 23 | boot_stack_top2: -------------------------------------------------------------------------------- /toyos/src/fs/iovec.rs: -------------------------------------------------------------------------------- 1 | use alloc::vec::Vec; 2 | use alloc::vec; 3 | use crate::memory::{ 4 | get_data_buffer, 5 | translated_array_copy, 6 | }; 7 | 8 | 9 | #[derive(Debug, Copy, Clone)] 10 | #[repr(C)] 11 | pub struct IoVec { 12 | base: *mut u8, 13 | len: usize, 14 | } 15 | 16 | pub struct IoVecs(pub Vec<&'static mut [u8]>); 17 | 18 | impl IoVecs { 19 | pub unsafe fn new( 20 | iov_ptr: *mut IoVec, 21 | iov_num: usize, 22 | token: usize, 23 | )-> Self { 24 | let mut iovecs: Vec<&'static mut [u8]> = vec![]; 25 | let iovref_vec = translated_array_copy(token, iov_ptr, iov_num); 26 | iovecs.reserve(iovref_vec.len()); 27 | for iovref in iovref_vec { 28 | if iovref.len == 0 { 29 | continue; 30 | } 31 | let mut buf:Vec<&'static mut [u8]> = get_data_buffer(token, iovref.base, iovref.len); 32 | iovecs.append(&mut buf); 33 | } 34 | Self(iovecs) 35 | } 36 | } -------------------------------------------------------------------------------- /toyos/src/fs/mount.rs: -------------------------------------------------------------------------------- 1 | use alloc::vec::Vec; 2 | use alloc::string::String; 3 | use lazy_static::*; 4 | use spin::Mutex; 5 | use alloc::sync::Arc; 6 | const MNT_MAXLEN:usize = 16; 7 | 8 | pub struct MountTable { 9 | mnt_list:Vec<(String, String, String)> 10 | } 11 | 12 | impl MountTable { 13 | pub fn mount(&mut self, special:String,dir:String,fstype:String, flag:u32)->isize{ 14 | if self.mnt_list.len() == MNT_MAXLEN { 15 | return -1 16 | } 17 | if self.mnt_list.iter().find( |&(_,d, _)|{*d == dir}).is_some() { 18 | return 0 19 | } 20 | self.mnt_list.push((special, dir, fstype)); 21 | return 0 22 | } 23 | 24 | pub fn umount(&mut self, special:String, flags:u32)->isize{ 25 | let len = self.mnt_list.len(); 26 | for i in 0..len { 27 | if self.mnt_list[i].0 == special || self.mnt_list[i].1 == special{ 28 | self.mnt_list.remove(i); 29 | return 0 30 | } 31 | } 32 | return -1 33 | } 34 | } 35 | 36 | lazy_static! { 37 | pub static ref MNT_TABLE: Arc> = { 38 | let mnt_table = MountTable { 39 | mnt_list: Vec::new(), 40 | }; 41 | Arc::new(Mutex::new( mnt_table )) 42 | }; 43 | } -------------------------------------------------------------------------------- /toyos/src/lang_items.rs: -------------------------------------------------------------------------------- 1 | use core::panic::PanicInfo; 2 | use crate::sbi::shutdown; 3 | 4 | /* 5 | * location.file打印出错文件 6 | * location.line打印出错行 7 | * info.message打印出错信息 8 | */ 9 | 10 | #[panic_handler] 11 | fn panic(info: &PanicInfo) -> ! { 12 | if let Some(location) = info.location() { 13 | println!( 14 | "Panicked at {}:{} {}", 15 | location.file(), 16 | location.line(), 17 | info.message().unwrap() 18 | ); 19 | } else { 20 | println!("Panicked: {}", info.message().unwrap()); 21 | } 22 | shutdown() 23 | } 24 | 25 | pub trait Bytes{ 26 | fn as_bytes(&self) -> &[u8] { 27 | let size = core::mem::size_of::(); 28 | unsafe { 29 | core::slice::from_raw_parts( 30 | self as *const _ as *const T as usize as *const u8, 31 | size, 32 | ) 33 | } 34 | } 35 | 36 | fn as_bytes_mut(&mut self) -> &mut [u8] { 37 | let size = core::mem::size_of::(); 38 | unsafe { 39 | core::slice::from_raw_parts_mut( 40 | self as *mut _ as *mut T as usize as *mut u8, 41 | size, 42 | ) 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /toyos/src/link_app.S: -------------------------------------------------------------------------------- 1 | 2 | .align 3 3 | .section .data 4 | .global _num_app 5 | _num_app: 6 | .quad 1 7 | .quad app_0_start 8 | .quad app_0_end 9 | 10 | .global _app_names 11 | _app_names: 12 | .string "initproc" 13 | 14 | .section .data 15 | .global app_0_start 16 | .global app_0_end 17 | .align 3 18 | app_0_start: 19 | .incbin "../user/target/riscv64gc-unknown-none-elf/release/initproc" 20 | app_0_end: 21 | -------------------------------------------------------------------------------- /toyos/src/linker-k210.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(riscv) 2 | ENTRY(_start) 3 | BASE_ADDRESS = 0x80020000; 4 | 5 | SECTIONS 6 | { 7 | . = BASE_ADDRESS; 8 | skernel = .; 9 | 10 | stext = .; 11 | .text : { 12 | *(.text.entry) 13 | 14 | . = ALIGN(4k); 15 | 16 | strampoline = .; 17 | *(.text.trampoline); 18 | 19 | . = ALIGN(4k); 20 | 21 | *(.text .text.*) 22 | } 23 | 24 | . = ALIGN(4K); 25 | etext = .; 26 | srodata = .; 27 | .rodata : { 28 | *(.rodata .rodata.*) 29 | *(.srodata .srodata.*) 30 | } 31 | 32 | . = ALIGN(4K); 33 | erodata = .; 34 | sdata = .; 35 | .data : { 36 | *(.data .data.*) 37 | *(.sdata .sdata.*) 38 | } 39 | 40 | . = ALIGN(4K); 41 | edata = .; 42 | sbss_with_stack = .; 43 | .bss : { 44 | *(.bss.stack) 45 | sbss = .; 46 | *(.bss .bss.*) 47 | *(.sbss .sbss.*) 48 | } 49 | 50 | . = ALIGN(4K); 51 | ebss = .; 52 | ekernel = .; 53 | 54 | /DISCARD/ : { 55 | *(.eh_frame) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /toyos/src/linker-qemu.ld: -------------------------------------------------------------------------------- 1 | /*设置目标平台为riscv*/ 2 | OUTPUT_ARCH(riscv) 3 | /*设置入口位置*/ 4 | ENTRY(_start) 5 | /*声明一个常量,作为初始化代码被放置的地址*/ 6 | BASE_ADDRESS = 0x80200000; 7 | 8 | SECTIONS 9 | { 10 | /*设置起始地址*/ 11 | . = BASE_ADDRESS; 12 | 13 | /*顺序放置skernel和stext*/ 14 | skernel = .; 15 | stext = .; 16 | 17 | /* 18 | * .text段放置内容 19 | * 格式:(SectionName) 20 | */ 21 | .text : { 22 | *(.text.entry) 23 | 24 | . = ALIGN(4k); 25 | 26 | strampoline = .; 27 | *(.text.trampoline); 28 | 29 | . = ALIGN(4k); 30 | 31 | *(.text .text.*) 32 | } 33 | 34 | /* 35 | * 按4k大小对齐 36 | */ 37 | . = ALIGN(4k); 38 | 39 | etext = .; 40 | srodata = .; 41 | .rodata : { 42 | *(.rodata .rodata.*) 43 | *(.srodata .srodata.*) 44 | } 45 | 46 | . = ALIGN(4k); 47 | 48 | erodata = .; 49 | sdata = .; 50 | .data : { 51 | *(.data .data.*) 52 | *(.sdata .sdata.*) 53 | } 54 | 55 | . = ALIGN(4k); 56 | 57 | edata = .; 58 | sbss_with_stack = .; 59 | .bss : { 60 | *(.bss.stack) 61 | sbss = .; 62 | *(.bss .bss.*) 63 | *(.sbss .sbss.*) 64 | } 65 | 66 | . = ALIGN(4k); 67 | ebss = .; 68 | ekernel = .; 69 | 70 | /DISCARD/ : { 71 | *(.eh_frame) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /toyos/src/memory/heap_allocator.rs: -------------------------------------------------------------------------------- 1 | use buddy_system_allocator::LockedHeap; 2 | use crate::config::KERNEL_HEAP_SIZE; 3 | 4 | /* 5 | *堆分配器实现 6 | *此处借用已实现的堆分配器 7 | */ 8 | 9 | /*全局化堆分配器*/ 10 | #[global_allocator] 11 | static HEAP_ALLOCATOR: LockedHeap = LockedHeap::empty(); 12 | 13 | /*分配出错时的处理*/ 14 | #[alloc_error_handler] 15 | pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! { 16 | panic!("Heap allocation error, layout = {:?}", layout); 17 | } 18 | 19 | /*堆空间大小设置*/ 20 | static mut HEAP_SPACE :[u8; KERNEL_HEAP_SIZE] = [0; KERNEL_HEAP_SIZE]; 21 | 22 | /*堆初始化*/ 23 | pub fn init_heap(){ 24 | unsafe{ 25 | HEAP_ALLOCATOR.lock().init(HEAP_SPACE.as_ptr() as usize, KERNEL_HEAP_SIZE); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /toyos/src/sbi.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | 3 | use core::arch::asm; 4 | 5 | /* 6 | * 封装与RustSBI进行的交互,使用RustSBI提供的服务 7 | *包括读取或打印控制台字符串、关机等... 8 | */ 9 | 10 | const SBI_SET_TIMER: usize = 0; 11 | const SBI_CONSOLE_PUTCHAR: usize = 1; 12 | const SBI_CONSOLE_GETCHAR: usize = 2; 13 | const SBI_CLEAR_IPI: usize = 3; 14 | const SBI_SHUTDOWN: usize = 8; 15 | 16 | const SBI_SEND_IPI: usize = 4; 17 | const SBI_REMOTE_FENCE_I: usize = 5; 18 | const SBI_REMOTE_SFENCE_VMA: usize = 6; 19 | const SBI_REMOTE_SFENCE_VMA_ASID: usize = 7; 20 | 21 | #[inline(always)] 22 | fn sbi_call(select: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { 23 | let mut ret; 24 | unsafe { 25 | asm!( 26 | "ecall", 27 | inlateout("x10") arg0 => ret, 28 | in("x11") arg1, 29 | in("x12") arg2, 30 | in("x17") select, 31 | ); 32 | } 33 | ret 34 | } 35 | //设置下一次时钟中断的时间,通过修改mtimecmp 36 | pub fn set_timer(timer: usize) { 37 | sbi_call(SBI_SET_TIMER, timer, 0, 0); 38 | } 39 | pub fn console_putchar(c : usize) { 40 | sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0); 41 | } 42 | 43 | pub fn console_getchar() -> usize { 44 | sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) 45 | } 46 | 47 | pub fn shutdown() -> ! { 48 | sbi_call(SBI_SHUTDOWN, 0, 0, 0); 49 | panic!("It should shutdown!"); 50 | } 51 | 52 | pub fn sbi_send_ipi(mask: usize) { 53 | sbi_call(SBI_SEND_IPI, mask, 0, 0); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /toyos/src/sync/mod.rs: -------------------------------------------------------------------------------- 1 | mod up; 2 | mod mutex; 3 | 4 | pub use up::UPSafeCell; 5 | pub use mutex::*; 6 | 7 | pub fn test(){ 8 | } 9 | /* 10 | *===============SpinMutex================== 11 | * 12 | *pub struct SpinMutex{ 13 | state : STATE 14 | } 15 | * 16 | * SpinMutex对外开放接口: 17 | * 18 | /*新建一个自旋锁*/ 19 | pub fn new() -> Self{} 20 | 21 | /*上锁*/ 22 | pub fn lock(&mut self){} 23 | 24 | /*解锁*/ 25 | pub fn unlock(&mut self){} 26 | * 27 | *================================================ 28 | * 29 | *==============自旋锁SpinLock================ 30 | * 31 | *pub struct SpinLock{ 32 | state : STATE,//自旋锁状态 33 | data : UpSafeCell,//自旋锁封装的数据 34 | } 35 | * 36 | *SpinLock对外开放接口: 37 | * 38 | /*新建一个自旋锁,data输入需要封装的变量,返回已被SpinMutex封装的变量*/ 39 | pub fn new(data : T) -> SpinMutex 40 | * 41 | /*加锁,返回可修改变量,若已加锁会进入忙等待,使用不当可能造成死锁!!!*/ 42 | pub fn lock(&mut self) -> RefMut<'_, T> 43 | * 44 | /*解锁*/ 45 | pub fn unlock(&mut self) 46 | * 47 | */ 48 | 49 | -------------------------------------------------------------------------------- /toyos/src/sync/up.rs: -------------------------------------------------------------------------------- 1 | use core::cell::{RefCell, RefMut}; 2 | 3 | pub struct UPSafeCell { 4 | inner: RefCell, 5 | } 6 | 7 | //unsafe impl Sync for UPSafeCell {} 8 | //unsafe impl Send for UPSafeCell {} 9 | unsafe impl Sync for UPSafeCell {} 10 | 11 | impl UPSafeCell { 12 | pub unsafe fn new(value: T) -> Self { 13 | Self { inner: RefCell::new(value) } 14 | } 15 | 16 | pub fn exclusive_access(&self) -> RefMut<'_, T> { 17 | self.inner.borrow_mut() 18 | } 19 | 20 | 21 | } 22 | 23 | pub struct RefFMutex{ 24 | inner: RefCell, 25 | } 26 | 27 | unsafe impl Sync for RefFMutex {} 28 | unsafe impl Send for RefFMutex {} 29 | 30 | impl RefFMutex { 31 | pub unsafe fn new(value: T) -> Self { 32 | Self { inner: RefCell::new(value) } 33 | } 34 | 35 | pub fn exclusive_access(&self) -> RefMut<'_, T> { 36 | self.inner.borrow_mut() 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /toyos/src/syscall/config.rs: -------------------------------------------------------------------------------- 1 | pub const SYS_GETCWD: usize = 17; //获取当前工作目录 2 | pub const SYS_PIPE2: usize = 59; //创建管道 3 | pub const SYS_DUP: usize = 23; //复制文件描述符 4 | pub const SYS_CHDIR: usize = 49; //切换工作目录 5 | pub const SYS_DUP3: usize = 24; //复制文件描述符,并指定新的文件描述符 6 | pub const SYS_chdir: usize = 49; //切换工作目录 7 | pub const SYS_OPENAT: usize = 56; //打开或创建一个文件 8 | pub const SYS_CLOSE: usize = 57; //关闭一个文件描述符 9 | pub const SYS_GETDENTS64: usize = 61; //获取目录条目 10 | pub const SYS_READ: usize = 63; //从一个文件描述符中读取 11 | pub const SYS_WRITE: usize = 64; //从一个文件描述符写入 12 | pub const SYS_LINKAT: usize = 37; //创建文件的链接 13 | pub const SYS_UNLINKAT: usize = 35; //移除制定文件的链接(可用于删除文件) 14 | pub const SYS_MKDIRAT: usize = 34; //创建目录 15 | pub const SYS_UMOUNT2: usize = 39; //卸载文件系统 16 | pub const SYS_MOUNT: usize = 40; //挂载文件系统 17 | pub const SYS_FSTAT: usize = 80; //获取文件状态 18 | pub const SYS_CLONE: usize = 220; //创建一个子进程 19 | pub const SYS_EXECVE: usize = 221; //执行一个指定的程序 20 | pub const SYS_WAIT4: usize = 260; //等待进程改变状态 21 | pub const SYS_EXIT: usize = 93; //触发进程终止,无返回值 22 | pub const SYS_GETPPID : usize = 173; //获取父进程ID 23 | pub const SYS_GETPID : usize = 172; //获取进程ID 24 | pub const SYS_BRK: usize = 214; //修改数据段的大小 25 | pub const SYS_MUNMAP: usize = 215; //将文件或设备取消映射到内存中 26 | pub const SYS_MMAP: usize = 222; //将文件或设备映射到内存中 27 | pub const SYS_TIMES: usize = 153; //获取进程时间 28 | pub const SYS_UNAME: usize = 160; //打印系统信息 29 | pub const SYS_SCHED_YIELD: usize = 124; //让出调度器 30 | pub const SYS_GET_TIMEOFDAY:usize = 169; //获取时间 31 | pub const SYS_NANOSLEEP: usize = 101; //执行线程睡眠,sleep()库函数都基于此系统调用 32 | -------------------------------------------------------------------------------- /toyos/src/syscall/mod.rs: -------------------------------------------------------------------------------- 1 | mod interface; 2 | mod process; 3 | mod system_call; 4 | mod config; 5 | mod fs; 6 | 7 | pub use system_call::*; 8 | 9 | use interface::*; 10 | use config::*; 11 | use fs::*; 12 | -------------------------------------------------------------------------------- /toyos/src/task/switch.S: -------------------------------------------------------------------------------- 1 | #保存进程上下文并加载下一个进程 2 | .altmacro 3 | .macro SAVE_SN n 4 | sd s\n, (\n+2)*8(a0) 5 | .endm 6 | .macro LOAD_SN n 7 | ld s\n, (\n+2)*8(a1) 8 | .endm 9 | .section .text 10 | .globl __switch 11 | __switch: 12 | sd sp, 8(a0) 13 | sd ra, 0(a0) 14 | .set n, 0 15 | .rept 12 16 | SAVE_SN %n 17 | .set n, n + 1 18 | .endr 19 | 20 | ld ra, 0(a1) 21 | .set n, 0 22 | .rept 12 23 | LOAD_SN %n 24 | .set n, n+1 25 | .endr 26 | ld sp, 8(a1) 27 | ret 28 | 29 | -------------------------------------------------------------------------------- /toyos/src/task/task_context.rs: -------------------------------------------------------------------------------- 1 | use crate::trap::trap_return; 2 | /* 3 | * taskcontext结构以及相关函数,用于保存任务的上下文 4 | */ 5 | #[derive(Copy, Clone)] 6 | #[repr(C)] 7 | pub struct TaskContext { 8 | /* 9 | * 控制寄存器的保存: 10 | *ra寄存器 11 | *sp寄存器: stack pointer 12 | * 13 | * 通用寄存器: s0-s12 14 | */ 15 | ra: usize, 16 | sp: usize, 17 | s: [usize; 12], 18 | } 19 | 20 | impl TaskContext { 21 | pub fn zero_init() -> Self { 22 | Self { 23 | ra: 0, 24 | sp: 0, 25 | s: [0; 12], 26 | } 27 | } 28 | //初始化变量 29 | pub fn register_init(stack_pointer: usize) -> Self{ 30 | Self { 31 | ra: trap_return as usize, 32 | sp: stack_pointer, 33 | s : [0;12], 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /toyos/src/timer.rs: -------------------------------------------------------------------------------- 1 | use riscv::register::time; 2 | use crate::sbi::set_timer; 3 | use crate::config::CLOCK_FREQ; 4 | //riscv系列接口由RustSBI提供,可以看作是对机器层指令的封装和预处理 5 | 6 | const MSEC_PER_SEC: usize = 1_000; 7 | const TICKS_PER_SEC: usize = 100;//每秒时钟中断数 8 | const USEC_PER_SEC: usize = 1_000_1000;//微秒 9 | pub const NSEC_PER_SEC: usize = 1_000_000_000; 10 | 11 | #[derive(Copy, Clone)] 12 | pub struct TimeSpec{ 13 | pub tv_sec: usize, 14 | pub tv_nsec: usize, 15 | } 16 | 17 | pub struct TMS 18 | { 19 | pub tms_utime: usize, /* User CPU time. 用户程序 CPU 时间*/ 20 | pub tms_stime: usize, /* System CPU time. 系统调用所耗费的 CPU 时间 */ 21 | pub tms_cutime: usize, /* User CPU time of dead children. 已死掉子进程的 CPU 时间*/ 22 | pub tms_cstime: usize, /* System CPU time of dead children. 已死掉子进程所耗费的系统调用 CPU 时间*/ 23 | } 24 | //time::read()返回计数器值 25 | pub fn get_time() -> usize { 26 | time::read() 27 | } 28 | 29 | //微秒级 30 | pub fn get_time_ms() -> usize { 31 | time::read() / (CLOCK_FREQ / MSEC_PER_SEC) 32 | } 33 | 34 | //秒级 35 | pub fn get_time_s() -> usize{ 36 | time::read() / CLOCK_FREQ 37 | } 38 | //纳秒级 39 | pub fn get_time_ns() -> usize{ 40 | time::read() / (CLOCK_FREQ / USEC_PER_SEC) * MSEC_PER_SEC 41 | } 42 | 43 | pub fn set_next_trigger() { 44 | set_timer(get_time() + CLOCK_FREQ / TICKS_PER_SEC); 45 | } 46 | 47 | pub fn tick_ms_translate(time: usize) -> usize{ 48 | time / (CLOCK_FREQ / MSEC_PER_SEC) 49 | } 50 | -------------------------------------------------------------------------------- /toyos/src/trap/trap.S: -------------------------------------------------------------------------------- 1 | .altmacro 2 | 3 | #类似define 4 | .macro SAVE_GP n 5 | sd x\n, \n*8(sp) 6 | .endm 7 | .macro LOAD_GP n 8 | ld x\n, \n*8(sp) 9 | .endm 10 | 11 | #位于.text段 12 | .section .text.trampoline 13 | .globl __alltraps 14 | .globl __restore 15 | .align 2 16 | 17 | __alltraps: 18 | #从用户栈到用户空间中trapcontext位置,sscratch保存的是trapcontext地址,csrrw可理解为交换寄存器值,sp指向trapcontext 19 | csrrw sp, sscratch, sp 20 | 21 | sd x1, 1*8(sp) 22 | sd x3, 3*8(sp) 23 | #循环函数,保存寄存器 24 | 25 | 26 | .set n, 5 27 | .rept 27 28 | SAVE_GP %n 29 | .set n, n+1 30 | .endr 31 | 32 | csrr t0, sstatus 33 | csrr t1, sepc 34 | sd t0, 32*8(sp) 35 | sd t1, 33*8(sp) 36 | #保存用户栈栈顶地址 37 | csrr t2, sscratch 38 | sd t2, 2*8(sp) 39 | #传参内核satp、trap_handler地址等 40 | 41 | ld t0, 34*8(sp) 42 | ld t1, 36*8(sp) 43 | ld sp, 35*8(sp) 44 | #进入内核虚拟空间,跳转进入trap_handler 45 | csrw satp, t0 46 | sfence.vma 47 | jr t1 48 | 49 | __restore: 50 | csrw satp, a1 51 | sfence.vma 52 | csrw sscratch, a0 53 | mv sp, a0 54 | ld t0, 32*8(sp) 55 | ld t1, 33*8(sp) 56 | 57 | csrw sstatus, t0 58 | csrw sepc, t1 59 | 60 | ld x1, 1*8(sp) 61 | ld x3, 3*8(sp) 62 | .set n, 5 63 | .rept 27 64 | LOAD_GP %n 65 | .set n, n+1 66 | .endr 67 | 68 | ld sp, 2*8(sp) 69 | 70 | sret 71 | -------------------------------------------------------------------------------- /toyos/src/trap/trap_context.rs: -------------------------------------------------------------------------------- 1 | use riscv::register::sstatus::{Sstatus, self, SPP}; 2 | 3 | //trap上下文 4 | #[repr(C)] 5 | pub struct TrapContext { 6 | pub x: [usize; 32], 7 | pub sstatus: Sstatus, 8 | pub sepc: usize, 9 | pub kernel_satp: usize, 10 | pub kernel_sp: usize, 11 | pub trap_handler: usize, 12 | } 13 | 14 | impl TrapContext { 15 | pub fn set_sp(&mut self, sp: usize) {self.x[2] = sp;} 16 | pub fn process_cx_init(entry: usize, sp: usize, kernel_satp: usize, trap_handler: usize, kernel_sp: usize) -> Self{ 17 | let mut sstatus = sstatus::read(); 18 | sstatus.set_spp(SPP::User); 19 | let mut cx = Self{ 20 | x: [0;32], 21 | sstatus, 22 | sepc: entry, 23 | kernel_satp: kernel_satp, 24 | kernel_sp: kernel_sp, 25 | trap_handler: trap_handler, 26 | }; 27 | cx.set_sp(sp); 28 | cx 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /user/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "riscv64gc-unknown-none-elf" 3 | 4 | [target.riscv64gc-unknown-none-elf] 5 | rustflags = [ 6 | "-Clink-args=-Tsrc/linker.ld", 7 | ] 8 | -------------------------------------------------------------------------------- /user/.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | -------------------------------------------------------------------------------- /user/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "buddy_system_allocator" 7 | version = "0.6.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b4e85e760e105b46ae0bd1236578793c6c147ae7463fe95c8350296b8bfcb830" 10 | dependencies = [ 11 | "spin", 12 | ] 13 | 14 | [[package]] 15 | name = "spin" 16 | version = "0.7.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "13287b4da9d1207a4f4929ac390916d64eacfe236a487e9a9f5b3be392be5162" 19 | 20 | [[package]] 21 | name = "user_lib" 22 | version = "0.1.0" 23 | dependencies = [ 24 | "buddy_system_allocator", 25 | ] 26 | -------------------------------------------------------------------------------- /user/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "user_lib" 3 | version = "0.1.0" 4 | authors = ["Yifan Wu "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | buddy_system_allocator = "0.6.0" 11 | 12 | [profile.release] 13 | debug = true -------------------------------------------------------------------------------- /user/Makefile: -------------------------------------------------------------------------------- 1 | TARGET := riscv64gc-unknown-none-elf 2 | MODE := release 3 | APP_DIR := src/bin 4 | TARGET_DIR := target/$(TARGET)/$(MODE) 5 | APPS := $(wildcard $(APP_DIR)/*.rs) 6 | ELFS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%, $(APPS)) 7 | BINS := $(patsubst $(APP_DIR)/%.rs, $(TARGET_DIR)/%.bin, $(APPS)) 8 | 9 | OBJDUMP := rust-objdump --arch-name=riscv64 10 | OBJCOPY := rust-objcopy --binary-architecture=riscv64 11 | 12 | elf: $(APPS) 13 | @cargo build --release 14 | 15 | binary: elf 16 | $(foreach elf, $(ELFS), $(OBJCOPY) $(elf) --strip-all -O binary $(patsubst $(TARGET_DIR)/%, $(TARGET_DIR)/%.bin, $(elf));) 17 | 18 | build: binary 19 | 20 | clean: 21 | @cargo clean 22 | 23 | .PHONY: elf binary build clean -------------------------------------------------------------------------------- /user/src/console.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{self, Write}; 2 | use super::{read,write}; 3 | 4 | struct Stdout; 5 | const STDIN:usize=0; 6 | const STDOUT: usize = 1; 7 | 8 | impl Write for Stdout { 9 | fn write_str(&mut self, s: &str) -> fmt::Result { 10 | write(STDOUT, s.as_bytes()); 11 | Ok(()) 12 | } 13 | } 14 | 15 | pub fn print(args: fmt::Arguments) { 16 | Stdout.write_fmt(args).unwrap(); 17 | } 18 | 19 | #[macro_export] 20 | macro_rules! print { 21 | ($fmt: literal $(, $($arg: tt)+)?) => { 22 | $crate::console::print(format_args!($fmt $(, $($arg)+)?)); 23 | } 24 | } 25 | 26 | #[macro_export] 27 | macro_rules! println { 28 | ($fmt: literal $(, $($arg: tt)+)?) => { 29 | $crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?)); 30 | } 31 | } 32 | 33 | pub fn getchar() -> u8 { 34 | let mut c = [0u8; 1]; 35 | read(STDIN, &mut c); 36 | c[0] 37 | } 38 | -------------------------------------------------------------------------------- /user/src/lang_items.rs: -------------------------------------------------------------------------------- 1 | #[panic_handler] 2 | fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { 3 | let err = panic_info.message().unwrap(); 4 | if let Some(location) = panic_info.location() { 5 | println!("Panicked at {}:{}, {}", location.file(), location.line(), err); 6 | } else { 7 | println!("Panicked: {}", err); 8 | } 9 | loop {} 10 | } -------------------------------------------------------------------------------- /user/src/linker.ld: -------------------------------------------------------------------------------- 1 | 2 | OUTPUT_ARCH(riscv) 3 | ENTRY(_start) 4 | 5 | BASE_ADDRESS = 0x10000; 6 | 7 | SECTIONS 8 | { 9 | . = BASE_ADDRESS; 10 | .text : { 11 | *(.text.entry) 12 | *(.text .text.*) 13 | } 14 | . = ALIGN(4K); 15 | .rodata : { 16 | *(.rodata .rodata.*) 17 | *(.srodata .srodata.*) 18 | } 19 | . = ALIGN(4K); 20 | .data : { 21 | *(.data .data.*) 22 | *(.sdata .sdata.*) 23 | } 24 | .bss : { 25 | *(.bss .bss.*) 26 | *(.sbss .sbss.*) 27 | } 28 | /DISCARD/ : { 29 | *(.eh_frame) 30 | *(.debug*) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /user_C_program/README.md: -------------------------------------------------------------------------------- 1 | # riscv syscalls测试用例 2 | 3 | ### 配置 4 | 先把riscv的交叉编译链的路径放到环境变量PATH中,例如`export PATH=$PATH:/path/to/kendryte-toolchain/bin` 5 |
6 | 推荐使用本仓库提供的[K210交叉编译器](res/kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz) 7 | 8 | ### 编译 9 | 编译所有的syscalls测试用例: 10 | ``` 11 | cd user 12 | ./build-oscomp.sh 13 | ``` 14 | 之后也可以使用脚本`src/oscomp/build-single-testcase.sh`来编译单个测例 15 | 16 | ### 运行 17 | syscalls测试用例程序会生成到目录: 18 | ``` 19 | user/build/riscv64 20 | ``` 21 | 把此文件夹放到待测OS的Fat32文件系统中即可; 22 | -------------------------------------------------------------------------------- /user_C_program/check_tests.py: -------------------------------------------------------------------------------- 1 | # 用于检查测试脚本是否有低级错误 2 | import os 3 | import re 4 | 5 | expermit = ["yield_test.py"] 6 | 7 | dir = os.path.join(os.getcwd(), "user", "src", "oscomp") 8 | print(dir) 9 | for file_name in os.listdir(dir): 10 | if file_name[-3:] != ".py": 11 | continue 12 | if file_name in expermit: 13 | continue 14 | file_path = os.path.join(dir, file_name) 15 | print(file_path) 16 | file_test_name = re.findall(r"([a-zA-Z0-9]+)_test\.py", file_name) 17 | if not file_test_name: 18 | continue 19 | file_test_name = file_test_name[0] 20 | content = open(file_path, encoding="utf-8").read() 21 | class_test_name = re.findall(r"class ([a-zA-Z0-9]+)_test\(TestBase\)", content)[0] 22 | test_name, test_count = re.findall(r"super\(\)\.__init__\(\"([a-zA-Z0-9]+)\", (\d+)\)", content)[0] 23 | asserts = len(re.findall(r"self\.assert_", content)) 24 | assert class_test_name == file_test_name == test_name 25 | assert int(test_count) == asserts 26 | 27 | print("OK!") -------------------------------------------------------------------------------- /user_C_program/res/kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MZT-srcount/ToyOS/0a01a27b4bf4e1b38080c77ac90333ae372224d0/user_C_program/res/kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz -------------------------------------------------------------------------------- /user_C_program/user/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | riscv64/ -------------------------------------------------------------------------------- /user_C_program/user/build-oscomp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make all CHAPTER=7 4 | 5 | sync 6 | -------------------------------------------------------------------------------- /user_C_program/user/include/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef __STDIO_H__ 2 | #define __STDIO_H__ 3 | 4 | #define STDIN 0 5 | #define STDOUT 1 6 | #define STDERR 2 7 | 8 | //#define TEST_START(x) puts(x) 9 | #define TEST_START(x) puts("========== START ");puts(x);puts(" ==========\n"); 10 | #define TEST_END(x) puts("========== END ");puts(x);puts(" ==========\n"); 11 | 12 | #define stdin STDIN 13 | #define stdout STDOUT 14 | #define stderr STDERR 15 | 16 | #define va_start(ap, last) (__builtin_va_start(ap, last)) 17 | #define va_arg(ap, type) (__builtin_va_arg(ap, type)) 18 | #define va_end(ap) (__builtin_va_end(ap)) 19 | #define va_copy(d, s) (__builtin_va_copy(d, s)) 20 | 21 | typedef __builtin_va_list va_list; 22 | typedef unsigned long int uintmax_t; 23 | typedef long int intmax_t; 24 | 25 | int getchar(); 26 | int putchar(int); 27 | int puts(const char *s); 28 | void printf(const char *fmt, ...); 29 | 30 | #endif // __STDIO_H__ 31 | -------------------------------------------------------------------------------- /user_C_program/user/include/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef __STDLIB_H__ 2 | #define __STDLIB_H__ 3 | 4 | void panic(char *); 5 | 6 | #define WEXITSTATUS(s) (((s) & 0xff00) >> 8) 7 | 8 | #ifndef assert 9 | #define assert(f) \ 10 | if (!(f)) \ 11 | panic("\n --- Assert Fatal ! ---\n") 12 | #endif 13 | 14 | #endif //__STDLIB_H__ 15 | -------------------------------------------------------------------------------- /user_C_program/user/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __STRING_H__ 2 | #define __STRING_H__ 3 | 4 | #include "stddef.h" 5 | 6 | int isspace(int c); 7 | int isdigit(int c); 8 | int atoi(const char *s); 9 | void *memset(void *dest, int c, size_t n); 10 | int strcmp(const char *l, const char *r); 11 | size_t strlen(const char *); 12 | size_t strnlen(const char *s, size_t n); 13 | char *strncpy(char *restrict d, const char *restrict s, size_t n); 14 | int strncmp(const char *_l, const char *_r, size_t n); 15 | 16 | #endif // __STRING_H__ 17 | -------------------------------------------------------------------------------- /user_C_program/user/lib/arch/riscv/crt.S: -------------------------------------------------------------------------------- 1 | .section .text.entry 2 | .globl _start 3 | _start: 4 | mv a0, sp 5 | tail __start_main 6 | -------------------------------------------------------------------------------- /user_C_program/user/lib/arch/riscv/user.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(riscv) 2 | ENTRY(_start) 3 | 4 | SECTIONS { 5 | 6 | .text : { 7 | *(.text.entry) 8 | *(.text .text.*) 9 | } 10 | 11 | .bss : { 12 | *(.bss .bss.*) 13 | *(.sbss .sbss.*) 14 | } 15 | 16 | .data : { 17 | *(.data .rodata) 18 | *(.sdata .sdata.*) 19 | } 20 | 21 | /DISCARD/ : { *(.eh_*) } 22 | } -------------------------------------------------------------------------------- /user_C_program/user/lib/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int main(); 4 | 5 | int __start_main(long *p) 6 | { 7 | int argc = p[0]; 8 | char **argv = (void *)(p+1); 9 | 10 | exit(main(argc, argv)); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /user_C_program/user/lib/stdlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void panic(char *m) 7 | { 8 | puts(m); 9 | exit(-100); 10 | } 11 | -------------------------------------------------------------------------------- /user_C_program/user/lib/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSCALL_H__ 2 | #define __SYSCALL_H__ 3 | 4 | #include "syscall_arch.h" 5 | #include "syscall_ids.h" 6 | 7 | #ifndef __scc 8 | #define __scc(X) ((long)(X)) 9 | typedef long syscall_arg_t; 10 | #endif 11 | 12 | #define __syscall1(n, a) __syscall1(n, __scc(a)) 13 | #define __syscall2(n, a, b) __syscall2(n, __scc(a), __scc(b)) 14 | #define __syscall3(n, a, b, c) __syscall3(n, __scc(a), __scc(b), __scc(c)) 15 | #define __syscall4(n, a, b, c, d) __syscall4(n, __scc(a), __scc(b), __scc(c), __scc(d)) 16 | #define __syscall5(n, a, b, c, d, e) __syscall5(n, __scc(a), __scc(b), __scc(c), __scc(d), __scc(e)) 17 | #define __syscall6(n, a, b, c, d, e, f) __syscall6(n, __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) 18 | 19 | #define __SYSCALL_NARGS_X(a, b, c, d, e, f, g, h, n, ...) n 20 | #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, ) 21 | #define __SYSCALL_CONCAT_X(a, b) a##b 22 | #define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b) 23 | #define __SYSCALL_DISP(b, ...) \ 24 | __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__)) \ 25 | (__VA_ARGS__) 26 | 27 | #define __syscall(...) __SYSCALL_DISP(__syscall, __VA_ARGS__) 28 | #define syscall(...) __syscall(__VA_ARGS__) 29 | 30 | #endif // __SYSCALL_H 31 | -------------------------------------------------------------------------------- /user_C_program/user/riscv64: -------------------------------------------------------------------------------- 1 | build/riscv64/ -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/brk.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | 7 | /* 8 | * 测试通过时应输出: 9 | * "Before alloc,heap pos: [num]" 10 | * "After alloc,heap pos: [num+64]" 11 | * "Alloc again,heap pos: [num+128]" 12 | * 13 | * Linux 中brk(0)只返回0,此处与Linux表现不同,应特殊说明。 14 | */ 15 | void test_brk(){ 16 | TEST_START(__func__); 17 | intptr_t cur_pos, alloc_pos, alloc_pos_1; 18 | 19 | cur_pos = brk(0); 20 | printf("Before alloc,heap pos: %d\n", cur_pos); 21 | brk(cur_pos + 64); 22 | alloc_pos = brk(0); 23 | printf("After alloc,heap pos: %d\n",alloc_pos); 24 | brk(alloc_pos + 64); 25 | alloc_pos_1 = brk(0); 26 | printf("Alloc again,heap pos: %d\n",alloc_pos_1); 27 | TEST_END(__func__); 28 | } 29 | 30 | int main(void) { 31 | test_brk(); 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/brk_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class brk_test(TestBase): 6 | def __init__(self): 7 | super().__init__("brk", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | p1 = "Before alloc,heap pos: (.+)" 12 | p2 = "After alloc,heap pos: (.+)" 13 | p3 = "Alloc again,heap pos: (.+)" 14 | line1 = re.findall(p1, data[0]) 15 | line2 = re.findall(p2, data[1]) 16 | line3 = re.findall(p3, data[2]) 17 | if line1 == [] or line2 == [] or line3 == []: 18 | return 19 | a1 = int(line1[0], 10) 20 | a2 = int(line2[0], 10) 21 | a3 = int(line3[0], 10) 22 | self.assert_equal(a1 + 64, a2) 23 | self.assert_equal(a2 + 64, a3) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/build-single-testcase.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | elf=$1 4 | 5 | riscv64-unknown-elf-gcc -I../../include -march=rv64imac -mabi=lp64 -mcmodel=medany -fno-builtin -nostdinc -fno-stack-protector -ggdb -Wall -O3 -DNDEBUG -nostdlib -T ../../lib/arch/riscv/user.ld -Ttext 0x1000 $elf -o $elf.bin \ 6 | ../../build/libulib.a 7 | 8 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/chdir.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | static char buffer[30]; 6 | void test_chdir(void){ 7 | TEST_START(__func__); 8 | mkdir("test_chdir", 0666); 9 | int ret = chdir("test_chdir"); 10 | printf("chdir ret: %d\n", ret); 11 | assert(ret == 0); 12 | getcwd(buffer, 30); 13 | printf(" current working dir : %s\n", buffer); 14 | TEST_END(__func__); 15 | } 16 | 17 | int main(void){ 18 | test_chdir(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/chdir_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class chdir_test(TestBase): 6 | def __init__(self): 7 | super().__init__("chdir", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | p1 = r"chdir ret: (\d)+" 12 | r1 = re.findall(p1, data[0]) 13 | if r1: 14 | self.assert_equal(r1[0], "0") 15 | self.assert_in("test_chdir", data[1]) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/clone.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | size_t stack[1024] = {0}; 6 | static int child_pid; 7 | 8 | static int child_func(void){ 9 | printf(" Child says successfully!\n"); 10 | return 0; 11 | } 12 | 13 | void test_clone(void){ 14 | TEST_START(__func__); 15 | int wstatus; 16 | child_pid = clone(child_func, NULL, stack, 1024, SIGCHLD); 17 | assert(child_pid != -1); 18 | if (child_pid == 0){ 19 | exit(0); 20 | }else{ 21 | if(wait(&wstatus) == child_pid) 22 | printf("clone process successfully.\npid:%d\n", child_pid); 23 | else 24 | printf("clone process error.\n"); 25 | } 26 | 27 | TEST_END(__func__); 28 | } 29 | 30 | int main(void){ 31 | test_clone(); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/clone.s: -------------------------------------------------------------------------------- 1 | # __clone(func, stack, flags, arg, ptid, tls, ctid) 2 | # a0, a1, a2, a3, a4, a5, a6 3 | 4 | # syscall(SYS_clone, flags, stack, ptid, tls, ctid) 5 | # a7 a0, a1, a2, a3, a4 6 | 7 | .global __clone 8 | .type __clone, %function 9 | __clone: 10 | # Save func and arg to stack 11 | addi a1, a1, -16 12 | sd a0, 0(a1) 13 | sd a3, 8(a1) 14 | 15 | # Call SYS_clone 16 | mv a0, a2 17 | mv a2, a4 18 | mv a3, a5 19 | mv a4, a6 20 | li a7, 220 # SYS_clone 21 | ecall 22 | 23 | beqz a0, 1f 24 | # Parent 25 | ret 26 | 27 | # Child 28 | 1: ld a1, 0(sp) 29 | ld a0, 8(sp) 30 | jalr a1 31 | 32 | # Exit 33 | li a7, 93 # SYS_exit 34 | ecall 35 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/clone_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class clone_test(TestBase): 6 | def __init__(self): 7 | super().__init__("clone", 4) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | self.assert_in_str(" Child says successfully!", data) 12 | self.assert_in_str("pid:\d+", data) 13 | self.assert_in_str("clone process successfully.", data) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/close.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | /* 7 | * 测试成功则输出: 8 | * " close success." 9 | * 测试失败则输出: 10 | * " close error." 11 | */ 12 | 13 | void test_close(void) { 14 | TEST_START(__func__); 15 | int fd = open("test_close.txt", O_CREATE | O_RDWR); 16 | //assert(fd > 0); 17 | const char *str = " close error.\n"; 18 | int str_len = strlen(str); 19 | //assert(write(fd, str, str_len) == str_len); 20 | write(fd, str, str_len); 21 | int rt = close(fd); 22 | assert(rt == 0); 23 | printf(" close %d success.\n", fd); 24 | 25 | TEST_END(__func__); 26 | } 27 | 28 | int main(void) { 29 | test_close(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/close_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class close_test(TestBase): 6 | def __init__(self): 7 | super().__init__("close", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_in_str(" close \d+ success.", data) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/dup.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | /* 6 | * 测试通过时应输出: 7 | * " new fd is 3." 8 | */ 9 | 10 | void test_dup(){ 11 | TEST_START(__func__); 12 | int fd = dup(STDOUT); 13 | assert(fd >=0); 14 | printf(" new fd is %d.\n", fd); 15 | TEST_END(__func__); 16 | } 17 | 18 | int main(void) { 19 | test_dup(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/dup2.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | /* 7 | * 测试通过时应输出: 8 | * " from fd 100" 9 | */ 10 | void test_dup2(){ 11 | TEST_START(__func__); 12 | int fd = dup2(STDOUT, 100); 13 | assert(fd != -1); 14 | const char *str = " from fd 100\n"; 15 | write(100, str, strlen(str)); 16 | TEST_END(__func__); 17 | } 18 | 19 | int main(void) { 20 | test_dup2(); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/dup2_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class dup2_test(TestBase): 6 | def __init__(self): 7 | super().__init__("dup2", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_equal(" from fd 100", data[0]) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/dup_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class dup_test(TestBase): 6 | def __init__(self): 7 | super().__init__("dup", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | res = re.findall(" new fd is (\d+).", data[0]) 12 | if res: 13 | new_fd = int(res[0]) 14 | self.assert_not_equal(new_fd, 1) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/execve.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | /* 6 | * 测试成功则输出: 7 | * " I am test_echo." 8 | * 测试失败则输出: 9 | * " execve error." 10 | */ 11 | void test_execve(void){ 12 | TEST_START(__func__); 13 | char *newargv[] = {"test_echo", NULL}; 14 | char *newenviron[] = {NULL}; 15 | execve("test_echo", newargv, newenviron); 16 | printf(" execve error.\n"); 17 | //TEST_END(__func__); 18 | } 19 | 20 | int main(void){ 21 | test_execve(); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/execve_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class execve_test(TestBase): 6 | def __init__(self): 7 | super().__init__("execve", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_equal(" I am test_echo.", data[0]) 12 | self.assert_equal("execve success.", data[1]) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/exit.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | /* 6 | * 测试成功则输出: 7 | * "exit OK." 8 | * 测试失败则输出: 9 | * "exit ERR." 10 | */ 11 | void test_exit(void){ 12 | TEST_START(__func__); 13 | int cpid, waitret, wstatus; 14 | cpid = fork(); 15 | assert(cpid != -1); 16 | if(cpid == 0){ 17 | exit(0); 18 | }else{ 19 | waitret = wait(&wstatus); 20 | if(waitret == cpid) printf("exit OK.\n"); 21 | else printf("exit ERR.\n"); 22 | } 23 | TEST_END(__func__); 24 | } 25 | 26 | int main(void){ 27 | test_exit(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/exit_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class exit_test(TestBase): 6 | def __init__(self): 7 | super().__init__("exit", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_equal("exit OK.", data[0]) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/fork.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | #include "string.h" 5 | /* 6 | * 成功测试时父进程的输出: 7 | * " parent process." 8 | * 成功测试时子进程的输出: 9 | * " child process." 10 | */ 11 | static int fd[2]; 12 | 13 | void test_fork(void){ 14 | TEST_START(__func__); 15 | int cpid, wstatus; 16 | cpid = fork(); 17 | assert(cpid != -1); 18 | 19 | if(cpid > 0){ 20 | wait(&wstatus); 21 | printf(" parent process. wstatus:%d\n", wstatus); 22 | }else{ 23 | printf(" child process.\n"); 24 | exit(0); 25 | } 26 | TEST_END(__func__); 27 | } 28 | 29 | int main(void){ 30 | test_fork(); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/fork_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class fork_test(TestBase): 6 | def __init__(self): 7 | super().__init__("fork", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_in_str(" parent process\. wstatus:\d+", data) 12 | self.assert_in_str(" child process", data) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/fstat.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "stddef.h" 5 | 6 | #define AT_FDCWD (-100) //相对路径 7 | 8 | //Stat *kst; 9 | static struct kstat kst; 10 | void test_fstat() { 11 | TEST_START(__func__); 12 | int fd = open("./text.txt", 0); 13 | int ret = fstat(fd, &kst); 14 | printf("fstat ret: %d\n", ret); 15 | assert(ret >= 0); 16 | 17 | printf("fstat: dev: %d, inode: %d, mode: %d, nlink: %d, size: %d, atime: %d, mtime: %d, ctime: %d\n", 18 | kst.st_dev, kst.st_ino, kst.st_mode, kst.st_nlink, kst.st_size, kst.st_atime_sec, kst.st_mtime_sec, kst.st_ctime_sec); 19 | 20 | TEST_END(__func__); 21 | } 22 | 23 | int main(void) { 24 | test_fstat(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/fstat_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class fstat_test(TestBase): 6 | def __init__(self): 7 | super().__init__("fstat", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | res = re.findall("fstat ret: (\d+)", data[0]) 12 | if res: 13 | self.assert_equal(res[0], "0") 14 | res = re.findall(r"fstat: dev: \d+, inode: \d+, mode: (\d+), nlink: (\d+), size: \d+, atime: \d+, mtime: \d+, ctime: \d+", data[1]) 15 | if res: 16 | self.assert_equal(res[0][1], "1") -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getcwd.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | #include "string.h" 5 | 6 | /* 7 | * 测试通过时输出: 8 | * "getcwd OK." 9 | * 测试失败时输出: 10 | * "getcwd ERROR." 11 | */ 12 | void test_getcwd(void){ 13 | TEST_START(__func__); 14 | char *cwd = NULL; 15 | char buf[128] = {0}; 16 | cwd = getcwd(buf, 128); 17 | if(cwd != NULL) printf("getcwd: %s successfully!\n", buf); 18 | else printf("getcwd ERROR.\n"); 19 | TEST_END(__func__); 20 | } 21 | 22 | int main(void){ 23 | test_getcwd(); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getcwd_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class getcwd_test(TestBase): 6 | def __init__(self): 7 | super().__init__("getcwd", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_in_str("getcwd: (.+) successfully!", data) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getdents.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | char buf[512]; 6 | void test_getdents(void){ 7 | TEST_START(__func__); 8 | int fd, nread; 9 | struct linux_dirent64 *dirp64; 10 | dirp64 = buf; 11 | //fd = open(".", O_DIRECTORY); 12 | fd = open(".", O_RDONLY); 13 | printf("open fd:%d\n", fd); 14 | 15 | nread = getdents(fd, dirp64, 512); 16 | printf("getdents fd:%d\n", nread); 17 | assert(nread != -1); 18 | printf("getdents success.\n%s\n", dirp64->d_name); 19 | 20 | /* 21 | for(int bpos = 0; bpos < nread;){ 22 | d = (struct dirent *)(buf + bpos); 23 | printf( "%s\t", d->d_name); 24 | bpos += d->d_reclen; 25 | } 26 | */ 27 | 28 | printf("\n"); 29 | close(fd); 30 | TEST_END(__func__); 31 | } 32 | 33 | int main(void){ 34 | test_getdents(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getdents_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class getdents_test(TestBase): 6 | def __init__(self): 7 | super().__init__("getdents", 5) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 4) 11 | r = re.findall(r"open fd:(\d+)", data[0]) 12 | if r: 13 | self.assert_great(int(r[0]), 1) 14 | r = re.findall(r"getdents fd:(\d+)", data[1]) 15 | if r: 16 | self.assert_great(int(r[0]), 1) 17 | self.assert_equal("getdents success.", data[2]) 18 | self.assert_ge(len(data[3]), 1) 19 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getpid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | 理想结果:得到进程 pid,注意要关注 pid 是否符合内核逻辑,不要单纯以 Test OK! 作为判断。 7 | */ 8 | 9 | int test_getpid() 10 | { 11 | TEST_START(__func__); 12 | int pid = getpid(); 13 | assert(pid >= 0); 14 | printf("getpid success.\npid = %d\n", pid); 15 | TEST_END(__func__); 16 | } 17 | 18 | int main(void) { 19 | test_getpid(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getpid_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class getpid_test(TestBase): 6 | def __init__(self): 7 | super().__init__("getpid", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_equal(data[0], "getpid success.") 12 | r = re.findall(r"pid = (\d+)", data[1]) 13 | if r: 14 | self.assert_great(int(r[0]), 0) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getppid.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "unistd.h" 3 | #include "stdlib.h" 4 | 5 | /* 6 | * 能通过测试则输出: 7 | * " getppid success. ppid : [num]" 8 | * 不能通过测试则输出: 9 | * " getppid error." 10 | */ 11 | 12 | int test_getppid() 13 | { 14 | TEST_START(__func__); 15 | pid_t ppid = getppid(); 16 | if(ppid > 0) printf(" getppid success. ppid : %d\n", ppid); 17 | else printf(" getppid error.\n"); 18 | TEST_END(__func__); 19 | } 20 | 21 | int main(void) { 22 | test_getppid(); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/getppid_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class getppid_test(TestBase): 6 | def __init__(self): 7 | super().__init__("getppid", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_in(" getppid success. ppid : ", data[0]) 12 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/gettimeofday.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | /* 6 | * 测试通过时的输出: 7 | * "gettimeofday success." 8 | * "start:[num], end:[num]" 9 | * "interval: [num]" 注:数字[num]的值应大于0 10 | * 测试失败时的输出: 11 | * "gettimeofday error." 12 | */ 13 | void test_gettimeofday() { 14 | TEST_START(__func__); 15 | int test_ret1 = get_time(); 16 | volatile int i = 12500000; // qemu时钟频率12500000 17 | while(i > 0) i--; 18 | int test_ret2 = get_time(); 19 | if(test_ret1 > 0 && test_ret2 > 0){ 20 | printf("gettimeofday success.\n"); 21 | printf("start:%d, end:%d\n", test_ret1, test_ret2); 22 | printf("interval: %d\n", test_ret2 - test_ret1); 23 | }else{ 24 | printf("gettimeofday error.\n"); 25 | } 26 | TEST_END(__func__); 27 | } 28 | 29 | int main(void) { 30 | test_gettimeofday(); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/gettimeofday_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class gettimeofday_test(TestBase): 6 | def __init__(self): 7 | super().__init__("gettimeofday", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | self.assert_equal("gettimeofday success.", data[0]) 12 | res = re.findall(r"interval: (\d+)", data[2]) 13 | if res: 14 | self.assert_great(int(res[0]), 0) -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/mkdir_.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | void test_mkdir(void){ 6 | TEST_START(__func__); 7 | int rt, fd; 8 | 9 | rt = mkdir("test_mkdir", 0666); 10 | printf("mkdir ret: %d\n", rt); 11 | assert(rt != -1); 12 | fd = open("test_mkdir", O_RDONLY | O_DIRECTORY); 13 | if(fd > 0){ 14 | printf(" mkdir success.\n"); 15 | close(fd); 16 | } 17 | else printf(" mkdir error.\n"); 18 | TEST_END(__func__); 19 | } 20 | 21 | int main(void){ 22 | test_mkdir(); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/mkdir_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class mkdir_test(TestBase): 6 | def __init__(self): 7 | super().__init__("mkdir", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_in("mkdir ret:", data[0]) 12 | self.assert_in(" mkdir success.", data[1]) 13 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/mmap.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "string.h" 3 | #include "stdio.h" 4 | #include "stdlib.h" 5 | 6 | /* 7 | * 测试成功时输出: 8 | * " Hello, mmap success" 9 | * 测试失败时输出: 10 | * "mmap error." 11 | */ 12 | static struct kstat kst; 13 | void test_mmap(void){ 14 | TEST_START(__func__); 15 | char *array; 16 | const char *str = " Hello, mmap successfully!"; 17 | int fd; 18 | 19 | fd = open("test_mmap.txt", O_RDWR | O_CREATE); 20 | write(fd, str, strlen(str)); 21 | fstat(fd, &kst); 22 | printf("file len: %d\n", kst.st_size); 23 | array = mmap(NULL, kst.st_size, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); 24 | //printf("return array: %x\n", array); 25 | 26 | if (array == MAP_FAILED) { 27 | printf("mmap error.\n"); 28 | }else{ 29 | printf("mmap content: %s\n", array); 30 | //printf("%s\n", str); 31 | 32 | munmap(array, kst.st_size); 33 | } 34 | 35 | close(fd); 36 | 37 | TEST_END(__func__); 38 | } 39 | 40 | int main(void){ 41 | test_mmap(); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/mmap_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class mmap_test(TestBase): 6 | def __init__(self): 7 | super().__init__("mmap", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | r = re.findall(r"file len: (\d+)", data[0]) 12 | if r: 13 | self.assert_ge(int(r[0]), 27) 14 | self.assert_equal("mmap content: Hello, mmap successfully!", data[1]) 15 | 16 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/mount.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | //#define MNTPOINT "./mnt" 7 | 8 | static char mntpoint[64] = "./mnt"; 9 | static char device[64] = "/dev/vda2"; 10 | static const char *fs_type = "vfat"; 11 | 12 | void test_mount() { 13 | TEST_START(__func__); 14 | 15 | printf("Mounting dev:%s to %s\n", device, mntpoint); 16 | int ret = mount(device, mntpoint, fs_type, 0, NULL); 17 | printf("mount return: %d\n", ret); 18 | assert(ret == 0); 19 | 20 | if (ret == 0) { 21 | printf("mount successfully\n"); 22 | ret = umount(mntpoint); 23 | printf("umount return: %d\n", ret); 24 | } 25 | 26 | TEST_END(__func__); 27 | } 28 | 29 | int main(int argc,char *argv[]) { 30 | if(argc >= 2){ 31 | strcpy(device, argv[1]); 32 | } 33 | 34 | if(argc >= 3){ 35 | strcpy(mntpoint, argv[2]); 36 | } 37 | 38 | test_mount(); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/mount_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class mount_test(TestBase): 6 | def __init__(self): 7 | super().__init__("mount", 5) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 4) 11 | self.assert_equal(data[0], "Mounting dev:/dev/vda2 to ./mnt") 12 | self.assert_equal(data[1], "mount return: 0") 13 | self.assert_equal(data[2], "mount successfully") 14 | self.assert_equal(data[3], "umount return: 0") 15 | 16 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/munmap.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "string.h" 3 | #include "stdio.h" 4 | #include "stdlib.h" 5 | 6 | /* 7 | * 测试成功时输出: 8 | * " Hello, mmap success" 9 | * 测试失败时输出: 10 | * "mmap error." 11 | */ 12 | static struct kstat kst; 13 | void test_munmap(void){ 14 | TEST_START(__func__); 15 | char *array; 16 | const char *str = " Hello, mmap successfully!"; 17 | int fd; 18 | 19 | fd = open("test_mmap.txt", O_RDWR | O_CREATE); 20 | write(fd, str, strlen(str)); 21 | fstat(fd, &kst); 22 | printf("file len: %d\n", kst.st_size); 23 | array = mmap(NULL, kst.st_size, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); 24 | //printf("return array: %x\n", array); 25 | 26 | if (array == MAP_FAILED) { 27 | printf("mmap error.\n"); 28 | }else{ 29 | //printf("mmap content: %s\n", array); 30 | 31 | int ret = munmap(array, kst.st_size); 32 | printf("munmap return: %d\n",ret); 33 | assert(ret == 0); 34 | 35 | if (ret == 0) 36 | printf("munmap successfully!\n"); 37 | } 38 | close(fd); 39 | 40 | TEST_END(__func__); 41 | } 42 | 43 | int main(void){ 44 | test_munmap(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/munmap_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class munmap_test(TestBase): 6 | def __init__(self): 7 | super().__init__("munmap", 4) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | r = re.findall(r"file len: (\d+)", data[0]) 12 | if r: 13 | self.assert_ge(int(r[0]), 27) 14 | self.assert_equal(data[1], "munmap return: 0") 15 | self.assert_equal(data[2], "munmap successfully!") 16 | 17 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/open.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | void test_open() { 6 | TEST_START(__func__); 7 | // O_RDONLY = 0, O_WRONLY = 1 8 | int fd = open("./text.txt", 0); 9 | assert(fd >= 0); 10 | char buf[256]; 11 | int size = read(fd, buf, 256); 12 | if (size < 0) { 13 | size = 0; 14 | } 15 | write(STDOUT, buf, size); 16 | close(fd); 17 | TEST_END(__func__); 18 | } 19 | 20 | int main(void) { 21 | test_open(); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/open_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class open_test(TestBase): 6 | def __init__(self): 7 | super().__init__("open", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_equal("Hi, this is a text file.", data[0]) 12 | self.assert_equal("syscalls testing success!", data[1]) 13 | 14 | 15 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/openat.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | void test_openat(void) { 6 | TEST_START(__func__); 7 | //int fd_dir = open(".", O_RDONLY | O_CREATE); 8 | int fd_dir = open("./mnt", O_DIRECTORY); 9 | printf("open dir fd: %d\n", fd_dir); 10 | int fd = openat(fd_dir, "test_openat.txt", O_CREATE | O_RDWR); 11 | printf("openat fd: %d\n", fd); 12 | assert(fd > 0); 13 | printf("openat success.\n"); 14 | 15 | /*( 16 | char buf[256] = "openat text file"; 17 | write(fd, buf, strlen(buf)); 18 | int size = read(fd, buf, 256); 19 | if (size > 0) printf(" openat success.\n"); 20 | else printf(" openat error.\n"); 21 | */ 22 | close(fd); 23 | 24 | TEST_END(__func__); 25 | } 26 | 27 | int main(void) { 28 | test_openat(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/openat_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class openat_test(TestBase): 6 | def __init__(self): 7 | super().__init__("openat", 4) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | r = re.findall(r"open dir fd: (\d+)", data[0]) 12 | if r: 13 | self.assert_great(int(r[0]), 1) 14 | r1 = re.findall(r"openat fd: (\d+)", data[1]) 15 | if r1: 16 | self.assert_great(int(r1[0]), int(r[0])) 17 | self.assert_equal(data[2], "openat success.") 18 | 19 | 20 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/pipe.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | #include "string.h" 5 | /* 6 | * 成功测试时的输出: 7 | * " Write to pipe successfully." 8 | */ 9 | static int fd[2]; 10 | 11 | void test_pipe(void){ 12 | TEST_START(__func__); 13 | int cpid; 14 | char buf[128] = {0}; 15 | int ret = pipe(fd); 16 | assert(ret != -1); 17 | const char *data = " Write to pipe successfully.\n"; 18 | cpid = fork(); 19 | printf("cpid: %d\n", cpid); 20 | if(cpid > 0){ 21 | close(fd[1]); 22 | while(read(fd[0], buf, 1) > 0) 23 | write(STDOUT, buf, 1); 24 | write(STDOUT, "\n", 1); 25 | close(fd[0]); 26 | wait(NULL); 27 | }else{ 28 | close(fd[0]); 29 | write(fd[1], data, strlen(data)); 30 | close(fd[1]); 31 | exit(0); 32 | } 33 | TEST_END(__func__); 34 | } 35 | 36 | int main(void){ 37 | test_pipe(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/pipe_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class pipe_test(TestBase): 6 | def __init__(self): 7 | super().__init__("pipe", 4) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | cpid0 = False 12 | cpid1 = False 13 | for line in data[:3]: 14 | if line == "cpid: 0": 15 | cpid0 = True 16 | continue 17 | r = re.findall(r"cpid: (\d+)", line) 18 | if r and int(r[0]) > 0: 19 | cpid1 = True 20 | continue 21 | self.assert_equal(cpid0, True) 22 | self.assert_equal(cpid1, True) 23 | self.assert_equal(data[2], " Write to pipe successfully.") 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/read.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | void test_read() { 6 | TEST_START(__func__); 7 | int fd = open("./text.txt", 0); 8 | char buf[256]; 9 | int size = read(fd, buf, 256); 10 | assert(size >= 0); 11 | 12 | write(STDOUT, buf, size); 13 | close(fd); 14 | TEST_END(__func__); 15 | } 16 | 17 | int main(void) { 18 | test_read(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/read_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class read_test(TestBase): 6 | def __init__(self): 7 | super().__init__("read", 3) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_equal("Hi, this is a text file.", data[0]) 12 | self.assert_equal("syscalls testing success!", data[1]) 13 | 14 | 15 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/run-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tests=" 4 | brk 5 | chdir 6 | clone 7 | close 8 | dup2 9 | dup 10 | execve 11 | exit 12 | fork 13 | fstat 14 | getcwd 15 | getdents 16 | getpid 17 | getppid 18 | gettimeofday 19 | mkdir_ 20 | mmap 21 | mount 22 | munmap 23 | openat 24 | open 25 | pipe 26 | read 27 | times 28 | umount 29 | uname 30 | unlink 31 | wait 32 | waitpid 33 | write 34 | yield.sh 35 | " 36 | for i in $tests 37 | do 38 | echo "Testing $i :" 39 | ./$i 40 | done 41 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/sleep.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | /* 6 | * 测试通过时的输出: 7 | * "sleep success." 8 | * 测试失败时的输出: 9 | * "sleep error." 10 | */ 11 | void test_sleep() { 12 | TEST_START(__func__); 13 | 14 | int time1 = get_time(); 15 | assert(time1 >= 0); 16 | int ret = sleep(1); 17 | assert(ret == 0); 18 | int time2 = get_time(); 19 | assert(time2 >= 0); 20 | 21 | if(time2 - time1 >= 1){ 22 | printf("sleep success.\n"); 23 | }else{ 24 | printf("sleep error.\n"); 25 | } 26 | TEST_END(__func__); 27 | } 28 | 29 | int main(void) { 30 | test_sleep(); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/test_echo.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | 3 | /* 4 | * for execve 5 | */ 6 | 7 | int main(int argc, char *argv[]){ 8 | printf(" I am test_echo.\nexecve success.\n"); 9 | TEST_END(__func__); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/text.txt: -------------------------------------------------------------------------------- 1 | Hi, this is a text file. 2 | syscalls testing success! 3 | 4 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/times.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | 5 | struct tms 6 | { 7 | long tms_utime; 8 | long tms_stime; 9 | long tms_cutime; 10 | long tms_cstime; 11 | }; 12 | 13 | struct tms mytimes; 14 | 15 | void test_times() { 16 | TEST_START(__func__); 17 | 18 | int test_ret = times(&mytimes); 19 | assert(test_ret >= 0); 20 | 21 | printf("mytimes success\n{tms_utime:%d, tms_stime:%d, tms_cutime:%d, tms_cstime:%d}\n", 22 | mytimes.tms_utime, mytimes.tms_stime, mytimes.tms_cutime, mytimes.tms_cstime); 23 | TEST_END(__func__); 24 | } 25 | 26 | int main(void) { 27 | test_times(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/times_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class times_test(TestBase): 6 | def __init__(self): 7 | super().__init__("times", 6) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 2) 11 | self.assert_equal(data[0], "mytimes success") 12 | r = re.findall(r"\{tms_utime:(.+), tms_stime:(.+), tms_cutime:(.+), tms_cstime:(.+)}", data[1]) 13 | if r: 14 | self.assert_ge(int(r[0][0]), 0) 15 | self.assert_ge(int(r[0][1]), 0) 16 | self.assert_ge(int(r[0][2]), 0) 17 | self.assert_ge(int(r[0][3]), 0) 18 | 19 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/umount.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | //#define MNTPOINT "./mnt" 7 | 8 | static char mntpoint[64] = "./mnt"; 9 | static char device[64] = "/dev/vda2"; 10 | static const char *fs_type = "vfat"; 11 | 12 | void test_umount() { 13 | TEST_START(__func__); 14 | 15 | printf("Mounting dev:%s to %s\n", device, mntpoint); 16 | int ret = mount(device, mntpoint, fs_type, 0, NULL); 17 | printf("mount return: %d\n", ret); 18 | 19 | if (ret == 0) { 20 | ret = umount(mntpoint); 21 | assert(ret == 0); 22 | printf("umount success.\nreturn: %d\n", ret); 23 | } 24 | 25 | TEST_END(__func__); 26 | } 27 | 28 | int main(int argc,char *argv[]) { 29 | if(argc >= 2){ 30 | strcpy(device, argv[1]); 31 | } 32 | 33 | if(argc >= 3){ 34 | strcpy(mntpoint, argv[2]); 35 | } 36 | 37 | test_umount(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/umount_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class umount_test(TestBase): 6 | def __init__(self): 7 | super().__init__("umount", 5) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 4) 11 | self.assert_equal(data[0], "Mounting dev:/dev/vda2 to ./mnt") 12 | self.assert_equal("mount return: 0", data[1]) 13 | self.assert_equal("umount success.", data[2]) 14 | self.assert_equal("return: 0", data[3]) 15 | 16 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/uname.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | struct utsname { 7 | char sysname[65]; 8 | char nodename[65]; 9 | char release[65]; 10 | char version[65]; 11 | char machine[65]; 12 | char domainname[65]; 13 | }; 14 | 15 | struct utsname un; 16 | 17 | void test_uname() { 18 | TEST_START(__func__); 19 | int test_ret = uname(&un); 20 | assert(test_ret >= 0); 21 | 22 | printf("Uname: %s %s %s %s %s %s\n", 23 | un.sysname, un.nodename, un.release, un.version, un.machine, un.domainname); 24 | 25 | TEST_END(__func__); 26 | } 27 | 28 | int main(void) { 29 | test_uname(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/uname_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class uname_test(TestBase): 6 | def __init__(self): 7 | super().__init__("uname", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_in("Uname: ", data[0]) 12 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/unlink.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* 测试 unlink 8 | * 测试通过,应有如下输出: 9 | * " unlink success!" 10 | * 测试失败,应有如下输出: 11 | * " unlink error!" 12 | */ 13 | 14 | int test_unlink() 15 | { 16 | TEST_START(__func__); 17 | 18 | char *fname = "./test_unlink"; 19 | int fd, ret; 20 | 21 | fd = open(fname, O_CREATE | O_WRONLY); 22 | assert(fd > 0); 23 | close(fd); 24 | 25 | // unlink test 26 | ret = unlink(fname); 27 | assert(ret == 0); 28 | fd = open(fname, O_RDONLY); 29 | if(fd < 0){ 30 | printf(" unlink success!\n"); 31 | }else{ 32 | printf(" unlink error!\n"); 33 | close(fd); 34 | } 35 | // It's Ok if you don't delete the inode and data blocks. 36 | 37 | TEST_END(__func__); 38 | } 39 | 40 | int main(void) { 41 | test_unlink(); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/unlink_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class unlink_test(TestBase): 6 | def __init__(self): 7 | super().__init__("unlink", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_equal(data[0], " unlink success!") 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/wait.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | void test_wait(void){ 6 | TEST_START(__func__); 7 | int cpid, wstatus; 8 | cpid = fork(); 9 | if(cpid == 0){ 10 | printf("This is child process\n"); 11 | exit(0); 12 | }else{ 13 | pid_t ret = wait(&wstatus); 14 | assert(ret != -1); 15 | if(ret == cpid) 16 | printf("wait child success.\nwstatus: %d\n", wstatus); 17 | else 18 | printf("wait child error.\n"); 19 | } 20 | TEST_END(__func__); 21 | } 22 | 23 | int main(void){ 24 | test_wait(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/wait_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class wait_test(TestBase): 6 | def __init__(self): 7 | super().__init__("wait", 4) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | self.assert_equal(data[0], "This is child process") 12 | self.assert_equal(data[1], "wait child success.") 13 | self.assert_equal(data[2], "wstatus: 0") 14 | 15 | 16 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/waitpid.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "stdlib.h" 3 | #include "unistd.h" 4 | 5 | int i = 1000; 6 | void test_waitpid(void){ 7 | TEST_START(__func__); 8 | int cpid, wstatus; 9 | cpid = fork(); 10 | assert(cpid != -1); 11 | if(cpid == 0){ 12 | while(i--); 13 | sched_yield(); 14 | printf("This is child process\n"); 15 | exit(3); 16 | }else{ 17 | pid_t ret = waitpid(cpid, &wstatus, 0); 18 | assert(ret != -1); 19 | if(ret == cpid && WEXITSTATUS(wstatus) == 3) 20 | printf("waitpid successfully.\nwstatus: %x\n", WEXITSTATUS(wstatus)); 21 | else{ 22 | printf("waitpid error.\nret: %x, cpid: %x, wstatus: %x\n", ret, cpid, wstatus); 23 | } 24 | } 25 | TEST_END(__func__); 26 | } 27 | 28 | int main(void){ 29 | test_waitpid(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/waitpid_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class waitpid_test(TestBase): 6 | def __init__(self): 7 | super().__init__("waitpid", 4) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 3) 11 | self.assert_equal(data[0], "This is child process") 12 | self.assert_equal(data[1], "waitpid successfully.") 13 | self.assert_equal(data[2], "wstatus: 3") 14 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/write.c: -------------------------------------------------------------------------------- 1 | #include "unistd.h" 2 | #include "stdio.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | 6 | void test_write(){ 7 | TEST_START(__func__); 8 | const char *str = "Hello operating system contest.\n"; 9 | int str_len = strlen(str); 10 | assert(write(STDOUT, str, str_len) == str_len); 11 | TEST_END(__func__); 12 | } 13 | 14 | int main(void) { 15 | test_write(); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/write_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | 5 | class write_test(TestBase): 6 | def __init__(self): 7 | super().__init__("write", 2) 8 | 9 | def test(self, data): 10 | self.assert_ge(len(data), 1) 11 | self.assert_equal(data[0], "Hello operating system contest.") 12 | 13 | 14 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/yield.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | 理想结果:三个子进程交替输出 6 | */ 7 | 8 | int test_yield(){ 9 | TEST_START(__func__); 10 | 11 | for (int i = 0; i < 3; ++i){ 12 | if(fork() == 0){ 13 | for (int j = 0; j< 5; ++j){ 14 | sched_yield(); 15 | printf(" I am child process: %d. iteration %d.\n", getpid(), i); 16 | } 17 | exit(0); 18 | } 19 | } 20 | wait(NULL); 21 | wait(NULL); 22 | wait(NULL); 23 | TEST_END(__func__); 24 | } 25 | 26 | int main(void) { 27 | test_yield(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /user_C_program/user/src/oscomp/yield_test.py: -------------------------------------------------------------------------------- 1 | from test_base import TestBase 2 | import re 3 | 4 | class yield_test(TestBase): 5 | def __init__(self): 6 | super().__init__("yield", 4) 7 | 8 | def test(self, data): 9 | self.assert_equal(len(data), 15) 10 | lst = ''.join(data) 11 | cnt = {'0': 0, '1': 0, '2': 0, '3': 0, '4': 0} 12 | for c in lst: 13 | if c not in ('0', '1', '2', '3', '4'): 14 | continue 15 | cnt[c] += 1 16 | self.assert_ge(cnt['0'], 3) 17 | self.assert_ge(cnt['1'], 3) 18 | self.assert_ge(cnt['2'], 3) 19 | 20 | 21 | 22 | # BBBBBBBBBB [1/5] 23 | # CCCCCCCCCC [1/5] 24 | # BBBBBBBBBB [2/5] 25 | # CCCCCCCCCC [2/5] 26 | # AAAAAAAAAA [1/5] 27 | # CCCCCCCCCC [3/5] 28 | # BBBBBBBBBB [3/5] 29 | # AAAAAAAAAA [2/5] 30 | # BBBBBBBBBB [4/5] 31 | # CCCCCCCCCC [4/5] 32 | # AAAAAAAAAA [3/5] 33 | # BBBBBBBBBB [5/5] 34 | # CCCCCCCCCC [5/5] 35 | # AAAAAAAAAA [4/5] 36 | # AAAAAAAAAA [5/5] -------------------------------------------------------------------------------- /修改日志: -------------------------------------------------------------------------------- 1 | /*==============jarvis-user / 2022-3-18 17:10=================*/ 2 | 3 | 修改范围: 4 | 5 | 更新!:新增自旋锁功能 6 | 7 | 修改定位: 8 | toyos/src/sync/mod.rs 9 | toyos/src/sync/mutex.rs 10 | 11 | 接口声明: 12 | toyos/src/sync/mod.rs 13 | 14 | /*=============================================================*/ 15 | 16 | 17 | /*================jarvis-user / 2022-3-18 21:43================*/ 18 | 19 | 修改范围: 20 | 21 | 更新!:自旋锁可以用于包装自定义变量 22 | 23 | 修改定位: 24 | toyos/src/sync/mod.rs 25 | toyos/src/sync/mutex.rs 26 | toyos/src/sync/up.rs 27 | 28 | 接口声明: 29 | toyos/src/sync/mod.rs 30 | 31 | /*=============================================================*/ 32 | 33 | /*================jarvis-user / 2022-3-18 21:43================*/ 34 | 35 | 修改范围: 36 | 37 | 修改!:补充了memory、trap、task的接口说明,主要在memory、trap两部分做了详细补充 38 | 39 | /*=============================================================*/ 40 | 41 | /*================jarvis-user / 2022-4-21 15:06================*/ 42 | 43 | 修改范围: 44 | 45 | 新增!:补充了UserBuffer结构,主要是对vec<&'static mut [u8]>进行封装,包括new、len、iter、iter_mut四个函数, 46 | 其中iter与iter_mut主要是为了避免对userbuffer内部vec的直接访问,效果与Userbuffer.buffer.iter_mut效果相同 47 | 48 | /*=============================================================*/ 49 | --------------------------------------------------------------------------------