Skip to content

PasRISCV is a RV64GC RISC-V emulator, which is implemented in Object Pascal

License

Notifications You must be signed in to change notification settings

BeRo1985/pasriscv

Repository files navigation

PasRISCV

A RISC-V RV64GC emulator written in Object Pascal. It simulates processor cores, memory, I/O, and much more.

Features

  • RV64GC instruction set support with these ISA extensions:
    • M (Integer Multiplication and Division)
    • A (Atomic Operations)
    • F (Single-Precision Floating-Point)
    • D (Double-Precision Floating-Point)
    • C (Compressed Instructions)
    • Zicsr (Control and Status Register)
    • Zifencei (Instruction-Fetch Fence)
    • Zicond (Conditional stuff)
    • Zicntr (Base Counters and Timers)
    • Zihpm (Hardware Performance Counters)
    • Zkr (Entropy source)
    • Zicbom (Cache-Block Management Instructions)
    • Zicbop (Prefetch Hints)
    • Zicboz (Cache-Block Zero Instructions)
    • Zic64b (64-Byte Cache Blocks)
    • Ziccif (Instruction Fetch Coherence)
    • Ziccrse (LR/SC Forward Progress)
    • Ziccamoa (AMO on Main Memory)
    • Zicclsm (Misaligned Load/Store Support)
    • Za64rs (64-Byte Reservation Set)
    • Svadu (Hardware Updating of PTE A/D Bits)
    • Svade (Page-Fault on A/D Bit Violations)
    • Sscofpmf (Count Overflow and Mode-Based Filtering)
    • Sstc (RISC-V "stimecmp / vstimecmp" Extension)
    • Ssccptr (Main Memory Page-Table Reads)
    • Sstvecd (stvec Direct Mode)
    • Sstvala (stval Written on Faults)
    • Sscounterenw (Writable scounteren)
    • Ssu64xl (UXLEN=64)
    • Ssstateen (Supervisor-Mode State Enable)
    • Svbare (satp Bare Mode)
    • Ss1p13 (Supervisor Architecture v1.13)
    • Supm (User-Mode Pointer Masking)
    • Ssnpm (Supervisor-Mode Pointer Masking)
    • Sha (Augmented Hypervisor Extension)
    • Shcounterenw (Writable hcounteren)
    • Shgatpa (hgatp SvNNx4 Mode Support)
    • Shtvala (htval Written on Traps)
    • Shvsatpa (vsatp SvNN Mode Support)
    • Shvstvala (vstval Written on Traps)
    • Shvstvecd (vstvec Direct Mode)
    • Svpbmt (Page-Based Memory Types)
    • Svinval (Fine-Grained TLB Invalidation)
    • Svnapot ("NAPOT Translation" Continuity)
    • Zba/Zbb/Zbc/Zbs (Bit Manipulations)
    • Zca/Zcb (Compressed sub-extensions)
    • Zacas (Atomic Compare-And-Swap)
    • Zaamo (Atomic Memory Operations)
    • Zalrsc (Load-Reserved/Store-Conditional)
    • Zabha (8-bit / 16-bit Atomic Instructions)
    • Zawrs (Wait-on-Reservation-Set)
    • Zfa (Additional Floating-Point Instructions)
    • Zfh (Half-Precision Floating-Point)
    • Zfhmin (Half-Precision Float Minimal)
    • Zfbfmin (BFloat16 Minimal)
    • Zicntr (Base Counters and Timers)
    • Zihpm (Hardware Performance Counters)
    • Zkt (Data-Independent Execution Latency)
    • Zimop (May-Be-Operations)
    • Zcmop (Compressed May-Be-Operations)
    • Zihintpause (Pause Hint)
    • Zihintntl (Non-Temporal Locality Hints)
  • Multi-core SMP support
  • Emulated peripherals
    • ACLINT
    • PLIC when AIA is not enabled (default), otherwise APLIC and IMSIC if AIA is enabled
    • AIA (Advanced Interrupt Architecture) support with APLIC and IMSIC devices (disabled by default, because not fully tested yet, enable at your own risk)
    • UART NS16550A
    • SysCon
    • VirtIO MMIO with following devices support
      • Block
      • Network
      • Random/Entropy
      • 9P filesystem
      • Keyboard
      • Mouse
      • Sound
        • VirtIO Sound (default)
        • FM801 (PCI sound card, with PCM and OPL3 YMF262 support, if SoundMode=FM801)
      • GPU (2D only, no 3D/virgl support yet)
      • Socket (vsock) — host-guest socket communication with stream and seqpacket support
      • RTC (if RTCMode=VirtIO) — real-time clock with UTC, TAI and monotonic clocks (nanosecond precision)
    • Display mode support with three selectable backends:
      • SimpleFB — custom MMIO framebuffer (default, for baremetal and simple guests)
      • VirtIO GPU — standard VirtIO 2D GPU with EDID support (for Linux with virtio-gpu driver)
        • This is the recommended display mode for Linux guests, as it offers better performance and compatibility than SimpleFB. The guest OS updates the framebuffer via VirtIO and marks it as dirty, so the host only refreshes the output when the content has actually changed, whereas SimpleFB requires polling the entire framebuffer every frame, which is very inefficient for Linux desktop environments with compositing and frequent screen updates.
      • Bochs VBE — PCI VGA adapter with VBE DISPI registers (for Linux with bochs-drm driver)
      • Cirrus Logic GD 5446 — PCI VGA adapter compatible with QEMU cirrus driver (for Linux with cirrus DRM driver)
    • Framebuffer support
    • Shared memory device for host-guest shared memory communication with doorbell IRQ support
    • PS/2 keyboard and mouse
    • Raw keyboard input with scancode bit-array (for more direct input per polling)
    • DS1742 real-time clock (read-only, no write support)
    • Goldfish RTC (default, with interrupt support)
    • DS1307 I2C RTC (via I2C bus, if RTCMode=DS1307)
    • VirtIO RTC (VirtIO 1.4 Device ID 17, with UTC/TAI/Monotonic clocks)
    • PCIe Bus
      • NVMe SSD
      • IVSHMEM (Inter-VM Shared Memory) device for host-guest shared memory communication with doorbell interrupts
      • Bochs VBE VGA adapter (if DisplayMode=BochsVBE)
      • Cirrus Logic GD 5446 VGA adapter (if DisplayMode=Cirrus)
    • I2C bus with two selectable controller modes:
      • OpenCores I2C (opencores,i2c-ocores) — classic register-based I2C controller
      • Synopsys DesignWare I2C (snps,designware-i2c) — default, compatible with Linux i2c-designware driver
      • Attached devices:
        • DS1307 RTC (if RTCMode=DS1307)
        • HID keyboard (planned, currently disabled)
  • Full MMU support with Sv39, Sv48 and Sv57 page table modes, including support for Svnapot and Svadu extensions
  • Disassembler
    • RV64GC instruction set support
    • Supports disassembling code with or without compressed instructions
    • Supports disassembling code with or without floating-point instructions
    • Provides human-readable assembly code output
  • Debugger
    • Internal debugger
      • Command line interface
      • Debugger GUI backend API support
      • Breakpoint support
      • Memory and register inspection/modification
      • Step, Continue, Pause execution control
      • Reboot, Reset, PowerOff/Shutdown control
    • GDB remote debugging support (partially implemented)
      • Own GDB server implementation
    • Multiple debugger client support
      • GDB, internal CLI, custom GUI backends, all simultaneously at the same time
  • ELF loader
  • Linux kernel boot support
  • Untested support for other OS images (FreeBSD, NetBSD, OpenBSD, Haiku, etc.), may require additional fixes or tweaks
  • Device Tree Blob (DTB) support
  • Initrd support
  • Command line support for the guest OS
  • Simple test suite with various test cases for different parts of the emulator
  • Cross-platform (Windows, Linux, macOS)
  • Written in Object Pascal (Free Pascal / Lazarus)

Why 64-bit only?

The decision to support only 64-bit RISC-V (RV64GC) is primarily driven by the need for a modern architecture that can efficiently handle current and future workloads. 64-bit architectures provide several advantages over their 32-bit counterparts, including:

  1. Larger Address Space: 64-bit systems can address significantly more memory than 32-bit systems, allowing for more extensive and complex applications.

  2. Improved Performance: 64-bit processors can handle more data per clock cycle, leading to better performance for compute-intensive tasks.

  3. Future-Proofing: As software and workloads evolve, the demand for 64-bit processing power will only increase. Supporting 64-bit from the outset ensures that the emulator can accommodate future developments.

  4. Compatibility with Modern Software: Most modern operating systems and applications are designed with 64-bit architectures in mind, making it essential for the emulator to support this architecture for compatibility reasons.

And support for 32-bit RISC-V is virtually nonexistent outside of source-based distros (Gentoo, Buildroot, Yocto, etc.), strange embedded systems and some hobbyist projects. Most mainstream Linux distributions, other operating systems and software projects have moved to 64-bit as the standard, making it more practical to focus only on 64-bit support. 32-bit support would require additional development and maintenance effort, which may not be justified given the limited use cases and demand for 32-bit RISC-V. So, it is 64-bit only, and it will remain that way. The same applies to 128-bit RISC-V, which is not supported at all, since there is no real-world implementation or use case for it at this time.

Why Little-Endian only? Why not Big-Endian or Mixed-Endian?

The decision to support only Little-Endian mode in the PasRISCV emulator is based on several practical considerations:

  1. Prevalence of Little-Endian: Little-Endian is the most commonly used endianness in modern computing systems, including x86 and modern ARM architectures. By focusing on Little-Endian, the emulator aligns with the majority of existing software and hardware, ensuring better compatibility and ease of use. And most all RISC-V systems in the wild are also Little-Endian. And the RISC-V specification itself defaults to Little-Endian, with Big-Endian support being not specified and rarely implemented officially.

  2. Simplicity and Maintainability: Supporting multiple endianness modes (Little-Endian, Big-Endian, and Mixed-Endian) would significantly increase the complexity of the emulator's design and implementation. This added complexity could lead to more bugs, increased development time, and greater maintenance challenges. By limiting the scope to Little-Endian, the development process becomes more straightforward and manageable.

  3. Target Audience: The primary users of the PasRISCV emulator are likely to be developers and enthusiasts who are already familiar with Little-Endian systems. By catering to this audience, the emulator can provide a more focused and optimized experience.

  4. Performance Considerations: Emulating multiple endianness modes could introduce performance overhead due to the need for additional checks and conversions during memory access operations. By standardizing on Little-Endian, the emulator can optimize performance for the most common use cases.

  5. Low Byte-Swapping Costs: Modern compilers and processors are highly optimized for handling byte-swapping operations when necessary. This means that even if a user needs to work with Big-Endian data, the performance impact of converting between endianness is minimal in most scenarios. PasRISCV supports the Zbb extension, which includes bit manipulation instructions that can facilitate efficient byte-swapping just in a single instruction when needed, for example for network protocols (network byte order) or older file formats that used still Big-Endian.

  6. Big-Endian Is Dead: There are very few use cases for Big-Endian systems today, and they are mostly limited to legacy systems or specific niche applications. The demand for Big-Endian support is minimal, making it less justifiable to invest resources in its implementation. Big-Endian lives on mostly in some network protocols (network byte order) and some older file formats, but even there, its use is declining as more systems adopt Little-Endian.

  7. Mixed-Endian Complexity: Mixed-Endian systems, which use different endianness for different data types or structures, are even more complex to implement and maintain. The rarity of Mixed-Endian systems in practical applications further diminishes the need for support in the emulator.

Overall, the decision to support only Little-Endian mode in the PasRISCV emulator is a strategic choice that balances compatibility, simplicity, performance, and user needs. While Big-Endian and Mixed-Endian modes have their use cases, the benefits of focusing on Little-Endian outweigh the potential advantages of supporting multiple endianness modes in this context.

Usage

See pasriscvemu PasVulkan project for an emulator frontend that uses this library.

Documentation

See the docs directory for more information.

Related connected repositories

  • PasRISCV Third-Party Software Repository - This repository contains third-party software, including test cases, guest Linux system build scripts, and other related assets, for the PasRISCV Emulator — a RV64GC RISC-V emulator developed in Object Pascal. Needed for the test suite and other related assets.
  • PasVulkan - PasVulkan game engine and Vulkan API bindings for Object Pascal.
  • pasriscemu - PasRISCV Emulator frontend using PasVulkan.

License

This project is released under zlib license.

Releases

No releases published

Packages

No packages published

Languages