Difference between revisions of "BAR Emulation Specification"
(Remove unpaired blockquote tags left by reference cleanup) |
(No difference)
|
Revision as of 03:58, 12 October 2026
BAR Emulation Specification (GSP 570.144W)
Overview
Key Addresses
| Component | Address | Description |
|---|---|---|
| BAR Trap Handler | 0x04CB8188 | Main emulation logic (40 KB) |
| RPC Jump Table Entry | 0x057675B7 | BAR_TRAP in secondary dispatcher |
| String: BAR1 | 0x0406570E, 0x04085DE0 | BAR1 identifier |
| String: Bar1Rest | 0x040656DA | BAR1 restore state |
| String: ForceBarAccess | 0x040656F2 | Forced access control |
| String: Bar1Aperture | 0x04065722 | Aperture configuration |
| Memory Allocator | 0x429B450 | Arena for BAR backing store |
| Cache Management | 0x429B428 | Flush/invalidate |
Handler State Machine
Main Loop (0x04CB8188)
The handler runs a continuous event loop processing BAR trap requests:
<syntaxhighlight lang="c">while (true) {
// Wait for trap event (bitmask in unaff_s5)
event = wait_for_bar_event;
switch (event & 0x3F) {
case 0x01: // BAR1 write access
handle_bar1_write;
break;
case 0x02: // BAR1 read access
handle_bar1_read;
break;
case 0x08: // Aperture configuration
handle_aperture_config;
break;
case 0x10: // ForceBarAccess
handle_force_access;
break;
case 0x20: // Bar1Rest (restore)
handle_bar1_restore;
break;
default:
return ERROR_UNKNOWN_EVENT;
}
}</syntaxhighlight>
Event Bitmask
| Bit | Event | Description |
|---|---|---|
| 0 | BAR1_WRITE | Guest VF wrote to BAR1 |
| 1 | BAR1_READ | Guest VF read from BAR1 |
| 3 | APERTURE | Aperture size/offset change |
| 4 | FORCE_ACCESS | ForceBarAccess triggered |
| 5 | BAR1_REST | Restore BAR1 state |
Memory Management
Allocator Arena (0x429B450)
<syntaxhighlight lang="c">// Allocate backing store for BAR emulation void *bar_alloc(size_t size) {
// Calls UNK_ram_058A1A9C(0x429B450, size) // Returns pointer in 0x429B000 region
}
// Free backing store void bar_free(void *ptr) {
// Calls UNK_ram_05895BF4(0x429B428, ptr)
}</syntaxhighlight>
Allocation Sizes
- Standard BAR1 page: 0x1000 (4 KB)
- Aperture buffer: 0x40000 (256 KB) max
- Force access buffer: 0x1000 (4 KB)
Cache Coherency
<syntaxhighlight lang="c">// Flush cache for DMA void bar_cache_flush(void *addr, size_t size) {
UNK_ram_05895BF4(0x429B428, addr); UNK_ram_05895BF4(0x429B428, addr + size);
}</syntaxhighlight>
BAR1 Emulation Logic
Write Path (Event 0x01)
<syntaxhighlight lang="c">int handle_bar1_write(bar_trap_t *trap) {
// 1. Validate offset within aperture
if (trap->offset >= bar1_aperture_size)
return ERROR_OVERFLOW;
// 2. Check ForceBarAccess flag
if (force_bar_access && !(trap->flags & FORCE_ALLOWED))
return ERROR_PERMISSION;
// 3. Translate to backing store
uint8_t *backing = bar1_backing + trap->offset;
// 4. Perform write (1/2/4/8 bytes)
switch (trap->size) {
case 1: *backing = trap->value; break;
case 2: *(uint16_t*)backing = trap->value; break;
case 4: *(uint32_t*)backing = trap->value; break;
case 8: *(uint64_t*)backing = trap->value; break;
}
// 5. Flush to device if needed
if (device_needs_flush)
bar_cache_flush(backing, trap->size);
return OK;
}</syntaxhighlight>
Read Path (Event 0x02)
<syntaxhighlight lang="c">int handle_bar1_read(bar_trap_t *trap) {
if (trap->offset >= bar1_aperture_size)
return ERROR_OVERFLOW;
uint8_t *backing = bar1_backing + trap->offset;
switch (trap->size) {
case 1: *trap->out_value = *backing; break;
case 2: *trap->out_value = *(uint16_t*)backing; break;
case 4: *trap->out_value = *(uint32_t*)backing; break;
case 8: *trap->out_value = *(uint64_t*)backing; break;
}
return OK;
}</syntaxhighlight>
Aperture Configuration (Event 0x08)
<syntaxhighlight lang="c">int handle_aperture_config(bar_config_t *cfg) {
// Validate new aperture
if (cfg->size > MAX_APERTURE_SIZE) // 0x40000
return ERROR_INVALID;
if (cfg->offset & 0xFFF) // Must be 4KB aligned
return ERROR_ALIGNMENT;
// Reallocate backing store if size changed
if (cfg->size != bar1_aperture_size) {
void *new_backing = bar_alloc(cfg->size);
if (!new_backing) return ERROR_NOMEM;
// Copy existing data
memcpy(new_backing, bar1_backing,
min(cfg->size, bar1_aperture_size));
bar_free(bar1_backing);
bar1_backing = new_backing;
bar1_aperture_size = cfg->size;
}
bar1_aperture_offset = cfg->offset;
return OK;
}</syntaxhighlight>
ForceBarAccess (Event 0x10)
<syntaxhighlight lang="c">int handle_force_access(force_access_t *fa) {
// ForceBarAccess allows hypervisor to bypass VF permissions
// Used for live migration, checkpoint/restore
force_bar_access = fa->enable;
force_access_vf = fa->vf_id;
force_access_range = fa->range;
// Allocate shadow buffer for forced operations
if (fa->enable) {
force_buffer = bar_alloc(0x1000);
if (!force_buffer) return ERROR_NOMEM;
} else {
bar_free(force_buffer);
force_buffer = NULL;
}
return OK;
}</syntaxhighlight>
Bar1Rest - State Restore (Event 0x20)
<syntaxhighlight lang="c">int handle_bar1_restore(restore_state_t *rs) {
// Restore BAR1 state from checkpoint
// Used during VF live migration
bar1_aperture_offset = rs->aperture_offset;
bar1_aperture_size = rs->aperture_size;
force_bar_access = rs->force_access;
// Restore backing store from serialized data
if (rs->backing_size > 0) {
void *new_backing = bar_alloc(rs->backing_size);
if (!new_backing) return ERROR_NOMEM;
memcpy(new_backing, rs->backing_data, rs->backing_size);
bar_free(bar1_backing);
bar1_backing = new_backing;
}
return OK;
}</syntaxhighlight>
vGPU-IO Integration
Kernel BAR Trap Registration
<syntaxhighlight lang="c">struct gsp_bar_ops {
int (*bar_trap)(struct gsp_device *gsp,
struct bar_trap_msg *msg);
int (*configure_aperture)(struct gsp_device *gsp,
uint32_t vf_id,
uint64_t offset, uint64_t size);
int (*force_access)(struct gsp_device *gsp,
uint32_t vf_id, bool enable);
int (*save_state)(struct gsp_device *gsp,
uint32_t vf_id, void *buf, size_t *size);
int (*restore_state)(struct gsp_device *gsp,
uint32_t vf_id, void *buf, size_t size);
};
static const struct gsp_bar_ops gsp_bar_ops = {.bar_trap = gsp_bar_trap_handler,.configure_aperture = gsp_bar_config_aperture,.force_access = gsp_bar_force_access,.save_state = gsp_bar_save_state,.restore_state = gsp_bar_restore_state, };</syntaxhighlight>
VF BAR Configuration
<syntaxhighlight lang="c">int gsp_vf_bar_init(struct gsp_vf *vf) {
struct bar_config cfg = {.vf_id = vf->id,.bar = 1, // BAR1.aperture_offset = vf->bar1_offset,.aperture_size = vf->bar1_size,.flags = BAR_FLAG_COHERENT,
};
return gsp_rpc_send(vf->gsp, RPC_BAR_TRAP,
BAR_SUBCMD_CONFIG, &cfg, sizeof(cfg));
}</syntaxhighlight>
Live Migration Support
<syntaxhighlight lang="c">// Save BAR state for migration int gsp_vf_bar_save(struct gsp_vf *vf, void *buf, size_t *size) {
struct bar_save_msg msg = {.vf_id = vf->id,.bar = 1,
};
return gsp_rpc_send(vf->gsp, RPC_BAR_TRAP,
BAR_SUBCMD_SAVE, &msg, sizeof(msg),
buf, size);
}
// Restore BAR state on destination int gsp_vf_bar_restore(struct gsp_vf *vf, void *buf, size_t size) {
struct bar_restore_msg msg = {.vf_id = vf->id,.bar = 1,.data = buf,.data_size = size,
};
return gsp_rpc_send(vf->gsp, RPC_BAR_TRAP,
BAR_SUBCMD_RESTORE, &msg, sizeof(msg));
}</syntaxhighlight>
Error Handling
| Error | Code | Recovery |
|---|---|---|
| OOM (0x51) | Allocator exhausted | Shrink aperture, retry |
| Timeout (0x1E) | Cache flush timeout | Reset BAR, reinitialize |
| Invalid (0x1F) | Bad aperture config | Validate alignment/size |
| Permission (0xFFFF) | ForceAccess violation | Check VF permissions |
| Overflow (0x25) | Offset beyond aperture | Bounds check in VF driver |
Debugging
Key Registers to Monitor
0x04296048: Global error flag (cRam0000000004296048) 0x0429B750: Error status (0x111300 offset) 0x429B428: Cache management base 0x429B450: Allocator arena base
Log Strings
Search for these in GSP logs:
BAR1- BAR1 accessBar1Rest- State restoreForceBarAccess- Forced accessBar1Aperture- Aperture changesBar1Size- Size queries
Reference
- Handler:
FUN_ram_04cb8188_ram_04cb8188.c(40 KB) - RPC Type: 0x0A (BAR_TRAP)
- Jump Table Entry: 0x057675B7