Files
main-website/docs/api-reference.md
T
2026-06-15 19:20:24 +02:00

4.6 KiB

API Reference

ReviveSparc provides a C API for embedding the SPARC emulator in other projects.

Core API

Initialization

#include <revivesparc.h>

// Create a new SPARC CPU instance
sparc_t *sparc_new(sparc_isa_t isa);

Parameters:

  • isa: SPARC_V9 for 64-bit mode, SPARC_V8 for 32-bit compatibility mode

Returns: Pointer to a new SPARC instance, or NULL on failure.

// Create with custom configuration
sparc_t *sparc_new_with_config(const sparc_config_t *config);
// Free a SPARC instance
void sparc_free(sparc_t *cpu);

Loading Programs

// Load an ELF file into memory
int sparc_load_elf(sparc_t *cpu, const char *path);

// Load a flat binary into memory at a specific address
int sparc_load_binary(sparc_t *cpu, const char *path, uint64_t addr);

// Load a file into memory at a specific offset
int sparc_load_file(sparc_t *cpu, const char *path, uint64_t addr);

All load functions return 0 on success, -1 on error.

Execution Control

// Reset the CPU to initial state
void sparc_reset(sparc_t *cpu);

// Run for a specified number of instructions
uint64_t sparc_run(sparc_t *cpu, uint64_t num_insts);

// Run until a breakpoint is hit
uint64_t sparc_run_until_break(sparc_t *cpu);

// Step a single instruction
int sparc_step(sparc_t *cpu);

// Stop execution (called from interrupt handler)
void sparc_stop(sparc_t *cpu);

Returns the actual number of instructions executed.

Register Access

// Read/write general-purpose registers
uint64_t sparc_get_gpr(sparc_t *cpu, int reg);
void     sparc_set_gpr(sparc_t *cpu, int reg, uint64_t val);

// Read/write special registers
uint64_t sparc_get_pc(sparc_t *cpu);
void     sparc_set_pc(sparc_t *cpu, uint64_t val);

uint64_t sparc_get_npc(sparc_t *cpu);
void     sparc_set_npc(sparc_t *cpu, uint64_t val);

// Floating-point registers
double   sparc_get_fpr(sparc_t *cpu, int reg);
void     sparc_set_fpr(sparc_t *cpu, int reg, double val);

// Privileged registers
uint64_t sparc_get_priv(sparc_t *cpu, sparc_priv_reg_t reg);
void     sparc_set_priv(sparc_t *cpu, sparc_priv_reg_t reg, uint64_t val);

Memory Access

// Direct memory access (bypasses MMU)
int sparc_mem_write(sparc_t *cpu, uint64_t addr, const void *buf, size_t len);
int sparc_mem_read(sparc_t *cpu, uint64_t addr, void *buf, size_t len);

// Virtual memory access (through MMU)
int sparc_virt_write(sparc_t *cpu, uint64_t addr, const void *buf, size_t len);
int sparc_virt_read(sparc_t *cpu, uint64_t addr, void *buf, size_t len);

Returns the number of bytes read/written, or -1 on error.

Debugging

// Set a breakpoint at a virtual address
int sparc_breakpoint_set(sparc_t *cpu, uint64_t addr);

// Clear a breakpoint
int sparc_breakpoint_clear(sparc_t *cpu, uint64_t addr);

// Get disassembly of an instruction
const char *sparc_disassemble(sparc_t *cpu, uint64_t addr);

// Set tracing level
void sparc_set_trace(sparc_t *cpu, int level);

Configuration Structures

typedef struct {
    int          num_cores;     // Number of cores (1-8)
    int          threads_per_core; // Threads per core (1-4)
    sparc_mem_t  memory_model;  // TSO, PSO, or RMO
    sparc_sched_t sched_mode;   // Fine or coarse-grained
    uint64_t     mem_size;      // Main memory size in bytes
    int          l1i_size;      // L1 I-cache size in bytes
    int          l1d_size;      // L1 D-cache size in bytes
    int          l2_size;       // L2 cache size in bytes
    int          num_windows;   // Number of register windows (8-32)
} sparc_config_t;

Error Handling

Most functions return 0 on success and -1 on error. Detailed error information can be retrieved:

// Get the last error message
const char *sparc_error(sparc_t *cpu);

// Get the last error code
int sparc_errno(sparc_t *cpu);

Example: Embedded Emulator

#include <stdio.h>
#include <revivesparc.h>

int main(int argc, char **argv) {
    sparc_t *cpu = sparc_new(SPARC_V9);
    if (!cpu) {
        fprintf(stderr, "Failed to create CPU\n");
        return 1;
    }

    sparc_config_t config = {
        .num_cores   = 1,
        .mem_size    = 256 * 1024 * 1024,
        .memory_model = MEM_TSO
    };
    sparc_configure(cpu, &config);

    if (sparc_load_elf(cpu, argv[1]) != 0) {
        fprintf(stderr, "Failed to load ELF: %s\n", sparc_error(cpu));
        return 1;
    }

    sparc_reset(cpu);
    uint64_t insts = sparc_run(cpu, 1000000);
    printf("Executed %lu instructions\n", insts);
    printf("Final PC: 0x%lx\n", sparc_get_pc(cpu));

    sparc_free(cpu);
    return 0;
}

Compile with:

cc -o myemu myemu.c -lrevivesparc