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

Go to the source code of this file.

Data Structures

union  header

Defines

#define INITIAL_MAIR0VAL   0xeeaa4400
#define INITIAL_MAIR1VAL   0xff000004
#define INITIAL_MAIRVAL   (INITIAL_MAIR0VAL|INITIAL_MAIR1VAL<<32)
#define UNCACHED   0x0
#define BUFFERABLE   0x1
#define WRITETHROUGH   0x2
#define WRITEBACK   0x3
#define DEV_SHARED   0x4
#define WRITEALLOC   0x7
#define DEV_NONSHARED   DEV_SHARED
#define DEV_WC   BUFFERABLE
#define DEV_CACHED   WRITEBACK
#define SCTLR_TE   (1<<30)
#define SCTLR_AFE   (1<<29)
#define SCTLR_TRE   (1<<28)
#define SCTLR_NMFI   (1<<27)
#define SCTLR_EE   (1<<25)
#define SCTLR_VE   (1<<24)
#define SCTLR_U   (1<<22)
#define SCTLR_FI   (1<<21)
#define SCTLR_WXN   (1<<19)
#define SCTLR_HA   (1<<17)
#define SCTLR_RR   (1<<14)
#define SCTLR_V   (1<<13)
#define SCTLR_I   (1<<12)
#define SCTLR_Z   (1<<11)
#define SCTLR_SW   (1<<10)
#define SCTLR_B   (1<<7)
#define SCTLR_C   (1<<2)
#define SCTLR_A   (1<<1)
#define SCTLR_M   (1<<0)
#define SCTLR_BASE   0x00c50078
#define HSCTLR_BASE   0x30c51878
#define HTTBR_INITVAL   0x0000000000000000ULL
#define HTTBR_BADDR_MASK   0x000000FFFFFFF000ULL
#define HTTBR_BADDR_SHIFT   12
#define HTCR_INITVAL   0x80000000
#define HTCR_SH0_MASK   0x00003000
#define HTCR_SH0_SHIFT   12
#define HTCR_ORGN0_MASK   0x00000C00
#define HTCR_ORGN0_SHIFT   10
#define HTCR_IRGN0_MASK   0x00000300
#define HTCR_IRGN0_SHIFT   8
#define HTCR_T0SZ_MASK   0x00000003
#define HTCR_T0SZ_SHIFT   0
#define HMM_L1_PTE_NUM   512
#define HMM_L2_PTE_NUM   512
#define HMM_L3_PTE_NUM   512
#define HEAP_ADDR   CFG_MEMMAP_MON_OFFSET + 0x02000000
#define HEAP_SIZE   0x0D000000
#define L2_ENTRY_MASK   0x1FF
#define L2_SHIFT   21
#define L3_ENTRY_MASK   0x1FF
#define L3_SHIFT   12
#define HEAP_END_ADDR   HEAP_ADDR + HEAP_SIZE
#define NALLOC   1024

Typedefs

typedef long Align
typedef union header fl_bheader

Functions

static lpaed_t _hmm_pgtable[HMM_L1_PTE_NUM__attribute ((__aligned__(4096)))
void hmm_heap_init (void)
static void _hmm_init (void)
int hvmm_mm_init (void)
void hmm_flushTLB (void)
lpaed_thmm_get_l3_table_entry (unsigned long virt, unsigned long npages)
void hmm_umap (unsigned long virt, unsigned long npages)
void hmm_map (unsigned long phys, unsigned long virt, unsigned long npages)
void * hmm_sbrk (unsigned int incr)
void hmm_free (void *ap)
static fl_bheadermorecore (unsigned int nu)
void * hmm_malloc (unsigned long size)

Variables

uint32_t mm_break
uint32_t mm_prev_break
uint32_t last_valid_address
static fl_bheader freep_base
static fl_bheaderfreep

Define Documentation

#define BUFFERABLE   0x1

Definition at line 43 of file mm.c.

#define DEV_CACHED   WRITEBACK

Definition at line 50 of file mm.c.

#define DEV_NONSHARED   DEV_SHARED

Definition at line 48 of file mm.c.

#define DEV_SHARED   0x4

Definition at line 46 of file mm.c.

#define DEV_WC   BUFFERABLE

Definition at line 49 of file mm.c.

#define HEAP_ADDR   CFG_MEMMAP_MON_OFFSET + 0x02000000

Definition at line 101 of file mm.c.

Definition at line 110 of file mm.c.

#define HEAP_SIZE   0x0D000000

Definition at line 102 of file mm.c.

#define HMM_L1_PTE_NUM   512

Definition at line 93 of file mm.c.

#define HMM_L2_PTE_NUM   512

Definition at line 96 of file mm.c.

#define HMM_L3_PTE_NUM   512

Definition at line 99 of file mm.c.

#define HSCTLR_BASE   0x30c51878

Definition at line 74 of file mm.c.

#define HTCR_INITVAL   0x80000000

Definition at line 82 of file mm.c.

#define HTCR_IRGN0_MASK   0x00000300

Definition at line 87 of file mm.c.

#define HTCR_IRGN0_SHIFT   8

Definition at line 88 of file mm.c.

#define HTCR_ORGN0_MASK   0x00000C00

Definition at line 85 of file mm.c.

#define HTCR_ORGN0_SHIFT   10

Definition at line 86 of file mm.c.

#define HTCR_SH0_MASK   0x00003000

Definition at line 83 of file mm.c.

#define HTCR_SH0_SHIFT   12

Definition at line 84 of file mm.c.

#define HTCR_T0SZ_MASK   0x00000003

Definition at line 89 of file mm.c.

#define HTCR_T0SZ_SHIFT   0

Definition at line 90 of file mm.c.

#define HTTBR_BADDR_MASK   0x000000FFFFFFF000ULL

Definition at line 78 of file mm.c.

#define HTTBR_BADDR_SHIFT   12

Definition at line 79 of file mm.c.

#define HTTBR_INITVAL   0x0000000000000000ULL

Definition at line 77 of file mm.c.

#define INITIAL_MAIR0VAL   0xeeaa4400

Definition at line 30 of file mm.c.

#define INITIAL_MAIR1VAL   0xff000004

Definition at line 31 of file mm.c.

Definition at line 32 of file mm.c.

#define L2_ENTRY_MASK   0x1FF

Definition at line 104 of file mm.c.

#define L2_SHIFT   21

Definition at line 105 of file mm.c.

#define L3_ENTRY_MASK   0x1FF

Definition at line 107 of file mm.c.

#define L3_SHIFT   12

Definition at line 108 of file mm.c.

#define NALLOC   1024

Definition at line 111 of file mm.c.

#define SCTLR_A   (1<<1)

Definition at line 71 of file mm.c.

#define SCTLR_AFE   (1<<29)

Definition at line 55 of file mm.c.

#define SCTLR_B   (1<<7)

Definition at line 69 of file mm.c.

#define SCTLR_BASE   0x00c50078

Definition at line 73 of file mm.c.

#define SCTLR_C   (1<<2)

Definition at line 70 of file mm.c.

#define SCTLR_EE   (1<<25)

Definition at line 58 of file mm.c.

#define SCTLR_FI   (1<<21)

Definition at line 61 of file mm.c.

#define SCTLR_HA   (1<<17)

Definition at line 63 of file mm.c.

#define SCTLR_I   (1<<12)

Definition at line 66 of file mm.c.

#define SCTLR_M   (1<<0)

Definition at line 72 of file mm.c.

#define SCTLR_NMFI   (1<<27)

Definition at line 57 of file mm.c.

#define SCTLR_RR   (1<<14)

Definition at line 64 of file mm.c.

#define SCTLR_SW   (1<<10)

Definition at line 68 of file mm.c.

#define SCTLR_TE   (1<<30)

Definition at line 54 of file mm.c.

#define SCTLR_TRE   (1<<28)

Definition at line 56 of file mm.c.

#define SCTLR_U   (1<<22)

Definition at line 60 of file mm.c.

#define SCTLR_V   (1<<13)

Definition at line 65 of file mm.c.

#define SCTLR_VE   (1<<24)

Definition at line 59 of file mm.c.

#define SCTLR_WXN   (1<<19)

Definition at line 62 of file mm.c.

#define SCTLR_Z   (1<<11)

Definition at line 67 of file mm.c.

#define UNCACHED   0x0

Definition at line 42 of file mm.c.

#define WRITEALLOC   0x7

Definition at line 47 of file mm.c.

#define WRITEBACK   0x3

Definition at line 45 of file mm.c.

#define WRITETHROUGH   0x2

Definition at line 44 of file mm.c.


Typedef Documentation

typedef long Align

Definition at line 118 of file mm.c.

typedef union header fl_bheader

Definition at line 128 of file mm.c.


Function Documentation

static lpaed_t _hmm_pgtable [HMM_L1_PTE_NUM] __attribute ( (__aligned__(4096))  ) [static]
static void _hmm_init ( void  ) [static]

Definition at line 151 of file mm.c.

{
    int i, j;
    uint64_t pa = 0x00000000ULL;
    /*
     * Partition 0: 0x00000000 ~ 0x3FFFFFFF - Peripheral - DEV_SHARED
     * Partition 1: 0x40000000 ~ 0x7FFFFFFF - Unused     - UNCACHED
     * Partition 2: 0x80000000 ~ 0xBFFFFFFF - Guest      - UNCACHED
     * Partition 3: 0xC0000000 ~ 0xFFFFFFFF - Monitor    - LV2 translation table address
     */
    _hmm_pgtable[0] = hvmm_mm_lpaed_l1_block(pa, DEV_SHARED); pa += 0x40000000;
    uart_print( "&_hmm_pgtable[0]:"); uart_print_hex32((uint32_t) &_hmm_pgtable[0]); uart_print("\n\r");
    uart_print( "lpaed:"); uart_print_hex64(_hmm_pgtable[0].bits); uart_print("\n\r");
    _hmm_pgtable[1] = hvmm_mm_lpaed_l1_block(pa, UNCACHED); pa += 0x40000000;
    uart_print( "&_hmm_pgtable[1]:"); uart_print_hex32((uint32_t) &_hmm_pgtable[1]); uart_print("\n\r");
    uart_print( "lpaed:"); uart_print_hex64(_hmm_pgtable[1].bits); uart_print("\n\r");
    _hmm_pgtable[2] = hvmm_mm_lpaed_l1_block(pa, UNCACHED); pa += 0x40000000;
    uart_print( "&_hmm_pgtable[2]:"); uart_print_hex32((uint32_t) &_hmm_pgtable[2]); uart_print("\n\r");
    uart_print( "lpaed:"); uart_print_hex64(_hmm_pgtable[2].bits); uart_print("\n\r");
    /* _hmm_pgtable[3] refers Lv2 page table address. */
    _hmm_pgtable[3] = hvmm_mm_lpaed_l1_table((uint32_t) _hmm_pgtable_l2); 
    uart_print( "&_hmm_pgtable[3]:"); uart_print_hex32((uint32_t) &_hmm_pgtable[3]); uart_print("\n\r");
    uart_print( "lpaed:"); uart_print_hex64(_hmm_pgtable[3].bits); uart_print("\n\r");
    for( i = 0; i <HMM_L2_PTE_NUM; i++){
        /* _hvmm_pgtable_lv2[i] refers Lv3 page table address. each element correspond 2MB */
        _hmm_pgtable_l2[i] = hvmm_mm_lpaed_l2_table((uint32_t) _hmm_pgtable_l3[i]); 
        /* _hvmm_pgtable_lv3[i][j] refers page, that size is 4KB */
        for(j = 0; j < HMM_L3_PTE_NUM; pa += 0x1000 ,j++){
            /* 0xF2000000 ~ 0xFF000000 - Heap memory 208MB */
            if(pa >= HEAP_ADDR && pa < HEAP_ADDR + HEAP_SIZE){
                _hmm_pgtable_l3[i][j] = hvmm_mm_lpaed_l3_table(pa, WRITEALLOC, 0);
            }
            else{
                _hmm_pgtable_l3[i][j] = hvmm_mm_lpaed_l3_table(pa, UNCACHED, 1);
            }
        }
    }
    for ( i = 4; i < HMM_L1_PTE_NUM; i++ ) {
        _hmm_pgtable[i].pt.valid = 0;
    }
}

Here is the call graph for this function:

void hmm_flushTLB ( void  )

Definition at line 301 of file mm.c.

{
    /* Invalidate entire unified TLB */
    invalidate_unified_tlb(0);
    asm volatile("dsb");
    asm volatile("isb");
}
void hmm_free ( void *  ap)

Definition at line 374 of file mm.c.

{
    fl_bheader *bp, *p;
    bp = (fl_bheader *)ap - 1; /* point to block header */
    for (p = freep; !(bp > p && bp  < p->s.ptr); p = p->s.ptr){
        if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)){
            break; /* freed block at start or end of arena */
        }
    }
    if(bp + bp->s.size == p->s.ptr) { /* join to upper nbr */
        bp->s.size += p->s.ptr->s.size;
        bp->s.ptr = p->s.ptr->s.ptr;
    } else
        bp->s.ptr = p->s.ptr;
    if (p + p->s.size == bp) {      /* join to lower nbr */
        p->s.size += bp->s.size;
        p->s.ptr = bp->s.ptr;
    } else
        p->s.ptr = bp;
    freep = p;
}
lpaed_t* hmm_get_l3_table_entry ( unsigned long  virt,
unsigned long  npages 
)

Definition at line 309 of file mm.c.

{
    int l2_index = (virt >> L2_SHIFT) & L2_ENTRY_MASK;
    int l3_index = (virt >> L3_SHIFT) & L3_ENTRY_MASK;
    int maxsize = ((HMM_L2_PTE_NUM * HMM_L3_PTE_NUM) - ( (l2_index + 1) * (l3_index + 1) ) + 1);
    if( maxsize < npages ) {
        printh("%s[%d] : Map size \"pages\" is exceeded memory size\n", __FUNCTION__, __LINE__);
        if(maxsize > 0){
            printh("%s[%d] : Available pages are %d\n", maxsize); 
        }
        else{
            printh("%s[%d] : Do not have available pages for map\n");
        }
        return 0;
    }
    return &_hmm_pgtable_l3[l2_index][l3_index];
}
void hmm_heap_init ( void  )

Definition at line 137 of file mm.c.

void* hmm_malloc ( unsigned long  size)

Definition at line 411 of file mm.c.

{
    fl_bheader *p, *prevp;
    unsigned int nunits; 
    nunits = (size + sizeof(fl_bheader) - 1)/sizeof(fl_bheader) + 1;
    if(nunits < 2){
        return 0;
    }
    
    if ((prevp = freep) == 0 ) { /* no free list yet */
        freep_base.s.ptr = freep = prevp = &freep_base;
        freep_base.s.size = 0;
    }
    for ( p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
        if ( p->s.size >= nunits ) { /* big enough */
            if ( p->s.size == nunits ) /* exactly */
                prevp->s.ptr = p->s.ptr;
            else {                    /* allocate tail end */
                p->s.size -= nunits;
                p += p->s.size;
                p->s.size = nunits;
            }
            freep = prevp;
            return (void *)(p+1);
    }
    if ( p == freep )   /* wrapped around free list */
        if (( p = morecore(nunits)) == 0 )
                return 0;  /* none avaliable memory left */
    }
}

Here is the call graph for this function:

void hmm_map ( unsigned long  phys,
unsigned long  virt,
unsigned long  npages 
)

Definition at line 337 of file mm.c.

{
    int i;
    lpaed_t* map_table_p = hmm_get_l3_table_entry( virt, npages );
    for( i = 0; i < npages; i++){
        lpaed_stage1_conf_l3_table( &map_table_p[i], (uint64_t)phys, 1 );
    }
    hmm_flushTLB();
}

Here is the call graph for this function:

void* hmm_sbrk ( unsigned int  incr)

Definition at line 350 of file mm.c.

{
    unsigned int required_addr;
    unsigned int virt;
    unsigned int required_pages = 0;

    mm_prev_break = mm_break;
    virt = mm_break;
    mm_break += incr;
    if( mm_break > last_valid_address ){
        required_addr = mm_break - last_valid_address;
        for( ;required_addr > 0x0; required_addr -= 0x1000){
            if( last_valid_address + 0x1000 > HEAP_END_ADDR ){
                printh("%s[%d] required address is exceeded heap memory size\n", __FUNCTION__, __LINE__);
                return (void *)-1;
            }
            last_valid_address += 0x1000;
            required_pages++;
        }
        hmm_map(virt, virt, required_pages);
    }
    return (void *)mm_prev_break;
}

Here is the call graph for this function:

void hmm_umap ( unsigned long  virt,
unsigned long  npages 
)

Definition at line 327 of file mm.c.

{ 
    int  i;
    lpaed_t* map_table_p = hmm_get_l3_table_entry( virt, npages );
    for( i = 0; i < npages; i++){
        lpaed_stage1_disable_l3_table( &map_table_p[i] );
    }
    hmm_flushTLB();
}

Here is the call graph for this function:

int hvmm_mm_init ( void  )

Definition at line 193 of file mm.c.

{
/*
 *  MAIR0, MAIR1
 *  HMAIR0, HMAIR1
 *  HTCR
 *  HTCTLR
 *  HTTBR
 *  HTCTLR
 */
    uint32_t mair, htcr, hsctlr, hcr;
    uint64_t httbr;
    uart_print( "[mm] mm_init: enter\n\r" );
    
    vmm_init();
    _hmm_init();

    // MAIR/HMAIR
    uart_print(" --- MAIR ----\n\r" );
    mair = read_mair0(); uart_print( "mair0:"); uart_print_hex32(mair); uart_print("\n\r");
    mair = read_mair1(); uart_print( "mair1:"); uart_print_hex32(mair); uart_print("\n\r");
    mair = read_hmair0(); uart_print( "hmair0:"); uart_print_hex32(mair); uart_print("\n\r");
    mair = read_hmair1(); uart_print( "hmair1:"); uart_print_hex32(mair); uart_print("\n\r");

    write_mair0( INITIAL_MAIR0VAL );
    write_mair1( INITIAL_MAIR1VAL );
    write_hmair0( INITIAL_MAIR0VAL );
    write_hmair1( INITIAL_MAIR1VAL );

    mair = read_mair0(); uart_print( "mair0:"); uart_print_hex32(mair); uart_print("\n\r");
    mair = read_mair1(); uart_print( "mair1:"); uart_print_hex32(mair); uart_print("\n\r");
    mair = read_hmair0(); uart_print( "hmair0:"); uart_print_hex32(mair); uart_print("\n\r");
    mair = read_hmair1(); uart_print( "hmair1:"); uart_print_hex32(mair); uart_print("\n\r");

    // HTCR
    uart_print(" --- HTCR ----\n\r" );
    htcr = read_htcr(); uart_print( "htcr:"); uart_print_hex32(htcr); uart_print("\n\r");
    write_htcr( 0x80002500 );
    htcr = read_htcr(); uart_print( "htcr:"); uart_print_hex32(htcr); uart_print("\n\r");

    // HSCTLR
    // i-Cache and Alignment Checking Enabled
    // MMU, D-cache, Write-implies-XN, Low-latency IRQs Disabled
    hsctlr = read_hsctlr(); uart_print( "hsctlr:"); uart_print_hex32(hsctlr); uart_print("\n\r");
    hsctlr = HSCTLR_BASE | SCTLR_A;
    write_hsctlr( hsctlr );
    hsctlr = read_hsctlr(); uart_print( "hsctlr:"); uart_print_hex32(hsctlr); uart_print("\n\r");


// HCR
    hcr = read_hcr(); uart_print( "hcr:"); uart_print_hex32(hcr); uart_print("\n\r");

// HTCR
    /*
     * Shareability - SH0[13:12] = 0 - Not shared
     * Outer Cacheability - ORGN0[11:10] = 11b - Write Back no Write Allocate Cacheable
     * Inner Cacheability - IRGN0[9:8] = 11b - Same
     * T0SZ[2:0] = 0 - 2^32 Input Address 
     */
    /* Untested code commented */
/*
    htcr = read_htcr(); uart_print( "htcr:"); uart_print_hex32(htcr); uart_print("\n\r");
    htcr &= ~HTCR_SH0_MASK;
    htcr |= (0x0 << HTCR_SH0_SHIFT) & HTCR_SH0_MASK;
    htcr &= ~HTCR_ORGN0_MASK;
    htcr |= (0x3 << HTCR_ORGN0_SHIFT) & HTCR_ORGN0_MASK;
    htcr &= ~VTCR_IRGN0_MASK;
    htcr |= (0x3 << HTCR_IRGN0_SHIFT) & HTCR_IRGN0_MASK;
    htcr &= ~VTCR_T0SZ_MASK;
    htcr |= (0x0 << HTCR_T0SZ_SHIFT) & HTCR_T0SZ_MASK;
    write_htcr( htcr );
    htcr = read_htcr(); uart_print( "htcr:"); uart_print_hex32(htcr); uart_print("\n\r");
*/

    /* HTTBR = &__hmm_pgtable */
    httbr = read_httbr(); uart_print( "httbr:" ); uart_print_hex64(httbr); uart_print("\n\r");
    httbr &= 0xFFFFFFFF00000000ULL;
    httbr |= (uint32_t) &_hmm_pgtable;
    httbr &= HTTBR_BADDR_MASK;
    uart_print( "writing httbr:" ); uart_print_hex64(httbr); uart_print("\n\r");
    write_httbr( httbr );
    httbr = read_httbr(); uart_print( "read back httbr:" ); uart_print_hex64(httbr); uart_print("\n\r");

    /* Enable PL2 Stage 1 MMU */

    hsctlr = read_hsctlr(); uart_print( "hsctlr:"); uart_print_hex32(hsctlr); uart_print("\n\r");

    /* HSCTLR Enable MMU and D-cache */
    // hsctlr |= (SCTLR_M |SCTLR_C);
    hsctlr |= (SCTLR_M);
    
    /* Flush PTE writes */
    asm("dsb");

    write_hsctlr( hsctlr );

    /* Flush iCache */
    asm("isb");

    hsctlr = read_hsctlr(); uart_print( "hsctlr:"); uart_print_hex32(hsctlr); uart_print("\n\r");

    hmm_heap_init();

    uart_print( "[mm] mm_init: exit\n\r" );

    return HVMM_STATUS_SUCCESS;
}

Here is the call graph for this function:

static fl_bheader* morecore ( unsigned int  nu) [static]

Definition at line 396 of file mm.c.

{
    char *cp;
    fl_bheader *up;
    if ( nu < NALLOC )
        nu = NALLOC;
    cp = hmm_sbrk(nu * sizeof(fl_bheader));
    if ( cp == (char *) -1 ) /* no space at all */
        return 0;
    up = (fl_bheader *)cp;
    up->s.size = nu;
    hmm_free((void*)(up+1));
    return freep;
}

Here is the call graph for this function:


Variable Documentation

fl_bheader* freep [static]

Definition at line 134 of file mm.c.

Definition at line 133 of file mm.c.

Definition at line 132 of file mm.c.

Definition at line 130 of file mm.c.

Definition at line 131 of file mm.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines