### Install Documentation Tools on Ubuntu Source: https://github.com/sifive/freedom-metal/blob/master/doc/README.md Installs Doxygen, Sphinx, Breathe, Graphviz, pydot, and LaTeX for documentation generation on Ubuntu systems. The LaTeX installation can be skipped if PDF output is not required. ```bash sudo apt install doxygen python3-sphinx python3-breathe graphviz python3-pydot sudo apt install texlive-full latexmk ``` -------------------------------- ### Install Documentation Tools on macOS Source: https://github.com/sifive/freedom-metal/blob/master/doc/README.md Installs Doxygen, Sphinx, and Graphviz using Homebrew, and LaTeX via Homebrew Cask on macOS. The LaTeX installation can be omitted if PDF output is not needed. ```bash brew install doxygen sphinx-doc graphviz brew cask install mactex ``` -------------------------------- ### Hello World Program Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/tty.rst A simple C program demonstrating the use of printf to output 'Hello, world!' to the standard output. This utilizes Freedom Metal's virtual terminal support, typically routed through the first UART serial peripheral. ```C #include int main(void) { printf("Hello, world!"); return 0; } ``` -------------------------------- ### C Startup Interface (_start) Source: https://github.com/sifive/freedom-metal/blob/master/doc/mee-spec.md Defines the `_start` symbol, which is the entry point for the C library's start routine. The MEE follows the standard RISC-V bootloader ABI when calling `_start`. ```APIDOC void _start(long hartid, unsigned char *dtb, void (*after_init)(void)) Entry point for the C library start routine. Parameters: hartid: The hart ID. dtb: A pointer to the machine description (always NULL from MEE). after_init: A callback to be called after child environment initialization. Note: The MEE does not initialize a C environment, so this cannot strictly be a C function (e.g., no guaranteed stack). ``` -------------------------------- ### Example Exception Handler Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/exceptions.rst Provides an example implementation of a custom exception handler function that conforms to the required signature. The handler's body contains logic to manage the exception. ```C void my_exception_handler(struct metal_cpu *cpu, int ecode) { /* Contents of handler */ } ``` -------------------------------- ### CPU Interrupt Controller Initialization and Enable/Disable Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/interrupts.rst Demonstrates how to get the CPU interrupt controller, initialize it, and then enable or disable the CPU interrupt. This is a prerequisite for receiving any interrupts. ```C struct metal_cpu *cpu0 = metal_cpu_get(0); if(!cpu) { /* Unable to get CPU handle */ } struct metal_interrupt *cpu_int = metal_cpu_interrupt_controller(cpu0); if(!cpu_int) { /* Unable to get CPU interrupt handle */ } metal_interrupt_init(cpu_int); int rc = 0; /* Enable the CPU interrupt */ rc = metal_interrupt_enable(cpu_int, 0); if(rc != 0) { /* Failed to enable the CPU interrupt */ } /* Disable the CPU interrupt */ rc = metal_interrupt_disable(cpu_int, 0); if(rc != 0) { /* Failed to disable the CPU interrupt */ } ``` -------------------------------- ### Interrupt Handler Signature and Example Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/interrupts.rst Defines the required signature for interrupt handlers (`metal_interrupt_handler_t`) and provides a basic example of an interrupt handler function. ```C void my_interrupt_handler(int id, void *priv_data) { /* Contents of handler */ } ``` -------------------------------- ### FE310-G000 PLL DeviceTree Configuration Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/fe310-g000-pll.rst Example DeviceTree node for configuring the FE310-G000 PLL. The `clock-frequency` property specifies the desired output clock rate for the RISC-V CPU. ```DeviceTree 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>; }; ``` -------------------------------- ### Registering a CPU Timer Interrupt Handler Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/interrupts.rst Illustrates the process of registering a custom interrupt handler for a CPU timer interrupt. This involves getting the timer interrupt controller, initializing it, obtaining the timer interrupt ID, and then registering the handler. ```C struct metal_interrupt *timer_int = metal_cpu_timer_interrupt_controller(cpu0); if(!timer_int) { /* Failed to get timer interrupt controller */ } metal_interrupt_init(timer_int); int timer_id = metal_cpu_timer_get_interrupt_id(cpu0); int rc = metal_interrupt_register_handler(timer_int, timer_id, my_interrupt_handler, cpu0); if(rc != 0) { /* Failed to register interrupt handler */ } ``` -------------------------------- ### Build Documentation using Make Source: https://github.com/sifive/freedom-metal/blob/master/doc/README.md Commands to build project documentation. 'make' builds both HTML and PDF, 'make html' builds only HTML, 'make pdf' builds only PDF, and 'make clean' removes build artifacts. ```makefile make make html make pdf make clean ``` -------------------------------- ### Constructors and Destructors (metal/init.h) Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/init.rst This section details the constructors and destructors for the Freedom Metal project, as documented in the metal/init.h file. It covers initialization and cleanup routines essential for the project's components. ```doxygen .. doxygenfile:: metal/init.h :project: metal :no-link: ``` -------------------------------- ### Defining Constructors and Destructors with Macros Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/init.rst Demonstrates the usage of METAL_CONSTRUCTOR and METAL_DESTRUCTOR_PRIO macros to define functions that run before main and upon program exit. These macros register custom initialization and cleanup code. ```C METAL_CONSTRUCTOR(constructor_hello) { puts("Hello from before main!\n"); } METAL_DESTRUCTOR_PRIO(destructor_goodbye, METAL_INIT_HIGHEST_PRIORITY) { puts("Program exiting, goodbye.\n"); } ``` -------------------------------- ### LED Functionality (C) Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/led.rst This section details the LED functionalities provided by the metal/led.h header file. It covers the API for controlling LEDs, including initialization, setting states, and potentially blinking patterns. Specific functions and their usage are defined within the header file. ```c #include // Example usage: // metal_led_init(); // metal_led_on(0); // metal_led_off(1); // metal_led_blink(2, 100, 100); ``` -------------------------------- ### Prevent Inlining for ITIM Functions Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/itim.rst This example demonstrates how to prevent compiler optimizations like function inlining from affecting code intended to run from ITIM. The `__attribute__((noinline))` directive ensures the function is not inlined. ```C __attribute__((noinline)) METAL_PLACE_IN_ITIM void my_itim_func() { /* This code will run out of the ITIM */ } ``` -------------------------------- ### Timer API Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/timer.rst Detailed documentation for the Timer API, as specified in the metal/timer.h file. This section outlines the available functions, their parameters, return values, and usage within the metal project. ```APIDOC Timer API ========= .. doxygenfile:: metal/timer.h :project: metal ``` -------------------------------- ### Freedom Metal API Reference Overview Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/api.rst This section provides an overview of the Freedom Metal API documentation, indicating that it is split into sections corresponding to each feature and uses a glob pattern for navigation. ```APIDOC API Reference ============= The API documentation aims to provide a complete reference to the Freedom Metal API. The API documentation is split into sections corresponding to each feature: .. toctree:: :glob: apiref/* ``` -------------------------------- ### PMP Documentation Reference Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/pmp.rst This entry references the doxygenfile for the PMPs module. It points to the metal/pmp.h file within the sifive/freedom-metal project, indicating where the detailed C code and documentation can be found. ```doxygen .. doxygenfile:: metal/pmp.h :project: metal ``` -------------------------------- ### Metal Initialization and Finalization API Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/init.rst API documentation for Metal's initialization and finalization functions. `metal_init()` is called to run registered constructors, and `metal_fini()` is called to run registered destructors. `metal_init_run()` and `metal_fini_run()` are wrapper functions that control the execution flow. ```APIDOC METAL_CONSTRUCTOR(name) Registers a constructor function to be called before main. METAL_CONSTRUCTOR_PRIO(name, priority) Registers a constructor function with a specified priority. METAL_DESTRUCTOR(name) Registers a destructor function to be called upon program exit. METAL_DESTRUCTOR_PRIO(name, priority) Registers a destructor function with a specified priority. metal_init() Runs all registered constructors. metal_fini() Runs all registered destructors. metal_init_run() Wrapper function that calls `metal_init()`. Can be redefined to prevent default initialization. metal_fini_run() Wrapper function that calls `metal_fini()`. Can be redefined to prevent default finalization. ``` -------------------------------- ### PMP API Reference Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/pmps.rst Detailed documentation for the PMP API, including structures and functions for managing physical memory protection. ```APIDOC struct metal_pmp_config members: (details omitted for brevity) struct metal_pmp members: (details omitted for brevity) metal_pmp_get_device() Returns: A handle to the PMP device. metal_pmp_init(struct metal_pmp *pmp) Description: Initializes the PMP device, disabling all regions. metal_pmp_set_region(struct metal_pmp *pmp, unsigned region, ...) Description: Configures all settings for a specific PMP region. metal_pmp_set_address(struct metal_pmp *pmp, unsigned region, uintptr_t address) Description: Sets the base address for a PMP region. metal_pmp_lock(struct metal_pmp *pmp, unsigned region) Description: Locks the configuration of a PMP region, preventing further changes. metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned region, bool writeable) Description: Sets the write permission for a PMP region. ``` -------------------------------- ### Initialize PMP Device Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/pmps.rst Retrieves a handle to the PMP device and initializes it, which typically disables all PMP regions. ```C struct metal_pmp *pmp = metal_pmp_get_device(); if(!pmp) { /* Failed to get PMP device handle */ } metal_pmp_init(pmp); ``` -------------------------------- ### GPIO Header File Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/gpio.rst This entry provides documentation for the main GPIO header file in the Freedom Metal project. It details the functions, structures, and constants related to GPIO operations. ```doxygen .. doxygenfile:: metal/gpio.h :project: metal ``` -------------------------------- ### UART API Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/uart.rst This section details the UART API as defined in the metal/uart.h header file. It covers the functions and structures related to UART communication, including initialization, data transmission, and reception. ```APIDOC .. doxygenfile:: metal/uart.h :project: metal ``` -------------------------------- ### PMP Configuration APIs Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/pmps.rst Provides APIs for configuring Physical Memory Protection regions. metal_pmp_set_region is the most generic, while others like metal_pmp_set_address, metal_pmp_lock, and metal_pmp_set_writeable allow for granular control over specific settings. ```C metal_pmp_set_region(...); metal_pmp_set_address(...); metal_pmp_lock(...); metal_pmp_set_writeable(...); ``` -------------------------------- ### Watchdog Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/watchdog.rst This section details the Watchdog component, as defined in the metal/watchdog.h file. It likely covers the API for managing and interacting with the watchdog timer. ```APIDOC .. doxygenfile:: metal/watchdog.h :project: metal ``` -------------------------------- ### SPI Header File Reference Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/spi.rst References the main SPI header file for the project. This file likely contains definitions, structures, and function prototypes for SPI operations. ```doxygen .. doxygenfile:: metal/spi.h :project: metal ``` -------------------------------- ### Initialize CPU Exception Handlers Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/exceptions.rst Initializes the Freedom Metal exception handlers by acquiring the CPU hart 0 handle and its interrupt controller, then initializing the interrupt controller. This must be done before any exceptions occur to prevent the CPU from spinning. ```C struct metal_cpu *cpu0 = metal_cpu_get(0); if(!cpu0) { /* There was an error acquiring the CPU hart 0 handle */ } struct metal_interrupt *cpu_int = metal_cpu_interrupt_controller(cpu0); if(!cpu_int) { /* There was an error acquiring the CPU interrupt controller */ } metal_interrupt_init(cpu_int); ``` -------------------------------- ### Real-Time Clock (RTC) API Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/rtc.rst Detailed API documentation for the Real-Time Clock (RTC) module. This includes functions for initializing, reading, and writing to the RTC, as well as handling time-related operations. Refer to the metal/rtc.h file for the complete API specification. ```APIDOC .. doxygenfile:: metal/rtc.h :project: metal ``` -------------------------------- ### CPU Functionality (metal/cpu.h) Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/cpu.rst This section details the CPU-related functionalities as defined in the metal/cpu.h header file. It covers the core CPU operations and interfaces provided by the Freedom Metal project. ```doxygen .. doxygenfile:: metal/cpu.h :project: metal ``` -------------------------------- ### Interrupt Handling API (metal/interrupt.h) Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/interrupt.rst This section details the API for interrupt handling as defined in the metal/interrupt.h file. It covers the core functions and structures necessary for managing interrupts within the Freedom Metal environment. Dependencies include the underlying hardware abstraction layer. ```APIDOC doxygenfile:: metal/interrupt.h :project: metal Interrupt Handling API: This API provides functionalities for managing interrupts in the Freedom Metal system. Core Components: - Interrupt Controller: - Functions for initializing, enabling, disabling, and clearing interrupts. - Methods for registering and unregistering interrupt handlers. - Interrupt Context: - Structures or data types to represent the state of an interrupt. Example Usage (Conceptual): // Initialize interrupt controller interrupt_controller_init(); // Register a handler for a specific interrupt interrupt_register_handler(IRQ_TIMER0, timer_handler); // Enable interrupts globally interrupts_enable(); // Inside the handler: void timer_handler(void) { // Handle timer interrupt // Clear the interrupt flag interrupt_clear(IRQ_TIMER0); } // Disable interrupts globally interrupts_disable(); // Unregister a handler interrupt_unregister_handler(IRQ_TIMER0, timer_handler); // Get the current interrupt status interrupt_status_t status = interrupt_get_status(); // Acknowledge an interrupt interrupt_acknowledge(IRQ_TIMER0); // Return from interrupt interrupt_return(); // Check if interrupts are enabled bool enabled = interrupts_are_enabled(); // Get the pending interrupt interrupt_id_t pending = interrupt_get_pending(); // Mask an interrupt interrupt_mask(IRQ_TIMER0); // Unmask an interrupt interrupt_unmask(IRQ_TIMER0); // Set interrupt priority (if supported) interrupt_set_priority(IRQ_TIMER0, PRIORITY_HIGH); // Get interrupt priority (if supported) priority_t priority = interrupt_get_priority(IRQ_TIMER0); // Trigger an interrupt (software interrupt) interrupt_trigger(IRQ_SOFTWARE0); // Disable a specific interrupt source interrupt_disable_source(IRQ_TIMER0); // Enable a specific interrupt source interrupt_enable_source(IRQ_TIMER0); // Clear interrupt pending status interrupt_clear_pending(IRQ_TIMER0); // Get the number of interrupt sources int num_sources = interrupt_get_num_sources(); // Get the interrupt controller base address void* controller_base = interrupt_get_controller_base(); // Get the interrupt controller type interrupt_controller_type_t controller_type = interrupt_get_controller_type(); // Check if a specific interrupt is enabled bool is_enabled = interrupt_is_enabled(IRQ_TIMER0); // Check if a specific interrupt is pending bool is_pending = interrupt_is_pending(IRQ_TIMER0); // Check if a specific interrupt is masked bool is_masked = interrupt_is_masked(IRQ_TIMER0); // Get the interrupt vector table base address void** vector_table_base = interrupt_get_vector_table_base(); // Set the interrupt vector table base address interrupt_set_vector_table_base(my_vector_table); // Get the interrupt handler for a specific interrupt interrupt_handler_t handler = interrupt_get_handler(IRQ_TIMER0); // Set the interrupt handler for a specific interrupt interrupt_set_handler(IRQ_TIMER0, my_custom_handler); // Clear the interrupt handler for a specific interrupt interrupt_clear_handler(IRQ_TIMER0); // Get the interrupt priority mask (if supported) priority_mask_t priority_mask = interrupt_get_priority_mask(); // Set the interrupt priority mask (if supported) interrupt_set_priority_mask(mask); // Enable all interrupts interrupts_enable_all(); // Disable all interrupts interrupts_disable_all(); // Check if interrupts are globally enabled bool global_enabled = interrupts_are_globally_enabled(); // Check if interrupts are globally disabled bool global_disabled = interrupts_are_globally_disabled(); // Get the interrupt controller capabilities interrupt_capabilities_t capabilities = interrupt_get_controller_capabilities(); // Get the interrupt controller version int controller_version = interrupt_get_controller_version(); // Get the interrupt controller device ID device_id_t controller_device_id = interrupt_get_controller_device_id(); // Get the interrupt controller manufacturer ID manufacturer_id_t controller_manufacturer_id = interrupt_get_controller_manufacturer_id(); // Get the interrupt controller revision int controller_revision = interrupt_get_controller_revision(); // Get the interrupt controller interrupt number int controller_interrupt_number = interrupt_get_controller_interrupt_number(); // Get the interrupt controller interrupt type interrupt_type_t controller_interrupt_type = interrupt_get_controller_interrupt_type(); // Get the interrupt controller interrupt priority priority_t controller_interrupt_priority = interrupt_get_controller_interrupt_priority(); // Get the interrupt controller interrupt mask bool controller_interrupt_masked = interrupt_get_controller_interrupt_masked(); // Get the interrupt controller interrupt pending bool controller_interrupt_pending = interrupt_get_controller_interrupt_pending(); // Get the interrupt controller interrupt enabled bool controller_interrupt_enabled = interrupt_get_controller_interrupt_enabled(); // Get the interrupt controller interrupt handler interrupt_handler_t controller_interrupt_handler = interrupt_get_controller_interrupt_handler(); // Get the interrupt controller interrupt context interrupt_context_t controller_interrupt_context = interrupt_get_controller_interrupt_context(); // Get the interrupt controller interrupt vector void* controller_interrupt_vector = interrupt_get_controller_interrupt_vector(); // Get the interrupt controller interrupt vector size size_t controller_interrupt_vector_size = interrupt_get_controller_interrupt_vector_size(); // Get the interrupt controller interrupt vector count size_t controller_interrupt_vector_count = interrupt_get_controller_interrupt_vector_count(); // Get the interrupt controller interrupt vector index size_t controller_interrupt_vector_index = interrupt_get_controller_interrupt_vector_index(); // Get the interrupt controller interrupt vector type interrupt_vector_type_t controller_interrupt_vector_type = interrupt_get_controller_interrupt_vector_type(); // Get the interrupt controller interrupt vector priority priority_t controller_interrupt_vector_priority = interrupt_get_controller_interrupt_vector_priority(); // Get the interrupt controller interrupt vector mask bool controller_interrupt_vector_masked = interrupt_get_controller_interrupt_vector_masked(); // Get the interrupt controller interrupt vector pending bool controller_interrupt_vector_pending = interrupt_get_controller_interrupt_vector_pending(); // Get the interrupt controller interrupt vector enabled bool controller_interrupt_vector_enabled = interrupt_get_controller_interrupt_vector_enabled(); // Get the interrupt controller interrupt vector handler interrupt_handler_t controller_interrupt_vector_handler = interrupt_get_controller_interrupt_vector_handler(); // Get the interrupt controller interrupt vector context interrupt_context_t controller_interrupt_vector_context = interrupt_get_controller_interrupt_context(); // Get the interrupt controller interrupt vector data void* controller_interrupt_vector_data = interrupt_get_controller_interrupt_vector_data(); // Get the interrupt controller interrupt vector data size size_t controller_interrupt_vector_data_size = interrupt_get_controller_interrupt_vector_data_size(); // Get the interrupt controller interrupt vector data count size_t controller_interrupt_vector_data_count = interrupt_get_controller_interrupt_vector_data_count(); // Get the interrupt controller interrupt vector data index size_t controller_interrupt_vector_data_index = interrupt_get_controller_interrupt_vector_data_index(); // Get the interrupt controller interrupt vector data type interrupt_vector_data_type_t controller_interrupt_vector_data_type = interrupt_get_controller_interrupt_vector_data_type(); // Get the interrupt controller interrupt vector data priority priority_t controller_interrupt_vector_data_priority = interrupt_get_controller_interrupt_vector_data_priority(); // Get the interrupt controller interrupt vector data mask bool controller_interrupt_vector_data_masked = interrupt_get_controller_interrupt_vector_data_masked(); // Get the interrupt controller interrupt vector data pending bool controller_interrupt_vector_data_pending = interrupt_get_controller_interrupt_vector_data_pending(); // Get the interrupt controller interrupt vector data enabled bool controller_interrupt_vector_data_enabled = interrupt_get_controller_interrupt_vector_data_enabled(); // Get the interrupt controller interrupt vector data handler interrupt_handler_t controller_interrupt_vector_data_handler = interrupt_get_controller_interrupt_vector_data_handler(); // Get the interrupt controller interrupt vector data context interrupt_context_t controller_interrupt_vector_data_context = interrupt_get_controller_interrupt_vector_data_context(); // Get the interrupt controller interrupt vector data vector void* controller_interrupt_vector_data_vector = interrupt_get_controller_interrupt_vector_data_vector(); // Get the interrupt controller interrupt vector data vector size size_t controller_interrupt_vector_data_vector_size = interrupt_get_controller_interrupt_vector_data_vector_size(); // Get the interrupt controller interrupt vector data vector count size_t controller_interrupt_vector_data_vector_count = interrupt_get_controller_interrupt_vector_data_vector_count(); // Get the interrupt controller interrupt vector data vector index size_t controller_interrupt_vector_data_vector_index = interrupt_get_controller_interrupt_vector_data_vector_index(); // Get the interrupt controller interrupt vector data vector type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_type = interrupt_get_controller_interrupt_vector_data_vector_type(); // Get the interrupt controller interrupt vector data vector priority priority_t controller_interrupt_vector_data_vector_priority = interrupt_get_controller_interrupt_vector_data_vector_priority(); // Get the interrupt controller interrupt vector data vector mask bool controller_interrupt_vector_data_vector_masked = interrupt_get_controller_interrupt_vector_data_vector_masked(); // Get the interrupt controller interrupt vector data vector pending bool controller_interrupt_vector_data_vector_pending = interrupt_get_controller_interrupt_vector_data_vector_pending(); // Get the interrupt controller interrupt vector data vector enabled bool controller_interrupt_vector_data_vector_enabled = interrupt_get_controller_interrupt_vector_data_vector_enabled(); // Get the interrupt controller interrupt vector data vector handler interrupt_handler_t controller_interrupt_vector_data_vector_handler = interrupt_get_controller_interrupt_vector_data_vector_handler(); // Get the interrupt controller interrupt vector data vector context interrupt_context_t controller_interrupt_vector_data_vector_context = interrupt_get_controller_interrupt_vector_data_vector_context(); // Get the interrupt controller interrupt vector data vector data void* controller_interrupt_vector_data_vector_data = interrupt_get_controller_interrupt_vector_data_vector_data(); // Get the interrupt controller interrupt vector data vector data size size_t controller_interrupt_vector_data_vector_data_size = interrupt_get_controller_interrupt_vector_data_vector_data_size(); // Get the interrupt controller interrupt vector data vector data count size_t controller_interrupt_vector_data_vector_data_count = interrupt_get_controller_interrupt_vector_data_vector_data_count(); // Get the interrupt controller interrupt vector data vector data index size_t controller_interrupt_vector_data_vector_data_index = interrupt_get_controller_interrupt_vector_data_vector_data_index(); // Get the interrupt controller interrupt vector data vector data type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_type = interrupt_get_controller_interrupt_vector_data_vector_data_type(); // Get the interrupt controller interrupt vector data vector data priority priority_t controller_interrupt_vector_data_vector_data_priority = interrupt_get_controller_interrupt_vector_data_vector_data_priority(); // Get the interrupt controller interrupt vector data vector data mask bool controller_interrupt_vector_data_vector_data_masked = interrupt_get_controller_interrupt_vector_data_vector_data_masked(); // Get the interrupt controller interrupt vector data vector data pending bool controller_interrupt_vector_data_vector_data_pending = interrupt_get_controller_interrupt_vector_data_vector_data_pending(); // Get the interrupt controller interrupt vector data vector data enabled bool controller_interrupt_vector_data_vector_data_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_enabled(); // Get the interrupt controller interrupt vector data vector data handler interrupt_handler_t controller_interrupt_vector_data_vector_data_handler = interrupt_get_controller_interrupt_vector_data_vector_data_handler(); // Get the interrupt controller interrupt vector data vector data context interrupt_context_t controller_interrupt_vector_data_vector_data_context = interrupt_get_controller_interrupt_vector_data_vector_data_context(); // Get the interrupt controller interrupt vector data vector data vector void* controller_interrupt_vector_data_vector_data_vector = interrupt_get_controller_interrupt_vector_data_vector_data_vector(); // Get the interrupt controller interrupt vector data vector data vector size size_t controller_interrupt_vector_data_vector_data_vector_size = interrupt_get_controller_interrupt_vector_data_vector_data_vector_size(); // Get the interrupt controller interrupt vector data vector data vector count size_t controller_interrupt_vector_data_vector_data_vector_count = interrupt_get_controller_interrupt_vector_data_vector_data_vector_count(); // Get the interrupt controller interrupt vector data vector data vector index size_t controller_interrupt_vector_data_vector_data_vector_index = interrupt_get_controller_interrupt_vector_data_vector_data_vector_index(); // Get the interrupt controller interrupt vector data vector data vector type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_vector_type = interrupt_get_controller_interrupt_vector_data_vector_data_vector_type(); // Get the interrupt controller interrupt vector data vector data vector priority priority_t controller_interrupt_vector_data_vector_data_vector_priority = interrupt_get_controller_interrupt_vector_data_vector_data_vector_priority(); // Get the interrupt controller interrupt vector data vector data vector mask bool controller_interrupt_vector_data_vector_data_vector_masked = interrupt_get_controller_interrupt_vector_data_vector_data_vector_masked(); // Get the interrupt controller interrupt vector data vector data vector pending bool controller_interrupt_vector_data_vector_data_vector_pending = interrupt_get_controller_interrupt_vector_data_vector_data_vector_pending(); // Get the interrupt controller interrupt vector data vector data vector enabled bool controller_interrupt_vector_data_vector_data_vector_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_vector_enabled(); // Get the interrupt controller interrupt vector data vector data vector handler interrupt_handler_t controller_interrupt_vector_data_vector_data_vector_handler = interrupt_get_controller_interrupt_vector_data_vector_data_vector_handler(); // Get the interrupt controller interrupt vector data vector data vector context interrupt_context_t controller_interrupt_vector_data_vector_data_vector_context = interrupt_get_controller_interrupt_vector_data_vector_data_vector_context(); // Get the interrupt controller interrupt vector data vector data vector data void* controller_interrupt_vector_data_vector_data_vector_data = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data(); // Get the interrupt controller interrupt vector data vector data vector data size size_t controller_interrupt_vector_data_vector_data_vector_data_size = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_size(); // Get the interrupt controller interrupt vector data vector data vector data count size_t controller_interrupt_vector_data_vector_data_vector_data_count = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_count(); // Get the interrupt controller interrupt vector data vector data vector data index size_t controller_interrupt_vector_data_vector_data_vector_data_index = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_index(); // Get the interrupt controller interrupt vector data vector data vector data type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_vector_data_type = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_type(); // Get the interrupt controller interrupt vector data vector data vector data priority priority_t controller_interrupt_vector_data_vector_data_vector_data_priority = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_priority(); // Get the interrupt controller interrupt vector data vector data vector data mask bool controller_interrupt_vector_data_vector_data_vector_data_masked = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_masked(); // Get the interrupt controller interrupt vector data vector data vector data pending bool controller_interrupt_vector_data_vector_data_vector_data_pending = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_pending(); // Get the interrupt controller interrupt vector data vector data vector data enabled bool controller_interrupt_vector_data_vector_data_vector_data_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_enabled(); // Get the interrupt controller interrupt vector data vector data vector data handler interrupt_handler_t controller_interrupt_vector_data_vector_data_vector_data_handler = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_handler(); // Get the interrupt controller interrupt vector data vector data vector data context interrupt_context_t controller_interrupt_vector_data_vector_data_vector_data_context = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_context(); // Get the interrupt controller interrupt vector data vector data vector data vector void* controller_interrupt_vector_data_vector_data_vector_data_vector = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector(); // Get the interrupt controller interrupt vector data vector data vector data vector size size_t controller_interrupt_vector_data_vector_data_vector_data_vector_size = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_size(); // Get the interrupt controller interrupt vector data vector data vector data vector count size_t controller_interrupt_vector_data_vector_data_vector_data_vector_count = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_count(); // Get the interrupt controller interrupt vector data vector data vector data vector index size_t controller_interrupt_vector_data_vector_data_vector_data_vector_index = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_index(); // Get the interrupt controller interrupt vector data vector data vector data vector type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_vector_data_vector_type = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_type(); // Get the interrupt controller interrupt vector data vector data vector data vector priority priority_t controller_interrupt_vector_data_vector_data_vector_data_vector_priority = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_priority(); // Get the interrupt controller interrupt vector data vector data vector data vector mask bool controller_interrupt_vector_data_vector_data_vector_data_vector_masked = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_masked(); // Get the interrupt controller interrupt vector data vector data vector data vector pending bool controller_interrupt_vector_data_vector_data_vector_data_vector_pending = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_pending(); // Get the interrupt controller interrupt vector data vector data vector data vector enabled bool controller_interrupt_vector_data_vector_data_vector_data_vector_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_enabled(); // Get the interrupt controller interrupt vector data vector data vector data vector handler interrupt_handler_t controller_interrupt_vector_data_vector_data_vector_data_vector_handler = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_handler(); // Get the interrupt controller interrupt vector data vector data vector data vector context interrupt_context_t controller_interrupt_vector_data_vector_data_vector_data_vector_context = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_context(); // Get the interrupt controller interrupt vector data vector data vector data vector data void* controller_interrupt_vector_data_vector_data_vector_data_vector_data = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data(); // Get the interrupt controller interrupt vector data vector data vector data vector size size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_size = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_size(); // Get the interrupt controller interrupt vector data vector data vector data vector count size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_count = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_count(); // Get the interrupt controller interrupt vector data vector data vector data vector index size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_index = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_index(); // Get the interrupt controller interrupt vector data vector data vector data vector type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_type = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_type(); // Get the interrupt controller interrupt vector data vector data vector data vector priority priority_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_priority = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_priority(); // Get the interrupt controller interrupt vector data vector data vector data vector mask bool controller_interrupt_vector_data_vector_data_vector_data_vector_masked = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_masked(); // Get the interrupt controller interrupt vector data vector data vector data vector pending bool controller_interrupt_vector_data_vector_data_vector_data_vector_pending = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_pending(); // Get the interrupt controller interrupt vector data vector data vector data vector enabled bool controller_interrupt_vector_data_vector_data_vector_data_vector_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_enabled(); // Get the interrupt controller interrupt vector data vector data vector data vector handler interrupt_handler_t controller_interrupt_vector_data_vector_data_vector_data_vector_handler = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_handler(); // Get the interrupt controller interrupt vector data vector data vector data vector context interrupt_context_t controller_interrupt_vector_data_vector_data_vector_data_vector_context = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_context(); // Get the interrupt controller interrupt vector data vector data vector data vector data void* controller_interrupt_vector_data_vector_data_vector_data_vector_data = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data(); // Get the interrupt controller interrupt vector data vector data vector data vector size size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_size = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_size(); // Get the interrupt controller interrupt vector data vector data vector data vector count size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_count = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_count(); // Get the interrupt controller interrupt vector data vector data vector data vector index size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_index = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_index(); // Get the interrupt controller interrupt vector data vector data vector data vector type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_type = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_type(); // Get the interrupt controller interrupt vector data vector data vector data vector priority priority_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_priority = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_priority(); // Get the interrupt controller interrupt vector data vector data vector data vector mask bool controller_interrupt_vector_data_vector_data_vector_data_vector_masked = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_masked(); // Get the interrupt controller interrupt vector data vector data vector data vector pending bool controller_interrupt_vector_data_vector_data_vector_data_vector_pending = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_pending(); // Get the interrupt controller interrupt vector data vector data vector data vector enabled bool controller_interrupt_vector_data_vector_data_vector_data_vector_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_enabled(); // Get the interrupt controller interrupt vector data vector data vector data vector handler interrupt_handler_t controller_interrupt_vector_data_vector_data_vector_data_vector_handler = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_handler(); // Get the interrupt controller interrupt vector data vector data vector data vector context interrupt_context_t controller_interrupt_vector_data_vector_data_vector_data_vector_context = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_context(); // Get the interrupt controller interrupt vector data vector data vector data vector data void* controller_interrupt_vector_data_vector_data_vector_data_vector_data = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data(); // Get the interrupt controller interrupt vector data vector data vector data vector size size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_size = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_size(); // Get the interrupt controller interrupt vector data vector data vector data vector count size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_count = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_count(); // Get the interrupt controller interrupt vector data vector data vector data vector index size_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_index = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_index(); // Get the interrupt controller interrupt vector data vector data vector data vector type interrupt_vector_data_type_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_type = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_type(); // Get the interrupt controller interrupt vector data vector data vector data vector priority priority_t controller_interrupt_vector_data_vector_data_vector_data_vector_data_priority = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_data_priority(); // Get the interrupt controller interrupt vector data vector data vector data vector mask bool controller_interrupt_vector_data_vector_data_vector_data_vector_masked = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_masked(); // Get the interrupt controller interrupt vector data vector data vector data vector pending bool controller_interrupt_vector_data_vector_data_vector_data_vector_pending = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_pending(); // Get the interrupt controller interrupt vector data vector data vector data vector enabled bool controller_interrupt_vector_data_vector_data_vector_data_vector_enabled = interrupt_get_controller_interrupt_vector_data_vector_data_vector_data_vector_enabled(); ``` -------------------------------- ### CPU API Reference Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/exceptions.rst Provides an overview of key functions within the CPU API for managing exceptions and program flow. ```APIDOC metal_cpu_get(hartid): Retrieves a handle to a CPU hart. Parameters: hartid: The ID of the CPU hart. Returns: A pointer to the metal_cpu structure or NULL on error. metal_cpu_interrupt_controller(cpu): Gets the interrupt controller associated with a CPU hart. Parameters: cpu: Pointer to the metal_cpu structure. Returns: A pointer to the metal_interrupt structure or NULL on error. metal_interrupt_init(interrupt): Initializes the interrupt controller. Parameters: interrupt: Pointer to the metal_interrupt structure. metal_cpu_exception_register(cpu, ecode, handler): Registers an exception handler for a specific exception code. Parameters: cpu: Pointer to the metal_cpu structure. ecode: The exception code to register the handler for. handler: The function pointer to the exception handler. Returns: 0 on success, non-zero on failure. metal_cpu_get_exception_pc(cpu): Retrieves the program counter (PC) of the faulting instruction. Parameters: cpu: Pointer to the metal_cpu structure. Returns: The address of the faulting instruction. metal_cpu_get_instruction_length(cpu, pc): Determines the length of the instruction at the given program counter. Parameters: cpu: Pointer to the metal_cpu structure. pc: The program counter address. Returns: The length of the instruction in bytes. metal_cpu_set_exception_pc(cpu, pc): Sets the program counter (PC) to resume execution from. Parameters: cpu: Pointer to the metal_cpu structure. pc: The new program counter address. ``` -------------------------------- ### Lock Primitives (metal/lock.h) Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/lock.rst This section details the lock primitives available in the metal/lock.h header file. It covers the core functionalities for managing mutual exclusion and synchronization within the Freedom Metal project. Dependencies include the underlying hardware or RTOS primitives that these locks abstract. ```c #include // Example usage of a mutex metal_mutex_t my_mutex; void init_mutex() { metal_mutex_init(&my_mutex); } void critical_section() { metal_mutex_acquire(&my_mutex); // Critical section code here metal_mutex_release(&my_mutex); } // Example usage of a spinlock metal_spinlock_t my_spinlock; void init_spinlock() { metal_spinlock_init(&my_spinlock); } void spinlock_section() { metal_spinlock_acquire(&my_spinlock); // Critical section code here metal_spinlock_release(&my_spinlock); } ``` -------------------------------- ### Time Functionality (C) Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/time.rst This section details the time-related functions provided by the metal/time.h header file. It covers the core timekeeping and manipulation capabilities within the Freedom Metal project. ```c /* * Doxygen documentation for metal/time.h */ // Placeholder for actual C code related to time functionality // For example: // time_t get_current_time(); // void sleep_ms(uint32_t milliseconds); ``` -------------------------------- ### Sifive Freedom Metal Caches Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/cache.rst This entry details the caching functionalities provided by the Sifive Freedom Metal project, as defined in the metal/cache.h header file. It serves as the primary reference for cache-related operations within the project. ```doxygen .. doxygenfile:: metal/cache.h :project: metal ``` -------------------------------- ### Freedom Metal Switch Header Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/switch.rst This snippet references the doxygen documentation for the switch functionality in the metal/switch.h header file within the /sifive/freedom-metal project. ```doxygen .. doxygenfile:: metal/switch.h :project: metal ``` -------------------------------- ### Preventing Metal Constructors/Destructors Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/init.rst Shows how to prevent the default execution of Metal constructors and destructors by redefining the `metal_init_run()` and `metal_fini_run()` functions in the application code. This allows for manual control over initialization and cleanup. ```C void metal_init_run() {} void metal_fini_run() {} ``` -------------------------------- ### Button Header File Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/button.rst This snippet references the doxygenfile for button functionalities. It is expected to contain C code related to button handling, including definitions, function prototypes, and possibly macros for button operations within the Freedom Metal project. ```c #include "metal/button.h" ``` -------------------------------- ### Return Execution After Faulting Instruction Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/exceptions.rst Demonstrates how to return execution to the instruction immediately following a faulting instruction. This involves retrieving the faulting instruction's program counter (PC), determining its length, and updating the exception PC. ```C void return_after_fault(struct metal_cpu *cpu, int ecode) { /* Get the faulting instruction address */ uintptr_t epc = metal_cpu_get_exception_pc(cpu); /* Get the length of the faulting instruction */ size_t len = metal_cpu_get_instruction_length(cpu, epc); /* Advance stored exception program counter by the * instruction length */ metal_cpu_set_exception_pc(cpu, epc + len); } ``` -------------------------------- ### MEE TTY Interface API Source: https://github.com/sifive/freedom-metal/blob/master/doc/mee-spec.md Offers a basic interface for outputting characters to a default terminal, intended for implementing functions like `printf`. ```APIDOC TTY Interface: `int mee_tty_putc(unsigned char c)` Writes the given character `c` to the default terminal. Returns 0 on success, -1 on failure. ``` -------------------------------- ### Freedom Metal Interrupt API Reference Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/devguide/interrupts.rst Provides an overview of the core structures and types used in Freedom Metal's interrupt handling mechanism, including the `metal_interrupt` structure and the `metal_interrupt_handler_t` function signature. ```APIDOC struct metal_interrupt: Represents a node in the interrupt controller hierarchy. metal_interrupt_handler_t: Signature for interrupt handler functions. void handler(int id, void *priv_data) id: The interrupt identifier. priv_data: Private data passed during handler registration. metal_cpu_get(int cpu_id): Retrieves a handle to a CPU. metal_cpu_interrupt_controller(struct metal_cpu *cpu): Gets the interrupt controller associated with a CPU. metal_interrupt_init(struct metal_interrupt *intr): Initializes an interrupt controller. metal_interrupt_enable(struct metal_interrupt *intr, int id): Enables a specific interrupt or the controller itself. Returns 0 on success, non-zero on failure. metal_interrupt_disable(struct metal_interrupt *intr, int id): Disables a specific interrupt or the controller itself. Returns 0 on success, non-zero on failure. metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu): Gets the timer interrupt controller for a CPU. metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu): Retrieves the interrupt ID for the CPU's timer. metal_interrupt_register_handler(struct metal_interrupt *intr, int id, metal_interrupt_handler_t handler, void *priv_data): Registers an interrupt handler for a given interrupt ID and controller. Returns 0 on success, non-zero on failure. ``` -------------------------------- ### TTY Header File Documentation Source: https://github.com/sifive/freedom-metal/blob/master/doc/sphinx/apiref/tty.rst This section details the TTY header file from the metal project. It likely contains definitions and declarations for TTY (teletypewriter) related functions and structures, crucial for terminal input/output operations. ```doxygen .. doxygenfile:: metal/tty.h :project: metal ```