예제 #1
0
void enable_paging()
{
    PAGE *addr;

    PAGE_DIR[0] = make_pde(((uint32_t)KERNEL_PT) >> 12, 0, 1);

    for(addr = 0; addr < &_START_OF_TEXT_; ++addr)
        KERNEL_PT[PT_NUM_ADDR(addr)] = make_pte(PT_NUM_ADDR(addr), 1, 0, 1);

    for(addr = &_START_OF_TEXT_; addr < &_END_OF_RODATA_; ++addr)
        KERNEL_PT[PT_NUM_ADDR(addr)] = make_pte(PT_NUM_ADDR(addr), 1, 0, 0);

    for(addr = &_START_OF_DATA_; addr < &_END_OF_BSS_STACK_; ++addr)
        KERNEL_PT[PT_NUM_ADDR(addr)] = make_pte(PT_NUM_ADDR(addr), 1, 0, 1);

    __asm__(
        ".intel_syntax noprefix;"
        "mov cr3, %0;"
        "mov eax, cr0;"
        "or eax, 0x80010000;"
        "mov cr0, eax;"
        ".att_syntax;"
        :
        :"r"(PAGE_DIR)
        :"eax"
    );
}
예제 #2
0
void map_page(uint32_t *page_dir, uint32_t virt_page_num, uint32_t phy_page_num,
        bool global, bool user, bool read_write)
{
    uint16_t pd_idx = PD_IDX(virt_page_num),
             pt_idx = PT_IDX(virt_page_num);
    uint32_t *page_table;

    if(!(page_dir[pd_idx] & 0x1)) {
        uint32_t pt_page_num = alloc_phy_page(0, 1023);
        map_kernel_page(pt_page_num, pt_page_num, true, false, true);
        memset((void *)(pt_page_num << 12), 0, 4096);
        page_dir[pd_idx] = make_pde(pt_page_num, user, read_write);
    }

    page_table = (uint32_t *)(page_dir[pd_idx] & 0xfffff000);
    page_table[pt_idx] = make_pte(phy_page_num, global, user, read_write);
    ++phy_mem_rc[phy_page_num];
    __asm__ volatile(
        ".intel_syntax noprefix;"
        "mov eax, cr3;"
        "mov cr3, eax;"
        ".att_syntax;"
        :::"eax"
    );
}
예제 #3
0
파일: htab.c 프로젝트: muromec/linux-ezxdev
static inline void
create_pte_mapping(unsigned long start, unsigned long end,
		   unsigned long mode, unsigned long mask, int large)
{
	unsigned long addr;
	HPTE *htab = (HPTE *)__v2a(htab_data.htab);
	unsigned int step;

	if (large)
		step = 16*MB;
	else
		step = 4*KB;

	for (addr = start; addr < end; addr += step) {
		unsigned long vsid = get_kernel_vsid(addr);
		unsigned long va = (vsid << 28) | (addr & 0xfffffff);
		make_pte(htab, va, (unsigned long)__v2a(addr), 
			 mode, mask, large);
	}
}
예제 #4
0
/*
 * Bolt the kernel addr space into the HPT
 */
static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
{
	unsigned long pa;
	unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
	HPTE hpte;

	for (pa=saddr; pa < eaddr ;pa+=PAGE_SIZE) {
		unsigned long ea = (unsigned long)__va(pa);
		unsigned long vsid = get_kernel_vsid( ea );
		unsigned long va = ( vsid << 28 ) | ( pa & 0xfffffff );
		unsigned long vpn = va >> PAGE_SHIFT;
		unsigned long slot = HvCallHpt_findValid( &hpte, vpn );
		if (hpte.dw0.dw0.v) {
			/* HPTE exists, so just bolt it */
			HvCallHpt_setSwBits(slot, 0x10, 0);
		} else {
			/* No HPTE exists, so create a new bolted one */
			make_pte(NULL, va, (unsigned long)__v2a(ea), 
				 mode_rw, 0, 0);
		}
	}
}
예제 #5
0
파일: kvm.c 프로젝트: dpingg/os-lab1
/* Build a page table for the kernel */
void
init_page(void) {
	CR0 cr0;
	CR3 cr3;
	PDE *pdir = (PDE *)va_to_pa(kpdir);
	PTE *ptable = (PTE *)va_to_pa(kptable);
	uint32_t pdir_idx, ptable_idx, pframe_idx;


	for (pdir_idx = 0; pdir_idx < NR_PDE; pdir_idx ++) {
		make_invalid_pde(&pdir[pdir_idx]);
	}

	pframe_idx = 0;
	for (pdir_idx = 0; pdir_idx < PHY_MEM / PD_SIZE; pdir_idx ++) {
		make_pde(&pdir[pdir_idx], ptable);
		make_pde(&pdir[pdir_idx + KOFFSET / PD_SIZE], ptable);
		for (ptable_idx = 0; ptable_idx < NR_PTE; ptable_idx ++) {
			make_pte(ptable, (void*)(pframe_idx << 12));
			pframe_idx ++;
			ptable ++;
		}
	}

	/* make CR3 to be the entry of page directory */
	cr3.val = 0;
	cr3.page_directory_base = ((uint32_t)pdir) >> 12;
	write_cr3(&cr3);

	/* set PG bit in CR0 to enable paging */
	cr0.val = read_cr0();
	cr0.paging = 1;
	write_cr0(&cr0);

	/* Now we can access global variables! 
	 * Store CR3 in the global variable for future use. */
	kcr3.val = cr3.val;
}
예제 #6
0
파일: vmem.c 프로젝트: ShijianXu/ICS
void create_video_mapping() {
	/* TODO: create an identical mapping from virtual memory area 
	 * [0xa0000, 0xa0000 + SCR_SIZE) to physical memory area 
	 * [0xa0000, 0xa0000 + SCR_SIZE) for user program. You may define
	 * some page tables to create this mapping.
	 */

	PDE *pdir = (PDE *)get_updir();
	PTE *ptable = (PTE *)va_to_pa(vdtable);
//	ptable += (SCR_SIZE / PAGE_SIZE + 1) * PAGE_SIZE;
		
	pdir->val = make_pde(vdtable);
//	pdir[0 + KOFFSET / PT_SIZE].val = make_pde(vdtable);

//	ptable --;
	uint32_t pframe_addr =	VMEM_ADDR;
	int i=0;
	for(; i<=0xf; i++) {
		ptable[i+0xa0].val = make_pte(pframe_addr);
		pframe_addr += PAGE_SIZE;
	}

//	panic("please implement me");
}