/branches/dynload/kernel/arch/ia64/src/mm/tlb.c |
---|
475,6 → 475,73 |
} |
} |
static int is_io_page_accessible(int page) |
{ |
if(TASK->arch.iomap) return bitmap_get(TASK->arch.iomap,page); |
else return 0; |
} |
#define IO_FRAME_BASE 0xFFFFC000000 |
/** There is special handling of memmaped lagacy io, because |
* of 4KB sized access |
* only for userspace |
* |
* @param va virtual address of page fault |
* @param istate Structure with saved interruption state. |
* |
* |
* @return 1 on success, 0 on fail |
*/ |
static int try_memmap_io_insertion(uintptr_t va, istate_t *istate) |
{ |
if((va >= IO_OFFSET ) && (va < IO_OFFSET + (1<<IO_PAGE_WIDTH))) |
if(TASK){ |
uint64_t io_page=(va & ((1<<IO_PAGE_WIDTH)-1)) >> (USPACE_IO_PAGE_WIDTH); |
if(is_io_page_accessible(io_page)){ |
//printf("Insert %llX\n",va); |
uint64_t page,frame; |
page = IO_OFFSET + (1 << USPACE_IO_PAGE_WIDTH) * io_page; |
frame = IO_FRAME_BASE + (1 << USPACE_IO_PAGE_WIDTH) * io_page; |
tlb_entry_t entry; |
entry.word[0] = 0; |
entry.word[1] = 0; |
entry.p = true; /* present */ |
entry.ma = MA_UNCACHEABLE; |
entry.a = true; /* already accessed */ |
entry.d = true; /* already dirty */ |
entry.pl = PL_USER; |
entry.ar = AR_READ | AR_WRITE; |
entry.ppn = frame >> PPN_SHIFT; //MUSIM spocitat frame |
entry.ps = USPACE_IO_PAGE_WIDTH; |
dtc_mapping_insert(page, TASK->as->asid, entry); //Musim zjistit ASID |
return 1; |
}else { |
fault_if_from_uspace(istate,"IO access fault at %p",va); |
return 0; |
} |
} else |
return 0; |
else |
return 0; |
return 0; |
} |
/** Data TLB fault handler for faults with VHPT turned off. |
* |
* @param vector Interruption vector. |
511,10 → 578,11 |
dtc_pte_copy(t); |
page_table_unlock(AS, true); |
} else { |
page_table_unlock(AS, true); |
if (try_memmap_io_insertion(va,istate)) return; |
/* |
* Forward the page fault to the address space page fault handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
/branches/dynload/kernel/arch/ia64/src/mm/frame.c |
---|
36,14 → 36,20 |
#include <mm/frame.h> |
#include <config.h> |
#include <panic.h> |
#include <arch/bootinfo.h> |
#include <align.h> |
#include <macros.h> |
/* |
* This is Ski-specific and certainly not sufficient |
* for real ia64 systems that provide memory map. |
*/ |
#define MEMORY_SIZE (64 * 1024 * 1024) |
#define MEMORY_SIZE (256 * 1024 * 1024) |
#define MEMORY_BASE (0 * 64 * 1024 * 1024) |
#define KERNEL_RESERVED_AREA_BASE (0x4400000) |
#define KERNEL_RESERVED_AREA_SIZE (16*1024*1024) |
#define ONE_TO_ONE_MAPPING_SIZE (256*1048576) // Mapped at start |
#define ROM_BASE 0xa0000 //For ski |
50,22 → 56,41 |
#define ROM_SIZE (384 * 1024) //For ski |
void poke_char(int x,int y,char ch, char c); |
#define MIN_ZONE_SIZE (64*1024) |
uintptr_t last_frame; |
#define MINCONF 1 |
void frame_arch_init(void) |
{ |
if(config.cpu_active==1) |
{ |
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
if(config.cpu_active==1){ |
unsigned int i; |
for(i=0;i<bootinfo->memmap_items;i++){ |
if (bootinfo->memmap[i].type==EFI_MEMMAP_FREE_MEM){ |
uint64_t base=bootinfo->memmap[i].base; |
uint64_t size=bootinfo->memmap[i].size; |
uint64_t abase=ALIGN_UP(base,FRAME_SIZE); |
if(size>FRAME_SIZE) size -=abase-base; |
if(size>MIN_ZONE_SIZE) { |
zone_create(abase >> FRAME_WIDTH, (size) >> FRAME_WIDTH, max(MINCONF,((abase) >> FRAME_WIDTH)), 0); |
} |
} |
} |
//zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
/* |
* Blacklist ROM regions. |
*/ |
//frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(0), SIZE2FRAMES(1048576)); |
last_frame=SIZE2FRAMES((VRN_KERNEL<<VRN_SHIFT)+ONE_TO_ONE_MAPPING_SIZE); |
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE), SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE)); |
} |
} |