188 lines
4.6 KiB
Markdown
188 lines
4.6 KiB
Markdown
# API Reference
|
|
|
|
ReviveSparc provides a C API for embedding the SPARC emulator in other projects.
|
|
|
|
## Core API
|
|
|
|
### Initialization
|
|
|
|
```c
|
|
#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.
|
|
|
|
```c
|
|
// Create with custom configuration
|
|
sparc_t *sparc_new_with_config(const sparc_config_t *config);
|
|
```
|
|
|
|
```c
|
|
// Free a SPARC instance
|
|
void sparc_free(sparc_t *cpu);
|
|
```
|
|
|
|
### Loading Programs
|
|
|
|
```c
|
|
// 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
|
|
|
|
```c
|
|
// 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
|
|
|
|
```c
|
|
// 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
|
|
|
|
```c
|
|
// 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
|
|
|
|
```c
|
|
// 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
|
|
|
|
```c
|
|
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:
|
|
|
|
```c
|
|
// 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
|
|
|
|
```c
|
|
#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:
|
|
|
|
```bash
|
|
cc -o myemu myemu.c -lrevivesparc
|
|
```
|