Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
bane9 committed May 5, 2023
1 parent 2160786 commit 715c8a5
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 104 deletions.
9 changes: 6 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 3.22.1)

cmake_minimum_required(VERSION 3.18.4)
project(rv64gc_emu)

if (USE_EMSCRIPTEN)
Expand Down Expand Up @@ -33,7 +32,7 @@ set(SRC_FILES_COMMON
source/peripherals/clint.cpp
source/peripherals/plic.cpp
source/peripherals/ram.cpp
source/peripherals/virtio_blk.cpp
source/peripherals/virtio.cpp

source/instructions/loadinsn.cpp
source/instructions/otherinsn.cpp
Expand Down Expand Up @@ -98,6 +97,10 @@ FetchContent_Declare(
FetchContent_MakeAvailable(fmt)

if (${NATIVE_CLI})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(rv64gc_emu PRIVATE Threads::Threads)

target_include_directories(rv64gc_emu PRIVATE ${INCLUDE_DIRS})

target_link_libraries(rv64gc_emu PRIVATE fmt::fmt)
Expand Down
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Welcome to the RV64GC Emulator repository, a RISC-V emulator project developed u
- Raw framebuffer mode support: The firmware can write to memory-mapped locations to populate a framebuffer and display the contents on the screen.
- PLIC
- CLINT
- VIRTIO
- bios (firmware), kernel and dtb loading
- Successfully completes all [RISCV imafdcsu ISA tests](https://github.com/riscv-software-src/riscv-tests), with some caveats (see [Testing](#testing))

Expand Down Expand Up @@ -68,7 +69,8 @@ Options:
-f, --font Path to the font file (mandatory)
-d, --dtb Path to the device tree blob file (optional, mandatory if kernel is present)
-k, --kernel Path to the kernel file (optional)
-m, --memory Emulator RAM buffer size in MiB (optional, default 66 MiB)
-m, --memory Emulator RAM buffer size in MiB (optional, default 64 MiB)
-v, --virtual-drive Path to virtual disk image to use as a filesystem (optional)
```
`bios` option is meant either for bare-metal firmware, or for a linux bootloader (e.g OpenSBI, BBL, etc)
Expand All @@ -79,6 +81,8 @@ Options:
`memory` determines the amount of RAM the emulator should allocate. If the dtb argument is used, an additional 2MiB will be allocated, and the dtb will be stored in the top 2MiB.
`virtual-drive` path to a file that will be loaded to a virtio_blk device.
When a dtb is specified, the memory size register is expected to have the magic value `0x0badc0de`. For instance, the anticipated memory definitions in the DTS should appear as follows:
```dts
Expand Down Expand Up @@ -177,15 +181,13 @@ Please note that this will be built using the Native CLI configuration.
## Supported platforms
| Platform | Supported | Comments |
|-----------------|-----------|------------------------------------|
| MacOS aarch64 || |
| MacOS x86 || Currenly untested |
| Ubuntu x86 || Currenly untested |
| Ubuntu aarch64 || |
| Windows x86 || Native CLI only, currenly untested |
| Windows aarch64 || Native CLI only, currenly untested |
| Emscripten || Native CLI only |
| Platform | Compatible | Comments |
|-----------------|------------|------------------------------------|
| MacOS aarch64 || |
| MacOS x86 || Currenly untested |
| Ubuntu x86 || Currenly untested |
| Ubuntu aarch64 || |
| Emscripten || Native CLI only |
## Dependencies/credits
Expand Down
59 changes: 16 additions & 43 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "helper.hpp"
#include "plic.hpp"
#include "ram.hpp"
#include "virtio_blk.hpp"
#include "virtio.hpp"
#include <algorithm>
#include <array>
#include <cstring>
Expand Down Expand Up @@ -156,12 +156,23 @@ int main(int argc, char* argv[])
ram_size_total += SIZE_MIB(2);
}

auto bios = helper::load_file(bios_path);
RamDevice dram = RamDevice(DRAM_BASE, ram_size_total, std::move(bios));
virtio::VirtioBlkDevice* virtio_device = nullptr;

Cpu cpu;
if (virt_drive_path)
{
if (!file_exists(virt_drive_path))
{
error_exit(argv, "virt_drive path invalid");
}

std::vector<uint8_t> virt_drive = helper::load_file(virt_drive_path);
virtio_device = new virtio::VirtioBlkDevice(std::move(virt_drive));
}

virtio::VirtioBlkDevice* virtio_blk_device = nullptr;
RamDevice dram = RamDevice(DRAM_BASE, ram_size_total, helper::load_file(bios_path));
gpu::GpuDevice gpu = gpu::GpuDevice("RISC V emulator", font_path, 960, 540);

Cpu cpu = Cpu(&dram, &gpu, virtio_device);

if (dtb_path)
{
Expand Down Expand Up @@ -195,43 +206,5 @@ int main(int argc, char* argv[])
memcpy(dram.data.data() + KERNEL_OFFSET, kernel.data(), kernel.size());
}

if (virt_drive_path)
{
if (!file_exists(virt_drive_path))
{
error_exit(argv, "virt_drive path invalid");
}

std::vector<uint8_t> virt_drive = helper::load_file(virt_drive_path);
virtio_blk_device = new virtio::VirtioBlkDevice(std::move(virt_drive));
}

cpu.pc = dram.get_base_address();
cpu.regs[Cpu::reg_abi_name::sp] = dram.get_base_address() + ram_size;

gpu::GpuDevice gpu = gpu::GpuDevice("RISC V emulator", font_path, 960, 540);

ClintDevice clint;
PlicDevice plic;

// Devices manually sorted by frequency of use
cpu.bus.add_device(&dram);

#if !NATIVE_CLI
cpu.bus.add_device(&gpu);
#endif

cpu.bus.add_device(&clint);
cpu.bus.add_device(&plic);

if (virtio_blk_device != nullptr)
{
cpu.bus.add_device(virtio_blk_device);
}

#if NATIVE_CLI
cpu.bus.add_device(&gpu);
#endif

cpu.run();
}
20 changes: 5 additions & 15 deletions source/bus.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "bus.hpp"

#include "clint.hpp"
#include "cpu.hpp"
#include "gpu.hpp"
#include "virtio_blk.hpp"
#include "virtio.hpp"
#include <algorithm>
#include <fmt/core.h>

Expand Down Expand Up @@ -61,21 +60,12 @@ BusDevice* Bus::find_bus_device(uint64_t address) const
void Bus::tick_devices(Cpu& cpu)
{
#if !CPU_TEST
static gpu::GpuDevice* gpu_device =
static_cast<gpu::GpuDevice*>(find_bus_device(gpu::cfg::uart_base_address));

static ClintDevice* clint_device =
static_cast<ClintDevice*>(find_bus_device(ClintDevice::base_addr));

static virtio::VirtioBlkDevice* virtio_blk_device =
static_cast<virtio::VirtioBlkDevice*>(find_bus_device(virtio::cfg::virtio_base_address));

gpu_device->tick(cpu);
clint_device->tick(cpu);
cpu.gpu_device->tick(cpu);
cpu.clint_device.tick(cpu);

if (virtio_blk_device != nullptr)
if (cpu.virtio_blk_device != nullptr)
{
virtio_blk_device->tick(cpu);
cpu.virtio_blk_device->tick(cpu);
}
#endif
}
Expand Down
35 changes: 34 additions & 1 deletion source/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,43 @@
#include <sstream>
#include <utility>

Cpu::Cpu() : mmu(*this)
Cpu::Cpu(RamDevice* dram_device, gpu::GpuDevice* gpu_device,
virtio::VirtioBlkDevice* virtio_blk_device)
: mmu(*this)
{
mode = cpu::Mode::Machine;

pc = dram_device->get_base_address();
regs[reg_abi_name::sp] = dram_device->get_end_address();

bus.add_device(dram_device);

#if !NATIVE_CLI
if (gpu_device != nullptr)
{
bus.add_device(gpu_device);
}
#endif

bus.add_device(&plic_device);
bus.add_device(&clint_device);

#if NATIVE_CLI
if (gpu_device != nullptr)
{
bus.add_device(gpu_device);
}
#endif

if (virtio_blk_device != nullptr)
{
bus.add_device(virtio_blk_device);
}

this->dram_device = dram_device;
this->gpu_device = gpu_device;
this->virtio_blk_device = virtio_blk_device;

csr::init_handler_array();
}

Expand Down
15 changes: 14 additions & 1 deletion source/include/cpu.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#pragma once

#include "bus.hpp"
#include "clint.hpp"
#include "common_def.hpp"
#include "csr.hpp"
#include "gpu.hpp"
#include "interupt.hpp"
#include "misc.hpp"
#include "mmu.hpp"
#include "plic.hpp"
#include "ram.hpp"
#include "virtio.hpp"
#include <array>
#include <iostream>
#include <ostream>
Expand All @@ -16,7 +21,8 @@ class Decoder;
class Cpu
{
public:
Cpu();
Cpu(RamDevice* dram_device, gpu::GpuDevice* gpu_device = nullptr,
virtio::VirtioBlkDevice* virtio_blk_device = nullptr);

void dump_registers(std::ostream& stream);

Expand Down Expand Up @@ -159,6 +165,13 @@ class Cpu
// For debugging purposes
uint64_t previous_pc = 0;

public:
PlicDevice plic_device;
ClintDevice clint_device;
RamDevice* dram_device;
gpu::GpuDevice* gpu_device;
virtio::VirtioBlkDevice* virtio_blk_device;

public:
cpu::Mode mode;

Expand Down
17 changes: 4 additions & 13 deletions source/interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "gpu.hpp"
#include "interupt.hpp"
#include "plic.hpp"
#include "virtio_blk.hpp"
#include "virtio.hpp"
#include <fmt/core.h>

interrupt::Interrupt::InterruptValue interrupt::get_pending_interrupt(Cpu& cpu)
Expand All @@ -26,35 +26,26 @@ interrupt::Interrupt::InterruptValue interrupt::get_pending_interrupt(Cpu& cpu)
}

#if !CPU_TEST
static gpu::GpuDevice* gpu_device =
static_cast<gpu::GpuDevice*>(cpu.bus.find_bus_device(gpu::cfg::uart_base_address));

static PlicDevice* plic_device =
static_cast<PlicDevice*>(cpu.bus.find_bus_device(PlicDevice::base_addr));

static virtio::VirtioBlkDevice* virtio_blk_device = static_cast<virtio::VirtioBlkDevice*>(
cpu.bus.find_bus_device(virtio::cfg::virtio_base_address));

std::optional<uint32_t> irqn;

do
{
// A crude sorting method
if ((virtio_blk_device != nullptr) && (irqn = virtio_blk_device->is_interrupting()))
if ((cpu.virtio_blk_device != nullptr) && (irqn = cpu.virtio_blk_device->is_interrupting()))
[[unlikely]]
{
break;
}

if ((irqn = gpu_device->is_interrupting())) [[unlikely]]
if ((irqn = cpu.gpu_device->is_interrupting())) [[unlikely]]
{
break;
}
} while (false);

if (irqn) [[unlikely]]
{
plic_device->update_pending(*irqn);
cpu.plic_device.update_pending(*irqn);

cpu.cregs.write_bit(csr::Address::MIP, csr::Mask::SEIP_BIT, 1);
}
Expand Down
2 changes: 1 addition & 1 deletion source/mmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ bool Mmu::fetch_pte(uint64_t address, AccessType acces_type, cpu::Mode cpu_mode,

if (i == 0)
{
entry.phys_base = ((entry.pte >> 10) & 0x0fffffffffffULL) << 12;
entry.phys_base = ((entry.pte >> 10ULL) & 0x0fffffffffffULL) << 12ULL;
}
else
{
Expand Down
File renamed without changes.
8 changes: 5 additions & 3 deletions source/peripherals/ram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ RamDevice::RamDevice(uint64_t rom_start_address, uint64_t rom_end_offset)
{
base_addr = rom_start_address;
end_addr = rom_start_address + rom_end_offset;

data.resize(end_addr - base_addr);
}

RamDevice::RamDevice(uint64_t rom_start_address, uint64_t rom_end_offset, std::vector<uint8_t> data)
{
base_addr = rom_start_address;
end_addr = rom_start_address + rom_end_offset;

this->data.resize(end_addr - base_addr);
set_data(std::move(data));
}

Expand All @@ -39,9 +43,7 @@ uint64_t RamDevice::load(Bus& bus, uint64_t address, uint64_t length)

void RamDevice::set_data(std::vector<uint8_t> data)
{
this->data = std::move(data);

this->data.resize(end_addr - base_addr);
memcpy(this->data.data(), data.data(), data.size());
}

void RamDevice::store(Bus& bus, uint64_t address, uint64_t value, uint64_t length)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "virtio_blk.hpp"
#include "virtio.hpp"
#include "cpu.hpp"
#include "cpu_config.hpp"
#include "helper.hpp"
Expand Down Expand Up @@ -33,8 +33,8 @@ void VirtioBlkDevice::update()
{
vq.desc = queue_pfn * guest_page_size;
vq.avail = vq.desc + vq.num * sizeof(VirtqDesc);
vq.used = helper::align_up(vq.avail + offsetof(VRingAvail, ring) + vq.num * sizeof(uint16_t),
vq.align);
vq.used = helper::align_up(
vq.avail + offsetof(VRingAvail, ring) + vq.num * sizeof(VRingAvail::ring[0]), vq.align);
}

VirtqDesc VirtioBlkDevice::load_desc(Cpu& cpu, uint64_t address)
Expand Down
Loading

0 comments on commit 715c8a5

Please sign in to comment.