Integration with VM system - retrotruestory/M1DEV GitHub Wiki

Here's how to implement integration between the Magic-1 VM system and other components:

        .cseg
        .global _init_vm_integration
        .global _vm_call_host
        .global _vm_interrupt_handler

// Initialize VM integration
_init_vm_integration:
        enter   8
        push    a
        push    b
        
        // Setup VM trap handlers
        ld.16   b,#VM_TRAP_TABLE
        ld.16   a,#_vm_syscall_handler
        st.16   (b),a          ; System call handler
        
        add.16  b,#2
        ld.16   a,#_vm_interrupt_handler
        st.16   (b),a          ; Interrupt handler
        
        pop     b
        pop     a
        leave
        ret

// Handle VM to host calls
_vm_call_host:
        enter   4
        push    b
        
        ld.16   b,6(sp)        ; Get function ID
        
        // Map virtual to physical address
        push    b
        call    _vm_translate_addr
        pop     b
        
        // Execute host function
        call    b
        
        pop     b
        leave
        ret

Create the integration interface:

#ifndef VM_INTEGRATION_H
#define VM_INTEGRATION_H

#include <stdint.h>

// VM integration types
#define VM_HOST_CALL    1
#define VM_INTERRUPT    2
#define VM_TRAP         3

// VM state structure
typedef struct {
    uint16_t vm_flags;     // VM status flags
    uint16_t host_sp;      // Host stack pointer
    uint16_t vm_sp;        // VM stack pointer
    void*    vm_context;   // Current VM context
} vm_state_t;

// Function declarations
extern void init_vm_integration(void);
extern int vm_call_host(int func_id, void* params);
extern void vm_interrupt_handler(int irq);

#endif

Implement the VM integration layer:

#include "vm_integration.h"
#include "vm_memory.h"

static vm_state_t vm_state;

// Initialize VM integration
void init_vm_system(void) {
    // Initialize hardware VM support
    init_vm_memory();
    
    // Setup VM state
    vm_state.vm_flags = 0;
    vm_state.vm_sp = VM_STACK_TOP;
    vm_state.vm_context = NULL;
    
    // Initialize integration layer
    init_vm_integration();
}

// Switch from VM to host context
void vm_to_host_switch(void) {
    // Save VM state
    save_vm_context(&vm_state);
    
    // Switch to host stack
    __asm__(
        "copy sp,%0\n\t"      // Save VM stack
        "ld.16 sp,%1"         // Load host stack
        : "=m"(vm_state.vm_sp)
        : "m"(vm_state.host_sp)
    );
}

// Switch from host to VM context
void host_to_vm_switch(void) {
    // Switch to VM stack
    __asm__(
        "copy sp,%0\n\t"      // Save host stack
        "ld.16 sp,%1"         // Load VM stack
        : "=m"(vm_state.host_sp)
        : "m"(vm_state.vm_sp)
    );
    
    // Restore VM state
    restore_vm_context(&vm_state);
}

Add device access integration:

#include "vm_integration.h"
#include "hw_control.h"

// VM UART driver structure
typedef struct {
    uint16_t vm_base;      // VM-visible base address
    uint16_t host_base;    // Host physical address
    vm_state_t* vm_state; // VM context
} vm_uart_t;

// Initialize VM UART
void init_vm_uart(vm_uart_t* uart, uint16_t vm_base, uint16_t host_base) {
    uart->vm_base = vm_base;
    uart->host_base = host_base;
    
    // Map device in VM space
    map_device_page(host_base, vm_base);
    
    // Initialize hardware
    hw_write(host_base + 3, 0x80);   // Enable DLAB
    hw_write(host_base + 0, 0x0C);   // Set baud rate
    hw_write(host_base + 3, 0x03);   // 8N1, disable DLAB
}

// Handle VM UART interrupt
void vm_uart_interrupt(vm_uart_t* uart) {
    // Save host context
    vm_to_host_switch();
    
    // Handle interrupt
    uint8_t status = hw_read(uart->host_base + 5);
    if(status & 0x01) {
        // Data available
        uint8_t data = hw_read(uart->host_base);
        // Queue data for VM
        queue_vm_data(uart->vm_state, data);
    }
    
    // Return to VM
    host_to_vm_switch();
}

Example usage:

#include <stdio.h>
#include "vm_integration.h"
#include "vm_devices.h"

int main() {
    // Initialize VM system
    init_vm_system();
    
    // Setup VM UART
    vm_uart_t console_uart;
    init_vm_uart(&console_uart, VM_UART0_ADDR, UART0_BASE);
    
    // Create and start VM
    vm_state_t vm;
    vm.vm_flags = 0;
    vm.vm_context = create_vm_context();
    
    // Switch to VM execution
    host_to_vm_switch();
    
    // VM executes until exit
    run_vm(&vm);
    
    // Cleanup
    destroy_vm_context(vm.vm_context);
    
    return 0;
}

Update Makefile:

CC = clcc
AS = m1_as
CFLAGS = -O2
OBJECTS = vm_integration.o vm_devices.o test_integration.o

test_integration: $(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $(OBJECTS)

%.o: %.s
    $(AS) -o $@ $<

%.o: %.c
    $(CC) $(CFLAGS) -c $<

clean:
    rm -f test_integration *.o

Key features:

  1. Seamless Integration

    • VM/Host context switching
    • Shared device access
    • Interrupt handling
    • Memory mapping
  2. Resource Management

  3. Communication

    • VM to host calls
    • Host to VM callbacks
    • Shared memory regions
    • Event notification
  4. Safety

    • Context isolation
    • Protected mode transitions
    • Resource access control
    • Error handling

This implementation provides a complete integration between the VM and host system, allowing controlled access to hardware while maintaining isolation and protection.

⚠️ **GitHub.com Fallback** ⚠️