Skip to content

Commit

Permalink
Merge pull request #16 from diodesign/spike
Browse files Browse the repository at this point in the history
Support Spike's HTIF for console IO
  • Loading branch information
diodesign committed Mar 21, 2021
2 parents 68e035e + d277345 commit 406502c
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 10 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Note: you will be [billed](https://cloud.google.com/run/pricing) by Google for a

## Run Diosix from source in a container <a name="run"></a>

To build Diosix from source and boot it with a prebuilt guest OS within a Docker container on your own system, create a container image of the software:
To build Diosix from source and boot it within Qemu with a prebuilt guest OS within a Docker container on your own system, create a container image of the software:

```
git clone https://github.com/diodesign/diosix.git
Expand All @@ -84,7 +84,7 @@ As with Google Cloud Run, log into the provided guest Linux OS environment as `r

## Run Diosix from source without a container <a name="nocontainer"></a>

To build and run Diosix from its latest source code without using Docker, follow [these instructions](docs/running.md).
To build and run Diosix on real hardware, or within Qemu or Spike, from its latest source code without using Docker, follow [these instructions](docs/running.md).

## Frequently anticipated questions <a name="faq"></a> <a name="todo"></a>

Expand Down
35 changes: 35 additions & 0 deletions docs/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The outcome will booting one or more guest operating systems, such as Linux, on
1. [Getting started](#prep)
1. [Run Diosix in Qemu](#qemu)
1. [Using the system console](#console)
1. [Run Diosix in Spike](#spike)
1. [Run Diosix on real hardware](#realhw)
1. [Build without running](#buildonly)
1. [Options for building and running](#opts)
1. [Output build diagnostic messages](#opt_quiet)
Expand Down Expand Up @@ -69,6 +71,39 @@ By default, Diosix will run a system service called `gooey` that provides a very

Currently, `gooey` displays output text from all capsules, though when typing into it, either via Qemu or a real system's serial port, that input text is sent only to the first guest. The coloring of the input and output text can be temporarily altered by the guest, for example when listing files with `ls` and displaying executables in a special color. The exact colors seen may vary depending on the color scheme used by your terminal.

## Run Diosix in Spike <a name="spike"></a>

Once you have completed the [preparatory steps](#prep), run Diosix in the Spike RISC-V simulator:

```
just spike
```

Press `Control-c` to enter Spike's interactive debug mode. Instructions on how to use this mode are [here](https://github.com/riscv/riscv-isa-sim#interactive-debug-mode). Enter the command `q` or press `Control-c` again to quit the simulator from the debug mode. Note that support for Spike is not yet complete.

## Run Diosix on real hardware <a name="realhw"></a>

**Warning: Follow the next steps with care! The storage device specified below will be reformatted with a new GPT-based partitioning scheme, with the hypervisor and its dmfs image stored in partition 1. This will render any prior data on the device inaccessible. See [LICENSE](../LICENSE) for more information on the conditions and terms of use of this documentation**

Once you have completed the [preparatory steps](#prep), build Diosix and install it on an SD card or similar storage device for use in a physical system:

```
just disk=/dev/sdX install
```

Replace `/dev/sdX` with the path of the storage device you wish to install Diosix on. The installation process will require superuser privileges via `sudo`, and so your user account must be a `sudoer` for this just recipe to work. Once complete, the device can be used in a compatible computer. So far, this recipe supports:

* SiFive's [HiFive Unleashed](https://www.sifive.com/boards/hifive-unleashed). To run Diosix on this system:
1. Ensure the Unleashed board's boot mode switches are all set to `1`.
1. Insert a microSD card into the host building Diosix and run the above command, replacing `/dev/sdX` with the card's path to install the hypervisor to the card.
1. Remove the microSD card and insert it into the Unleashed board.
1. Connect the host to the Unleashed board's microUSB port via a suitable USB cable.
1. Power on or reset the Unleashed board.
1. Run the command `sudo screen /dev/ttyUSBX 115200` on the host to access the board's serial port console. You should replace `/dev/ttyUSBX` with the Unleashed's USB-to-serial interface. Typically, `X` is `1`.
1. You should see Diosix's output in the serial port console.

Note that support for real hardware is not yet complete.

## Build without running <a name="buildonly"></a>

To build Diosix without running the software:
Expand Down
42 changes: 34 additions & 8 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
# Build and run diosix in Qemu, using the defaults:
# just
#
# Build and run diosix in Spike, using the defaults:
# just spike
#
# Only build diosix using the defaults:
# just build
#
Expand All @@ -32,8 +35,14 @@
# Set target to the architecture you want to build for. Eg:
# just target=riscv64imac-unknown-none-elf
#
# Set emubin to the Qemu system emulator binary you want to use to run diosix, Eg:
# just emubin=qemu-system-riscv64
# Set qemubin to the path of the Qemu system emulator binary you want to use to run diosix, Eg:
# just qemubin=qemu-system-riscv64
#
# Set spikebin to the path of the Spike binary you want to use to run diosix, Eg:
# just spikebin=$HOME/src/riscv-isa-sim/build/spike
#
# Set spikeisa to the RISC-V ISA to use with Spike, eg:
# just spikeisa=RV64IMAC
#
# Set objcopybin to the objcopy suitable for the target architecture. Eg:
# just objcopybin=riscv64-linux-gnu-objcopy install
Expand All @@ -46,8 +55,8 @@
# Set to yes to only report warnings and errors. Eg:
# just quiet=no
# just quiet=yes
#
# Set cpus to the number of CPU cores to run within qemu, eg:
#
# Set cpus to the number of CPU cores to run within qemu and spike, eg:
# just cpus=1
#
# Force debug text output via Qemu's serial port by setting qemuprint to yes, eg:
Expand All @@ -56,6 +65,9 @@
# Force debug text output via SiFive's serial port by setting sifiveprint to yes, eg:
# just sifiveprint=yes
#
# Force debug text output via Spike's HTIF by setting htifprint to yes, eg:
# just htifprint=yes
#
# Disable hypervisor's regular integrity checks by setting integritychecks to no, eg:
# just integritychecks=no
#
Expand All @@ -72,13 +84,17 @@
# just guests-build=no
#
# The defaults are:
# emubin qemu-system-riscv64
# qemubin qemu-system-riscv64
# spikebin spike
# spikeisa RV64IMAFDC
# target riscv64gc-unknown-none-elf
# objcopybin riscv64-linux-gnu-objcopy
# quality debug
# quiet yes
# cpus 4
# qemuprint no
# sifiveprint no
# htifprint no
# integritychecks yes
# services yes
# guests yes
Expand All @@ -98,18 +114,22 @@ cleanmsg := msgprefix + "Cleaning build tree"
rustupmsg := msgprefix + "Ensuring Rust can build for"
builtmsg := msgprefix + "Diosix built and ready to use at"
qemumsg := msgprefix + "Running Diosix in Qemu"
spikemsg := msgprefix + "Running Diosix in Spike"
installmsg := msgprefix + "Installing"
installedmsg := msgprefix + "Diosix installed on disk"

# define defaults, these are overriden by the command line
target := "riscv64gc-unknown-none-elf"
emubin := "qemu-system-riscv64"
qemubin := "qemu-system-riscv64"
spikebin := "spike"
spikeisa := "RV64IMAFDC"
objcopybin := "riscv64-linux-gnu-objcopy"
quality := "debug"
quiet := "yes"
cpus := "4"
qemuprint := "no"
sifiveprint := "no"
htifprint := "no"
integritychecks := "yes"
services := "yes"
guests := "yes"
Expand All @@ -127,6 +147,7 @@ quiet_redir_sw := if quiet == "yes" { "> /dev/null " } else { "" }
verbose_sw := if quiet == "no" { "--verbose " } else { "" }
qemuprint_sw := if qemuprint == "yes" { "--features qemuprint" } else { "" }
sifiveprint_sw := if sifiveprint == "yes" { "--features sifiveprint" } else { "" }
htifprint_sw := if htifprint == "yes" { "--features htifprint" } else { "" }
cargo_sw := quiet_sw + release_sw + "--target " + target
integritychecks_sw := if integritychecks == "yes" { "--features integritychecks" } else { "" }
services_sw := if services == "no" { "--skip-services" } else { "" }
Expand All @@ -138,7 +159,12 @@ builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" }
# build diosix with its components, and run it within qemu
@qemu: build
echo "{{qemumsg}}"
{{emubin}} -bios none -nographic -machine virt -smp {{cpus}} -m 1G -kernel {{final-exe-path}}
{{qemubin}} -bios none -nographic -machine virt -smp {{cpus}} -m 1G -kernel {{final-exe-path}}

# build diosix, and run it within spike
@spike: build
echo "{{spikemsg}}"
{{spikebin}} --isa={{spikeisa}} -p{{cpus}} -m1024 {{final-exe-path}}

# build and install diosix with its components onto a disk (requires root via sudo)
@install: build
Expand All @@ -161,7 +187,7 @@ builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" }
# build the hypervisor and ensure it has a boot file system to include
@_hypervisor: _mkdmfs
echo "{{buildmsg}} hypervisor"
cd src/hypervisor && cargo build {{cargo_sw}} {{qemuprint_sw}} {{sifiveprint_sw}} {{integritychecks_sw}}
cd src/hypervisor && cargo build {{cargo_sw}} {{qemuprint_sw}} {{sifiveprint_sw}} {{htifprint_sw}} {{integritychecks_sw}}

# build and run the dmfs generator to include banners and system services.
# mkdmfs is configured by manifest.toml in the project root directory.
Expand Down
1 change: 1 addition & 0 deletions src/hypervisor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ serde_derive = "1.0.118"
[features]
qemuprint = [] # enable to force debug text through Qemu's serial port
sifiveprint = [] # enable to force debug text through SiFive's standard serial port
htifprint = [] # enable to force debug text through Spike's HTIF
integritychecks = [] # enable to check integrity of per-CPU structures from overwrites */

# local and special dependencies
Expand Down
8 changes: 8 additions & 0 deletions src/hypervisor/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ impl fmt::Write for ConsoleWriter
unsafe { *(tx_register as *mut u32) = *c as u32 };
}
}
else if cfg!(feature = "htifprint")
{
extern "C" { fn platform_write_to_htif(byte: u8); }
for c in s.as_bytes()
{
unsafe { platform_write_to_htif(*c) }
}
}
else
{
/* queue the output for printing out later when ready */
Expand Down
1 change: 1 addition & 0 deletions src/hypervisor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ fn hvmain(cpu_nr: PhysicalCoreID, dtb_ptr: *const u8, dtb_len: u32) -> Result<()
as such, only allow supervisor-mode capable CPU cores to build capasules */
if pcore::PhysicalCore::smode_supported() == true
{
/* only allow one core to do the unpacking */
let mut flag = MANIFEST_UNPACKED.lock();

if *flag == false
Expand Down

0 comments on commit 406502c

Please sign in to comment.