khypervisor  v1
Data Structures | Defines | Enumerations | Functions | Variables
context.h File Reference
#include <k-hypervisor-config.h>
#include "arch_types.h"
#include "vgic.h"
#include "lpae.h"
Include dependency graph for context.h:
This graph shows which files directly or indirectly include this file:

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_contextcontext_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 Documentation

#define ARCH_REGS_NUM_GPR   13

Definition at line 9 of file context.h.


Enumeration Type Documentation

Enumerator:
HYP_RESULT_ERET 
HYP_RESULT_STAY 

Definition at line 11 of file context.h.


Function Documentation

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;
}

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
}

Definition at line 538 of file context.c.

{
    /* FIXME:Hardcoded for now */
    return 0;
}
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");
}

Here is the call graph for this function:

Definition at line 544 of file context.c.

{
    /* FIXME:Hardcoded for now */
    return 1;
}

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;
}

Here is the call graph for this function:

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;
}

Here is the call graph for this function:

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();
}

Here is the call graph for this function:

Definition at line 572 of file context.c.

{
    return context_switchto_lock(vmid, 0);
}

Here is the call graph for this function:

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;
}

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();
}

Here is the call graph for this function:


Variable Documentation

Definition at line 22 of file context.h.

Definition at line 25 of file context.h.

Definition at line 24 of file context.h.

syntax unified arch_extension sec arch_extension virt text align SCR r10 bic ldr r11 mcr isb Use monitor_secure_vectors as temporary Hyp exception vector for Hyp mode entrance ldr return in NS state movs lr elr_hyp mov pc

Definition at line 23 of file context.h.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines