Difference between revisions of "BAR Emulation Specification"

From Open-IOV
Jump to navigation Jump to search
(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 access
  • Bar1Rest - State restore
  • ForceBarAccess - Forced access
  • Bar1Aperture - Aperture changes
  • Bar1Size - Size queries

Reference

  • Handler: FUN_ram_04cb8188_ram_04cb8188.c (40 KB)
  • RPC Type: 0x0A (BAR_TRAP)
  • Jump Table Entry: 0x057675B7