|
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 |
1.7.6.1