khypervisor
v1
|
Go to the source code of this file.
Data Structures | |
struct | arch_regs |
struct | arch_regs_cop |
struct | arch_regs_banked |
struct | hyp_guest_context |
Defines | |
#define | ARCH_REGS_NUM_GPR 13 |
Enumerations | |
enum | hyp_hvc_result_t { HYP_RESULT_ERET = 0, HYP_RESULT_STAY = 1 } |
Functions | |
struct arch_regs | __attribute ((packed)) |
void | context_dump_regs (struct arch_regs *regs) |
void | context_switch_to_initial_guest (void) |
void | context_init_guests (void) |
hvmm_status_t | context_perform_switch (void) |
vmid_t | context_current_vmid (void) |
vmid_t | context_waiting_vmid (void) |
hvmm_status_t | context_switchto (vmid_t vmid) |
hvmm_status_t | context_switchto_lock (vmid_t vmid, uint8_t locked) |
vmid_t | context_first_vmid (void) |
vmid_t | context_last_vmid (void) |
vmid_t | context_next_vmid (vmid_t ofvmid) |
struct hyp_guest_context * | context_atvmid (vmid_t vmid) |
void | start_guest_os (void) |
Variables | |
uint32_t | cpsr |
uint32_t | pc |
uint32_t | lr |
uint32_t | gpr [ARCH_REGS_NUM_GPR] |
struct arch_regs_cop | __attribute |
#define ARCH_REGS_NUM_GPR 13 |
enum hyp_hvc_result_t |
Definition at line 11 of file context.h.
{ HYP_RESULT_ERET = 0, HYP_RESULT_STAY = 1 } hyp_hvc_result_t;
struct arch_regs __attribute | ( | (packed) | ) |
struct hyp_guest_context* context_atvmid | ( | vmid_t | vmid | ) | [read] |
Definition at line 526 of file context.c.
{ struct hyp_guest_context * result = 0; if ( vmid < NUM_GUEST_CONTEXTS ) { result = &guest_contexts[vmid]; } return result; }
vmid_t context_current_vmid | ( | void | ) |
Definition at line 562 of file context.c.
{ return _current_guest_vmid; }
void context_dump_regs | ( | struct arch_regs * | regs | ) |
Definition at line 145 of file context.c.
{ #ifdef DEBUG uart_print( "cpsr:" ); uart_print_hex32( regs->cpsr ); uart_print( "\n\r" ); uart_print( " pc:" ); uart_print_hex32( regs->pc ); uart_print( "\n\r" ); uart_print( " lr:" ); uart_print_hex32( regs->lr ); uart_print( "\n\r" ); #ifdef __CONTEXT_TRACE_VERBOSE__ { int i; uart_print( " gpr:\n\r" ); for( i = 0; i < ARCH_REGS_NUM_GPR; i++) { uart_print( " " ); uart_print_hex32( regs->gpr[i] ); uart_print( "\n\r" ); } } #endif #endif }
vmid_t context_first_vmid | ( | void | ) |
void context_init_guests | ( | void | ) |
Definition at line 468 of file context.c.
{ struct hyp_guest_context *context; struct arch_regs *regs = 0; uart_print("[hyp] init_guests: enter\n\r"); /* Guest 1 @guest_bin_start */ context = &guest_contexts[0]; regs = &context->regs; regs->cpsr = 0x1d3; // supervisor, interrupt disabled #if defined (LINUX_GUEST) regs->pc = 0xA0008000; // PA:0xA0008000, where zImage is regs->gpr[1] = CFG_MACHINE_NUMBER; regs->gpr[2] = 0x80000100; //src+(0x100/4); #else regs->pc = 0x80000000; // PA:0xA0000000, default entry for bmguest #endif /* regs->gpr[] = whatever */ context->vmid = 0; context->ttbl = vmm_vmid_ttbl(context->vmid); context_init_cops( &context->regs_cop ); context_init_banked( &context->regs_banked ); vgic_init_status( &context->vgic_status, context->vmid ); /* Guest 2 @guest2_bin_start */ context = &guest_contexts[1]; regs = &context->regs; regs->pc = 0x80000000; // PA: 0xB0000000 regs->cpsr = 0x1d3; // supervisor, interrupt disabled /* regs->gpr[] = whatever */ context->vmid = 1; context->ttbl = vmm_vmid_ttbl(context->vmid); context_init_cops( &context->regs_cop ); context_init_banked( &context->regs_banked ); vgic_init_status( &context->vgic_status, context->vmid ); #if defined (LINUX_GUEST) _hyp_guest0_copy_zimage(); #elif defined (BAREMETAL_GUEST) /* Workaround for unloaded bmguest.bin at 0xB0000000@PA */ _hyp_fixup_unloaded_guest(); #endif #if defined (LINUX_GUEST) { extern uint32_t guest_bin_start; uint32_t *src = &guest_bin_start; loadlinux_setup_tags(src); } #endif uart_print("[hyp] init_guests: return\n\r"); }
vmid_t context_last_vmid | ( | void | ) |
vmid_t context_next_vmid | ( | vmid_t | ofvmid | ) |
Definition at line 550 of file context.c.
{ vmid_t next = VMID_INVALID; if ( ofvmid == VMID_INVALID ) { next = context_first_vmid(); } else if ( ofvmid < context_last_vmid() ) { /* FIXME:Hardcoded */ next = ofvmid + 1; } return next; }
hvmm_status_t context_perform_switch | ( | void | ) |
Definition at line 419 of file context.c.
{ hvmm_status_t result = HVMM_STATUS_IGNORED; if ( _current_guest_vmid == VMID_INVALID ) { printh("context: launching the first guest\n"); /* very first time, to the default first guest */ result = context_perform_switch_to_guest_regs( 0, _next_guest_vmid ); /* DOES NOT COME BACK HERE */ } else if ( _next_guest_vmid != VMID_INVALID && _current_guest_vmid != _next_guest_vmid ) { struct arch_regs *regs = trap_saved_regs(); if ( (regs->cpsr & 0x1F) != 0x1A ) { printh("curr: %x\n", _current_guest_vmid); printh("next: %x\n", _next_guest_vmid); /* Only if not from Hyp */ result = context_perform_switch_to_guest_regs( regs, _next_guest_vmid ); _next_guest_vmid = VMID_INVALID; } } else { /* Staying at the currently active guest. Flush out queued virqs since we didn't have a chance to switch the context, where virq flush takes place, this time */ vgic_flush_virqs(_current_guest_vmid); } _switch_locked = 0; return result; }
void context_switch_to_initial_guest | ( | void | ) |
Definition at line 447 of file context.c.
{ struct hyp_guest_context *context = 0; struct arch_regs *regs = 0; uart_print("[hyp] switch_to_initial_guest:\n\r"); /* Select the first guest context to switch to. */ _current_guest_vmid = VMID_INVALID; context = &guest_contexts[0]; /* Dump the initial register values of the guest for debugging purpose */ regs = &context->regs; context_dump_regs( regs ); /* Context Switch with current context == none */ context_switchto(0); context_perform_switch(); }
hvmm_status_t context_switchto | ( | vmid_t | vmid | ) |
Definition at line 572 of file context.c.
{ return context_switchto_lock(vmid, 0); }
hvmm_status_t context_switchto_lock | ( | vmid_t | vmid, |
uint8_t | locked | ||
) |
Definition at line 577 of file context.c.
{ hvmm_status_t result = HVMM_STATUS_IGNORED; HVMM_TRACE_ENTER(); /* valid and not current vmid, switch */ if (_switch_locked == 0) { if ( !_valid_vmid(vmid) ) { result = HVMM_STATUS_BAD_ACCESS; } else { _next_guest_vmid = vmid; result = HVMM_STATUS_SUCCESS; printh("switching to vmid: %x\n", (uint32_t)vmid); } } else { printh("context: next vmid locked to %d\n", _next_guest_vmid ); } if ( locked ) _switch_locked = locked; HVMM_TRACE_EXIT(); return result; }
vmid_t context_waiting_vmid | ( | void | ) |
Definition at line 567 of file context.c.
{ return _next_guest_vmid; }
void start_guest_os | ( | void | ) |
Definition at line 604 of file context.c.
{ init_print(); hvmm_status_t ret = HVMM_STATUS_UNKNOWN_ERROR; printh("[%s : %d] Starting...\n", __FUNCTION__, __LINE__); /* Initialize Memory Management */ ret = hvmm_mm_init(); /* Initialize Interrupt Management */ ret = hvmm_interrupt_init(); if ( ret != HVMM_STATUS_SUCCESS ) { uart_print("[hyp_main] interrupt initialization failed...\n\r"); } /* Initialize Guests */ context_init_guests(); /* Initialize Virtual Devices */ vdev_init(); /* Virtual GIC Distributor */ printh( "tests: Registering sample vdev:'vgicd' at %x\n", CFG_GIC_BASE_PA | GIC_OFFSET_GICD); vdev_gicd_init(CFG_GIC_BASE_PA | GIC_OFFSET_GICD); /* Initialize PIRQ to VIRQ mapping */ virqmap_init(); /* Start Scheduling */ scheduler_test_scheduling(); /* Begin running test code for newly implemented features */ hvmm_tests_main(); /* Print Banner */ printH("%s", BANNER_STRING); /* Switch to the first guest */ context_switch_to_initial_guest(); /* The code flow must not reach here */ uart_print("[hyp_main] ERROR: CODE MUST NOT REACH HERE\n\r"); hyp_abort_infinite(); }
struct arch_regs_cop __attribute |