khypervisor  v1
Data Structures | Defines | Functions | Variables
vmm.c File Reference
#include <k-hypervisor-config.h>
#include <arch_types.h>
#include "vmm.h"
#include <armv7_p15.h>
#include <hvmm_trace.h>
#include <gic_regs.h>
#include <config/cfg_platform.h>
#include <log/print.h>
Include dependency graph for vmm.c:

Go to the source code of this file.

Data Structures

struct  memmap_desc

Defines

#define VMM_L1_PTE_NUM   4
#define VMM_L1_PADDING_PTE_NUM   (512 - VMM_L1_PTE_NUM)
#define VMM_L2_PTE_NUM   512
#define VMM_L3_PTE_NUM   512
#define VMM_L2L3_PTE_NUM_TOTAL   (VMM_L2_PTE_NUM * VMM_L3_PTE_NUM + VMM_L2_PTE_NUM)
#define VMM_PTE_NUM_TOTAL
#define VTTBR_INITVAL   0x0000000000000000ULL
#define VTTBR_VMID_MASK   0x00FF000000000000ULL
#define VTTBR_VMID_SHIFT   48
#define VTTBR_BADDR_MASK   0x000000FFFFFFF000ULL
#define VTTBR_BADDR_SHIFT   12
#define VTCR_INITVAL   0x80000000
#define VTCR_SH0_MASK   0x00003000
#define VTCR_SH0_SHIFT   12
#define VTCR_ORGN0_MASK   0x00000C00
#define VTCR_ORGN0_SHIFT   10
#define VTCR_IRGN0_MASK   0x00000300
#define VTCR_IRGN0_SHIFT   8
#define VTCR_SL0_MASK   0x000000C0
#define VTCR_SL0_SHIFT   6
#define VTCR_S_MASK   0x00000010
#define VTCR_S_SHIFT   4
#define VTCR_T0SZ_MASK   0x00000003
#define VTCR_T0SZ_SHIFT   0
#define TTBL_L3(ttbl_l2, index_l2)   (&ttbl_l2[VMM_L2_PTE_NUM + (VMM_L3_PTE_NUM * (index_l2))])
#define TTBL_L2(ttbl_l1, index_l1)   (&ttbl_l1[(VMM_L1_PTE_NUM + VMM_L1_PADDING_PTE_NUM) + (VMM_L2L3_PTE_NUM_TOTAL * (index_l1))])

Functions

static lpaed_t _ttbl_guest0[VMM_PTE_NUM_TOTAL__attribute ((__aligned__(4096)))
static void vmm_ttbl3_map (lpaed_t *ttbl3, uint64_t offset, uint32_t pages, uint64_t pa, lpaed_stage2_memattr_t mattr)
static void vmm_ttbl3_unmap (lpaed_t *ttbl3, uint64_t offset, uint32_t pages)
static void vmm_ttbl2_unmap (lpaed_t *ttbl2, uint64_t va_offset, uint32_t size)
static void vmm_ttbl2_map (lpaed_t *ttbl2, uint64_t va_offset, uint64_t pa, uint32_t size, lpaed_stage2_memattr_t mattr)
static void vmm_ttbl2_init_entries (lpaed_t *ttbl2)
static void vmm_init_ttbl2 (lpaed_t *ttbl2, struct memmap_desc *md)
static void vmm_init_ttbl (lpaed_t *ttbl, struct memmap_desc *mdlist[])
static void vmm_init_mmu (void)
void vmm_init (void)
lpaed_tvmm_vmid_ttbl (vmid_t vmid)
void vmm_stage2_enable (int enable)
hvmm_status_t vmm_set_vmid_ttbl (vmid_t vmid, lpaed_t *ttbl)

Variables

uint32_t guest_bin_start
uint32_t guest2_bin_start
static lpaed_t_vmid_ttbl [NUM_GUESTS_STATIC]
static struct memmap_desc guest_md_empty []
static struct memmap_desc guest_device_md0 []
static struct memmap_desc guest_device_md1 []
static struct memmap_desc guest_memory_md0 []
static struct memmap_desc guest_memory_md1 []
static struct memmap_descguest_mdlist0 []
static struct memmap_descguest_mdlist1 []

Define Documentation

#define TTBL_L2 (   ttbl_l1,
  index_l1 
)    (&ttbl_l1[(VMM_L1_PTE_NUM + VMM_L1_PADDING_PTE_NUM) + (VMM_L2L3_PTE_NUM_TOTAL * (index_l1))])

Definition at line 116 of file vmm.c.

#define TTBL_L3 (   ttbl_l2,
  index_l2 
)    (&ttbl_l2[VMM_L2_PTE_NUM + (VMM_L3_PTE_NUM * (index_l2))])

Definition at line 115 of file vmm.c.

#define VMM_L1_PADDING_PTE_NUM   (512 - VMM_L1_PTE_NUM)

Definition at line 15 of file vmm.c.

#define VMM_L1_PTE_NUM   4

Definition at line 14 of file vmm.c.

#define VMM_L2_PTE_NUM   512

Definition at line 17 of file vmm.c.

Definition at line 19 of file vmm.c.

#define VMM_L3_PTE_NUM   512

Definition at line 18 of file vmm.c.

#define VTCR_INITVAL   0x80000000

Definition at line 30 of file vmm.c.

#define VTCR_IRGN0_MASK   0x00000300

Definition at line 35 of file vmm.c.

#define VTCR_IRGN0_SHIFT   8

Definition at line 36 of file vmm.c.

#define VTCR_ORGN0_MASK   0x00000C00

Definition at line 33 of file vmm.c.

#define VTCR_ORGN0_SHIFT   10

Definition at line 34 of file vmm.c.

#define VTCR_S_MASK   0x00000010

Definition at line 39 of file vmm.c.

#define VTCR_S_SHIFT   4

Definition at line 40 of file vmm.c.

#define VTCR_SH0_MASK   0x00003000

Definition at line 31 of file vmm.c.

#define VTCR_SH0_SHIFT   12

Definition at line 32 of file vmm.c.

#define VTCR_SL0_MASK   0x000000C0

Definition at line 37 of file vmm.c.

#define VTCR_SL0_SHIFT   6

Definition at line 38 of file vmm.c.

#define VTCR_T0SZ_MASK   0x00000003

Definition at line 41 of file vmm.c.

#define VTCR_T0SZ_SHIFT   0

Definition at line 42 of file vmm.c.

#define VTTBR_BADDR_MASK   0x000000FFFFFFF000ULL

Definition at line 26 of file vmm.c.

#define VTTBR_BADDR_SHIFT   12

Definition at line 27 of file vmm.c.

#define VTTBR_INITVAL   0x0000000000000000ULL

Definition at line 23 of file vmm.c.

#define VTTBR_VMID_MASK   0x00FF000000000000ULL

Definition at line 24 of file vmm.c.

#define VTTBR_VMID_SHIFT   48

Definition at line 25 of file vmm.c.


Function Documentation

static lpaed_t _ttbl_guest0 [VMM_PTE_NUM_TOTAL] __attribute ( (__aligned__(4096))  ) [static]
void vmm_init ( void  )

Definition at line 339 of file vmm.c.

{
    /*
     * Initializes Translation Table for Stage2 Translation (IPA -> PA)
     */
    int i;

    HVMM_TRACE_ENTER();
    for( i = 0; i < NUM_GUESTS_STATIC; i++ ) {
        _vmid_ttbl[i] = 0;
    }

    _vmid_ttbl[0] = &_ttbl_guest0[0];
    _vmid_ttbl[1] = &_ttbl_guest1[0];


    /*
     * VA: 0x00000000 ~ 0x3FFFFFFF,   1GB
     * PA: 0xA0000000 ~ 0xDFFFFFFF    guest_bin_start
     * PA: 0xB0000000 ~ 0xEFFFFFFF    guest2_bin_start
     */

    guest_memory_md0[0].pa = (uint64_t) ((uint32_t) &guest_bin_start);
    guest_memory_md1[0].pa = (uint64_t) ((uint32_t) &guest2_bin_start);

    vmm_init_ttbl(&_ttbl_guest0[0], &guest_mdlist0[0]);
    vmm_init_ttbl(&_ttbl_guest1[0], &guest_mdlist1[0]);
   
    vmm_init_mmu();

    HVMM_TRACE_EXIT();
}

Here is the call graph for this function:

static void vmm_init_mmu ( void  ) [static]

Definition at line 306 of file vmm.c.

{
    uint32_t vtcr, vttbr;

    HVMM_TRACE_ENTER();

    vtcr = read_vtcr(); uart_print( "vtcr:"); uart_print_hex32(vtcr); uart_print("\n\r");

    // start lookup at level 1 table
    vtcr &= ~VTCR_SL0_MASK;
    vtcr |= (0x01 << VTCR_SL0_SHIFT) & VTCR_SL0_MASK;
    vtcr &= ~VTCR_ORGN0_MASK;
    vtcr |= (0x3 << VTCR_ORGN0_SHIFT) & VTCR_ORGN0_MASK;
    vtcr &= ~VTCR_IRGN0_MASK;
    vtcr |= (0x3 << VTCR_IRGN0_SHIFT) & VTCR_IRGN0_MASK;
    write_vtcr(vtcr);
    vtcr = read_vtcr(); uart_print( "vtcr:"); uart_print_hex32(vtcr); uart_print("\n\r");
    {
        uint32_t sl0 = (vtcr & VTCR_SL0_MASK) >> VTCR_SL0_SHIFT;
        uint32_t t0sz = vtcr & 0xF;
        uint32_t baddr_x = (sl0 == 0 ? 14 - t0sz : 5 - t0sz);
        uart_print( "vttbr.baddr.x:"); uart_print_hex32(baddr_x); uart_print("\n\r");
    }
// VTTBR
    vttbr = read_vttbr(); uart_print( "vttbr:" ); uart_print_hex64(vttbr); uart_print("\n\r");

    HVMM_TRACE_EXIT();
}
static void vmm_init_ttbl ( lpaed_t ttbl,
struct memmap_desc mdlist[] 
) [static]

Definition at line 285 of file vmm.c.

{
    int i = 0;
    HVMM_TRACE_ENTER();

    while(mdlist[i]) {
        struct memmap_desc *md = mdlist[i];

        if ( md[0].label == 0 ) {
            lpaed_stage2_conf_l1_table(&ttbl[i], 0, 0);
        } else {
            lpaed_stage2_conf_l1_table(&ttbl[i], (uint64_t) ((uint32_t) TTBL_L2(ttbl, i)), 1);
            vmm_init_ttbl2(TTBL_L2(ttbl, i), md);
        }
        i++;
    }

    HVMM_TRACE_EXIT();
}

Here is the call graph for this function:

static void vmm_init_ttbl2 ( lpaed_t ttbl2,
struct memmap_desc md 
) [static]

Definition at line 264 of file vmm.c.

{
    int i = 0;
    HVMM_TRACE_ENTER();
    printh( " - ttbl2:%x\n", (uint32_t) ttbl2 );
    if ( ((uint64_t) ( (uint32_t) ttbl2) ) & 0x0FFFULL ) {
        printh( " - error: invalid ttbl2 address alignment\n" );
    }

    /* construct l2-l3 table hirerachy with invalid pages */
    vmm_ttbl2_init_entries(ttbl2);

    vmm_ttbl2_unmap( ttbl2, 0x00000000, 0x40000000 );

    while(md[i].label != 0) {
        vmm_ttbl2_map(ttbl2, md[i].va, md[i].pa, md[i].size, md[i].attr );
        i++;
    }
    HVMM_TRACE_EXIT();
}

Here is the call graph for this function:

Definition at line 397 of file vmm.c.

{
    uint64_t vttbr;

    /* 
     * VTTBR.VMID = vmid
     * VTTBR.BADDR = ttbl
     */
    vttbr = read_vttbr();
#if 0 /* ignore message due to flood log message */
    uart_print( "current vttbr:" ); uart_print_hex64(vttbr); uart_print("\n\r");
#endif
    vttbr &= ~(VTTBR_VMID_MASK);
    vttbr |= ((uint64_t)vmid << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;

    vttbr &= ~(VTTBR_BADDR_MASK);
    vttbr |= (uint32_t) ttbl & VTTBR_BADDR_MASK;
    write_vttbr(vttbr);

    vttbr = read_vttbr();
#if 0 /* ignore message due to flood log message */
    uart_print( "changed vttbr:" ); uart_print_hex64(vttbr); uart_print("\n\r");
#endif
    return HVMM_STATUS_SUCCESS;
}
void vmm_stage2_enable ( int  enable)

Definition at line 383 of file vmm.c.

{
    uint32_t hcr;

    // HCR.VM[0] = enable
    hcr = read_hcr(); //uart_print( "hcr:"); uart_print_hex32(hcr); uart_print("\n\r");
    if ( enable ) {
        hcr |= (0x1);
    } else {
        hcr &= ~(0x1);
    }
    write_hcr( hcr );
}
static void vmm_ttbl2_init_entries ( lpaed_t ttbl2) [static]

Definition at line 245 of file vmm.c.

{
    int i, j;
    HVMM_TRACE_ENTER();

    lpaed_t *ttbl3;
    for( i = 0; i < VMM_L2_PTE_NUM; i++ ) {
        ttbl3 = TTBL_L3(ttbl2, i);
        printh("ttbl2[%d]:%x ttbl3[]:%x\n", i, &ttbl2[i], ttbl3 );
        lpaed_stage2_conf_l2_table( &ttbl2[i], (uint64_t) ((uint32_t) ttbl3), 0);
        for( j = 0; j < VMM_L2_PTE_NUM; j++) {
            ttbl3[j].pt.valid = 0;
        }
    }        

    HVMM_TRACE_EXIT();
}

Here is the call graph for this function:

static void vmm_ttbl2_map ( lpaed_t ttbl2,
uint64_t  va_offset,
uint64_t  pa,
uint32_t  size,
lpaed_stage2_memattr_t  mattr 
) [static]

Definition at line 184 of file vmm.c.

{
    uint64_t block_offset;
    uint32_t index_l2;
    uint32_t index_l2_last;
    uint32_t num_blocks;
    uint32_t pages;
    lpaed_t *ttbl3;
    int i;

    HVMM_TRACE_ENTER();
    printh( "ttbl2:%x va_offset:%x pa:%x size:%d\n", (uint32_t) ttbl2, (uint32_t) va_offset, (uint32_t) pa, size);

    index_l2 = va_offset >> LPAE_BLOCK_L2_SHIFT;
    block_offset = va_offset & LPAE_BLOCK_L2_MASK;
    printh( "- index_l2:%d block_offset:%x\n", index_l2, (uint32_t) block_offset);
    /* head < BLOCK */
    if ( block_offset ) {
        uint64_t offset;
        offset = block_offset >> LPAE_PAGE_SHIFT;
        pages = size >> LPAE_PAGE_SHIFT;
        if ( pages > VMM_L3_PTE_NUM ) {
            pages = VMM_L3_PTE_NUM;
        }
        ttbl3 = TTBL_L3(ttbl2, index_l2 );
        vmm_ttbl3_map( ttbl3, offset, pages, pa, mattr );
        lpaed_stage2_enable_l2_table( &ttbl2[index_l2] );

        va_offset |= ~LPAE_BLOCK_L2_MASK;
        size -= pages * LPAE_PAGE_SIZE;
        pa += pages * LPAE_PAGE_SIZE;
        index_l2 ++;
    }

    /* body : n BLOCKS */
    if ( size > 0 ) {
        num_blocks = size >> LPAE_BLOCK_L2_SHIFT;
        index_l2_last = index_l2 + num_blocks;
        printh( "- index_l2_last:%d num_blocks:%d size:%d\n", index_l2_last, (uint32_t) num_blocks, size);

        for( i = index_l2; i < index_l2_last; i++ ) {
            lpaed_stage2_enable_l2_table( &ttbl2[i] );
            vmm_ttbl3_map( TTBL_L3(ttbl2, i), 0, VMM_L3_PTE_NUM, pa, mattr );
            pa += LPAE_BLOCK_L2_SIZE;
            size -= LPAE_BLOCK_L2_SIZE;
        }
    }

    /* tail < BLOCK */
    if ( size > 0) {
        pages = size >> LPAE_PAGE_SHIFT;
        printh( "- pages:%d size:%d\n", pages, size);
        if ( pages ) {
            ttbl3 = TTBL_L3(ttbl2, index_l2_last);
            vmm_ttbl3_map( ttbl3, 0, pages, pa, mattr );
            lpaed_stage2_enable_l2_table( &ttbl2[index_l2_last] );
        }
    }
    HVMM_TRACE_EXIT();
}

Here is the call graph for this function:

static void vmm_ttbl2_unmap ( lpaed_t ttbl2,
uint64_t  va_offset,
uint32_t  size 
) [static]

Definition at line 160 of file vmm.c.

{
    int index_l2 = 0;
    int index_l2_last = 0;
    int num_blocks = 0;

    /* Initialize the address spaces with 'invalid' state */

    num_blocks = size >> LPAE_BLOCK_L2_SHIFT;
    index_l2 = va_offset >> LPAE_BLOCK_L2_SHIFT;
    index_l2_last = num_blocks;

    for( ; index_l2 < index_l2_last; index_l2++ ) {
        ttbl2[index_l2].pt.valid = 0;
    }

    size &= LPAE_BLOCK_L2_MASK;
    if ( size ) {
        // last partial block
        lpaed_t *ttbl3 = TTBL_L3(ttbl2, index_l2);
        vmm_ttbl3_unmap( ttbl3, 0x00000000, size >> LPAE_PAGE_SHIFT);
    }
}

Here is the call graph for this function:

static void vmm_ttbl3_map ( lpaed_t ttbl3,
uint64_t  offset,
uint32_t  pages,
uint64_t  pa,
lpaed_stage2_memattr_t  mattr 
) [static]

Definition at line 119 of file vmm.c.

{
    int index_l3 = 0;
    int index_l3_last = 0;

 
    printh( "%s[%d]: ttbl3:%x offset:%x pte:%x pages:%d, pa:%x\n", __FUNCTION__, __LINE__, (uint32_t) ttbl3, (uint32_t) offset, &ttbl3[offset], pages, (uint32_t) pa);
    /* Initialize the address spaces with 'invalid' state */

    index_l3 = offset;
    index_l3_last = index_l3 + pages;

    for( ; index_l3 < index_l3_last; index_l3++ ) {
        lpaed_stage2_map_page(&ttbl3[index_l3], pa, mattr );
        pa += LPAE_PAGE_SIZE;
    }

}

Here is the call graph for this function:

static void vmm_ttbl3_unmap ( lpaed_t ttbl3,
uint64_t  offset,
uint32_t  pages 
) [static]

Definition at line 139 of file vmm.c.

{
    int index_l3 = 0;
    int index_l3_last = 0;

    /* Initialize the address spaces with 'invalid' state */

    index_l3 = offset >> LPAE_PAGE_SHIFT;
    index_l3_last = index_l3 + pages;

    for( ; index_l3 < index_l3_last; index_l3++ ) {
        ttbl3[index_l3].pt.valid = 0;
    }
}

Definition at line 373 of file vmm.c.

{
    lpaed_t *ttbl = 0;
    if ( vmid < NUM_GUESTS_STATIC ) {
        ttbl = _vmid_ttbl[vmid];
    }
    return ttbl;
}

Variable Documentation

Definition at line 53 of file vmm.c.

struct memmap_desc guest_device_md0[] [static]
Initial value:
 {
    
    CFG_GUEST0_DEVICE_MEMORY,
    { 0, 0, 0, 0,  0},
}

Definition at line 70 of file vmm.c.

struct memmap_desc guest_device_md1[] [static]
Initial value:
 {
    
    CFG_GUEST1_DEVICE_MEMORY,
    { 0, 0, 0, 0,  0},
}

Definition at line 76 of file vmm.c.

struct memmap_desc guest_md_empty[] [static]
Initial value:
 {
    {       0, 0, 0, 0,  0},
}

Definition at line 66 of file vmm.c.

struct memmap_desc* guest_mdlist0[] [static]
Initial value:
 {
    &guest_device_md0[0],   
    &guest_md_empty[0],     
    &guest_memory_md0[0],
    &guest_md_empty[0],     
    0
}

Definition at line 95 of file vmm.c.

struct memmap_desc* guest_mdlist1[] [static]
Initial value:
 {
    &guest_device_md1[0],
    &guest_md_empty[0],
    &guest_memory_md1[0],
    &guest_md_empty[0],
    0
}

Definition at line 104 of file vmm.c.

struct memmap_desc guest_memory_md0[] [static]
Initial value:
 {
    
    { "start", 0x00000000,          0, 0x30000000, LPAED_STAGE2_MEMATTR_NORMAL_OWT | LPAED_STAGE2_MEMATTR_NORMAL_IWT },
    {       0, 0, 0, 0,  0},
}

Definition at line 82 of file vmm.c.

struct memmap_desc guest_memory_md1[] [static]
Initial value:
 {
    
    { "start", 0x00000000,          0, 0x10000000, LPAED_STAGE2_MEMATTR_NORMAL_OWT | LPAED_STAGE2_MEMATTR_NORMAL_IWT },
    {       0, 0, 0, 0,  0},
}

Definition at line 88 of file vmm.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines