Freedom Metal Machine Compatibility Library

repository·master·Indexed 41 days ago

https://github.com/sifive/freedom-metal

A machine compatibility library for hardware abstraction and machine-level software development. It provides a Machine Emulation Environment (MEE) with C APIs for portable bare-metal code, including interfaces for system clocks, timers, power control, TTY, and UART. The library includes mechanisms for managing CPU interrupts, exception handlers, and a constructor/destructor system for driver initialization via METAL_CONSTRUCTOR and METAL_DESTRUCTOR macros.

Tokens
5.5K
Snippets
15
Records
32
Agent score
50%

What's inside Freedom Metal

  1. What is Freedom Metal?

    master

    Freedom Metal is a machine compatibility library designed for portable, bare-metal application development across the SiFive RISC-V ecosystem. It acts as a hardware abstraction layer (HAL) that enables code to be retargeted to any SiFive RISC-V product.

    Key features include:

    • A bare-metal C application environment.
    • An API for controlling CPU features and peripherals.
    • Portability across SiFive RISC-V IP, FPGA evaluation targets, and development boards.
  2. What is Physical Memory Protection (PMP)?

    master
    Physical Memory Protection (PMP) is a feature of the RISC-V Privileged Architecture that provides a standard memory protection unit interface. It allows you to define a finite number of PMP regions, each configured with specific access permissions for a range of memory addresses. This enables fine-grained control over which parts of the memory are accessible to different execution modes.
  3. Use Standard I/O for virtual terminal support

    master

    Freedom Metal provides virtual terminal support by integrating with the libc STDOUT stream. By default, STDOUT is mapped to the first UART serial peripheral available on the target hardware.

    Note: If the target does not have a UART serial peripheral (for example, in SiFive CoreIP test harnesses), bytes sent to STDOUT will be silently dropped.

  4. Understand the Freedom Metal interrupt hierarchy

    master

    Freedom Metal models interrupts as a tree hierarchy of interrupt controllers. The structure of this hierarchy is determined by the target platform's hardware and is typically defined in the platform's DeviceTree (e.g., bsp/<target-name>/design.dts).

    In this model:

    • The nodes of the tree are represented by struct metal_interrupt.
    • The vertices (connections) between nodes are defined by interrupt ids.

    The CPU Interrupt Controller sits at the top of the hierarchy and must be initialized before any other interrupt controllers.

  5. Understand the MEE User API naming conventions

    master

    The Machine Emulation Environment (MEE) provides a C API for portable bare-metal code. To use the API correctly, follow these naming conventions:

    • Public Interfaces: Symbols beginning with mee_ are part of the stable public API.
    • Internal Symbols: Symbols beginning with __mee_ are internal to the MEE implementation. Do not call or define these in your user code.

    Note that while the API is intended to be stable, no guarantees are made until the 1.0.0 release. Additionally, the MEE defines a source-level compatibility layer, but does not define an ABI; therefore, binaries are not compatible between different MEE versions or platforms.

  6. How Metal initialization and finalization flow works

    master

    By default, Metal manages the execution flow of constructors and destructors through wrapper functions. The standard execution sequence is:

    1. _start
    2. metal_init_run (calls metal_init, which executes all registered constructors)
    3. main (your application code)
    4. exit
    5. metal_fini_run (calls metal_fini, which executes all registered destructors)

    This flow ensures that Metal device drivers (like a UART driver configuring its baud rate) are initialized before your main() function begins.

  7. Build the documentation (HTML and PDF)

    master

    Use make to generate both HTML and PDF documentation. You can also target specific formats or clean the build directory.

    # Build both HTML and PDF
    make
    
    # Build only HTML
    make html
    
    # Build only PDF
    make pdf
    
    # Clean build files and outputs
    make clean
  8. Handle PMP Access Faults

    master
    When the PMP prevents a memory access, the CPU triggers an exception. To manage these events, you must install a CPU exception handler specifically for exception codes related to memory access faults. Refer to the Exception Handlers Developer Guide for instructions on creating and registering these handlers.
  9. Use Instruction Tightly Integrated Memory (ITIM) with METAL_PLACE_IN_ITIM

    master

    On certain SiFive RISC-V CPUs, you can use Instruction Tightly Integrated Memory (ITIM) to achieve low-latency instruction access. Freedom Metal allows you to designate specific functions to reside in the ITIM by using the METAL_PLACE_IN_ITIM decorator. This decorator instructs the toolchain to link the decorated function into the ITIM memory region.

    METAL_PLACE_IN_ITIM
    void my_itim_func() {
       /* This code will run out of the ITIM */
    }
  10. Configure the FE310-G000 PLL via DeviceTree

    master

    On targets compatible with the FE310-G000 SoC, the PLL is automatically configured during program initialization using a constructor. To request a specific clock rate for the RISC-V CPU, define a clock node in your DeviceTree. The PLL driver uses the clock-frequency property to attempt to achieve the requested rate.

    Important Note: The FE310-G000 PLL only supports specific input/output clock rate ratios. Consequently, the actual effective output rate may differ from the rate requested in the clock-frequency property.

    hfclk: clock@4 {
    	compatible = "sifive,fe310-g000,pll";
    	clocks = <&hfxoscout &hfroscout>;
    	clock-names = "pllref", "pllsel0";
    	reg = <&prci 0x8 &prci 0xc>;
    	reg-names = "config", "divider";
    	clock-frequency = <16000000>;
    };
  11. Get started with Freedom Metal

    master

    To begin developing bare-metal applications with Freedom Metal, you should use one of the following two primary distribution methods:

    1. SiFive Freedom E SDK: This is the recommended way to get started. It bundles the necessary build scripts and configurations required to use Freedom Metal with standard SiFive evaluation products.
    2. SiFive Freedom Studio: If you prefer an Integrated Development Environment (IDE), Freedom Studio comes packaged with a prebuilt toolchain and includes the same Freedom Metal examples found in the Freedom E SDK.

    Freedom Metal provides a bare-metal C application environment and an API for controlling CPU features and peripherals, allowing you to write portable hardware tests and bootstrap bare-metal development across SiFive's RISC-V IP, FPGA evaluation targets, and development boards.