|
khypervisor
v1
|
#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>
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_t * | hmm_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_bheader * | morecore (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_bheader * | freep |
| #define BUFFERABLE 0x1 |
| #define DEV_CACHED WRITEBACK |
| #define DEV_NONSHARED DEV_SHARED |
| #define DEV_SHARED 0x4 |
| #define DEV_WC BUFFERABLE |
| #define HEAP_END_ADDR HEAP_ADDR + HEAP_SIZE |
| #define HMM_L1_PTE_NUM 512 |
| #define HMM_L2_PTE_NUM 512 |
| #define HMM_L3_PTE_NUM 512 |
| #define HSCTLR_BASE 0x30c51878 |
| #define HTCR_INITVAL 0x80000000 |
| #define HTCR_IRGN0_MASK 0x00000300 |
| #define HTCR_IRGN0_SHIFT 8 |
| #define HTCR_ORGN0_MASK 0x00000C00 |
| #define HTCR_ORGN0_SHIFT 10 |
| #define HTCR_SH0_MASK 0x00003000 |
| #define HTCR_SH0_SHIFT 12 |
| #define HTCR_T0SZ_MASK 0x00000003 |
| #define HTCR_T0SZ_SHIFT 0 |
| #define HTTBR_BADDR_MASK 0x000000FFFFFFF000ULL |
| #define HTTBR_BADDR_SHIFT 12 |
| #define HTTBR_INITVAL 0x0000000000000000ULL |
| #define INITIAL_MAIR0VAL 0xeeaa4400 |
| #define INITIAL_MAIR1VAL 0xff000004 |
| #define INITIAL_MAIRVAL (INITIAL_MAIR0VAL|INITIAL_MAIR1VAL<<32) |
| #define L2_ENTRY_MASK 0x1FF |
| #define L3_ENTRY_MASK 0x1FF |
| #define SCTLR_BASE 0x00c50078 |
| #define SCTLR_NMFI (1<<27) |
| #define WRITEALLOC 0x7 |
| #define WRITETHROUGH 0x2 |
| typedef union header fl_bheader |
| 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;
}
}

| 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.
{
mm_break = HEAP_ADDR;
mm_prev_break = HEAP_ADDR;
last_valid_address = HEAP_ADDR;
freep = 0;
}
| 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 */
}
}

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

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

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

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

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

fl_bheader* freep [static] |
fl_bheader freep_base [static] |
1.7.6.1