本文整理汇总了C++中page2pa函数的典型用法代码示例。如果您正苦于以下问题:C++ page2pa函数的具体用法?C++ page2pa怎么用?C++ page2pa使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了page2pa函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: pml4e_walk
pte_t *
pml4e_walk(pml4e_t *pml4e, const void *va, int create)
{
struct Page *newPage = NULL;
//if(!create) cprintf("va = %0x, pml4e[PML4(va)] = %0x\n", va, pml4e[PML4(va)]);
if (!pml4e[PML4(va)]) {
if (!create)
return NULL;
else {
newPage = page_alloc(0);
if (newPage == 0) {
return NULL;
} else {
newPage->pp_ref++;
pml4e[PML4(va)] = page2pa(newPage) | PTE_U | PTE_W | PTE_P;
memset(page2kva(newPage), 0x00, PGSIZE);
}
}
}
pdpe_t* pdpe = (pdpe_t*)(KADDR((PTE_ADDR(pml4e[PML4(va)]))));
pte_t *result = pdpe_walk(pdpe, va, create);
if (!result && newPage) {
pml4e[PML4(va)] = 0;
newPage->pp_ref = 0;
page_free(newPage);
}
//return result + PTX(va);
if (result) {
return result + PTX(va);
}
else {
return result;
}
}
示例2: env_setup_vm
//
// Initialize the kernel virtual memory layout for environment e.
// Allocate a page directory, set e->env_pgdir and e->env_cr3 accordingly,
// and initialize the kernel portion of the new environment's address space.
// Do NOT (yet) map anything into the user portion
// of the environment's virtual address space.
//
// Returns 0 on success, < 0 on error. Errors include:
// -E_NO_MEM if page directory or table could not be allocated.
//
static int
env_setup_vm(struct Env *e)
{
int i, r;
struct Page *p = NULL;
// Allocate a page for the page directory
if ((r = page_alloc(&p)) < 0)
return r;
// Now, set e->env_pgdir and e->env_cr3,
// and initialize the page directory.
//
// Hint:
// - The VA space of all envs is identical above UTOP
// (except at VPT and UVPT, which we've set below).
// See inc/memlayout.h for permissions and layout.
// Can you use boot_pgdir as a template? Hint: Yes.
// (Make sure you got the permissions right in Lab 2.)
// - The initial VA below UTOP is empty.
// - You do not need to make any more calls to page_alloc.
// - Note: pp_ref is not maintained for most physical pages
// mapped above UTOP -- but you do need to increment
// env_pgdir's pp_ref!
// LAB 3: Your code here.
e->env_pgdir = page2kva(p);
e->env_cr3 = page2pa(p);
memset(e->env_pgdir, 0, PGSIZE);
p->pp_ref++;
for(i = PDX(UTOP); i < NPDENTRIES; i++){
e->env_pgdir[i] = boot_pgdir[i];
}
// VPT and UVPT map the env's own page table, with
// different permissions.
e->env_pgdir[PDX(VPT)] = e->env_cr3 | PTE_P | PTE_W;
e->env_pgdir[PDX(UVPT)] = e->env_cr3 | PTE_P | PTE_U;
//cprintf("env_setup_vm end!!\n");
return 0;
}
示例3: e100_rfa_alloc
//
// Allocate the receive frame area.
//
// Initialize the RFA setting each rds's link pointer to point to the next RFD
// in the ring. The pointers need to be physical addresses because a DMA ring
// is created to be used by the device and a device on the PCI bus does not
// have access to the CPU's MMU to translate virtual addresses into physical
// addresses.
//
void
e100_rfa_alloc(void)
{
int i, r;
struct Page *pp;
struct rfd *rfd = NULL, *tail = NULL;
for (i = 0; i < RFASIZE; i++) {
// Allocate a page for each command block.
// Must zero out the contents of the page and
// increment the reference count for it.
if ((r = page_alloc(&pp)) != 0)
panic("e100_rfa_alloc: %e\n", r);
memset(page2kva(pp), 0, PGSIZE);
++pp->pp_ref;
// Initialize the RFD
rfd = page2kva(pp);
rfd->pa = page2pa(pp);
rfd->size = ETH_FRAME_LEN;
if (i == 0) {
e100.rfds = rfd;
} else {
// Extend the RFA by inserting the RFD
// after the current tail in the list.
tail->link = rfd->pa;
tail->next = rfd;
rfd->prev = tail;
}
// Set the new tail.
tail = rfd;
}
// Complete the ring.
tail->link = e100.rfds->pa;
tail->next = e100.rfds;
e100.rfds->prev = tail;
e100.rfds_avail = RFASIZE;
e100.rfd_to_clean = tail;
e100.rfd_to_use = e100.rfds;
}
示例4: page_insert
int
page_insert(pgd_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) {
pte_t *ptep = get_pte(pgdir, la, 1);
if (ptep == NULL) {
return -E_NO_MEM;
}
page_ref_inc(page);
if (*ptep & PTE_P) {
struct Page *p = pte2page(*ptep);
if (p == page) {
page_ref_dec(page);
}
else {
page_remove_pte(pgdir, la, ptep);
}
}
*ptep = page2pa(page) | PTE_P | perm;
tlb_invalidate(pgdir, la);
return 0;
}
示例5: page_insert
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
// - If there is already a page mapped at 'va', it should be page_remove()d.
// - If necessary, on demand, a page table should be allocated and inserted
// into 'pgdir'.
// - pp->pp_ref should be incremented if the insertion succeeds.
// - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// However, try not to distinguish this case in your code, as this
// frequently leads to subtle bugs; there's an elegant way to handle
// everything in one code path.
//
// RETURNS:
// 0 on success
// -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
// Fill this function in
pte_t *ptep = pgdir_walk(pgdir, va, true);
if (!ptep)
return -E_NO_MEM;
//这儿非常trick!
//如果va, pp和以前的调用的page_insert相同,且pp->pp_ref++写在page_remove()
//下面的话, page_remove()就会把pp放到page_free_list上了
//所以必须先ref++,再检测page_remove()
pp->pp_ref++;
if (*ptep & PTE_P)
page_remove(pgdir, va);
*ptep = page2pa(pp) | perm | PTE_P;
//page directory的权限
pgdir[PDX(va)] |= *ptep & 0xfff;
tlb_invalidate(pgdir, va);
return 0;
}
示例6: env_setup_vm
//
// Initialize the kernel virtual memory layout for environment e.
// Allocate a page directory, set e->env_pgdir and e->env_cr3 accordingly,
// and initialize the kernel portion of the new environment's address space.
// Do NOT (yet) map anything into the user portion
// of the environment's virtual address space.
//
// Returns 0 on success, < 0 on error. Errors include:
// -E_NO_MEM if page directory or table could not be allocated.
//
static int
env_setup_vm(struct Env *e)
{
int i, r;
struct Page *p = NULL;
// Allocate a page for the page directory
if ((r = page_alloc(&p)) < 0)
return r;
// Now, set e->env_pgdir and e->env_cr3,
// and initialize the page directory.
// Hint:
// - Remember that page_alloc doesn't zero the page.
// - The VA space of all envs is identical above UTOP
// (except at VPT and UVPT, which we've set below).
// See inc/memlayout.h for permissions and layout.
// Can you use boot_pgdir as a template? Hint: Yes.
// (Make sure you got the permissions right in Lab 2.)
// - The initial VA below UTOP is empty.
// - You do not need to make any more calls to page_alloc.
// - Note: In general, pp_ref is not maintained for
// physical pages mapped only above UTOP, but env_pgdir
// is an exception -- you need to increment env_pgdir's
// pp_ref for env_free to work correctly.
// - The functions in kern/pmap.h are handy.
// LAB 3: Your code here.
//sunus,DEC 6,2010
p->pp_ref++;
e->env_pgdir = page2kva(p);
e->env_cr3 = page2pa(p);
memset(e->env_pgdir, 0, PDX(UTOP) * 4);
memmove(&(e->env_pgdir[PDX(UTOP)]), &(boot_pgdir[PDX(UTOP)]),(1024 - PDX(UTOP)) * 4);
//sunus,DEC 6,2010
// VPT and UVPT map the env's own page table, with
// different permissions.
e->env_pgdir[PDX(VPT)] = e->env_cr3 | PTE_P | PTE_W;
e->env_pgdir[PDX(UVPT)] = e->env_cr3 | PTE_P | PTE_U;
return 0;
}
示例7: cbl_alloc
/**
* Allocate CB_MAX_NUM pages, each page for a control block
*/
static void
cbl_alloc () {
int i, r;
struct Page *p;
struct cb *prevcb = NULL;
struct cb *currcb = NULL;
// Allocate physical page for Control block
for (i = 0; i < CB_MAX_NUM; i++) {
if ((r = page_alloc (&p)) != 0)
panic ("cbl_init: run out of physical memory! %e\n", r);
p -> pp_ref ++;
memset (page2kva (p), 0, PGSIZE);
currcb = (struct cb *)page2kva (p);
currcb->phy_addr = page2pa (p);
if (i == 0)
nic.cbl.start = currcb;
else {
prevcb->cb_link = currcb->phy_addr;
prevcb->next = currcb;
currcb->prev = prevcb;
}
prevcb = currcb;
}
prevcb->cb_link = nic.cbl.start->phy_addr;
nic.cbl.start->prev = prevcb;
prevcb->next = nic.cbl.start;
nic.cbl.cb_avail = CB_MAX_NUM;
nic.cbl.cb_wait = 0;
nic.cbl.front = nic.cbl.start;
nic.cbl.rear = nic.cbl.start->prev;
}
示例8: page_insert
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
// - If there is already a page mapped at 'va', it should be page_remove()d.
// - If necessary, on demand, a page table should be allocated and inserted
// into 'pgdir'.
// - pp->pp_ref should be incremented if the insertion succeeds.
// - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// Don't be tempted to write special-case code to handle this
// situation, though; there's an elegant way to address it.
//
// RETURNS:
// 0 on success
// -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct Page *pp, void *va, int perm)
{
pte_t* pte = pgdir_walk(pgdir, va, 0);
physaddr_t ppa = page2pa(pp);
// If some page is already mapped there
if (pte != NULL) {
if (*pte & PTE_P) page_remove(pgdir, va); // also invalidates tlb
if (page_free_list == pp) page_free_list = page_free_list->pp_link;
}
else {
pte = pgdir_walk(pgdir, va, 1); // Allocate new page table
if (pte == NULL) return -E_NO_MEM; // failed to alloc page table
}
*pte = ppa | perm | PTE_P;
pp->pp_ref++;
tlb_invalidate(pgdir, va);
return 0;
}
示例9: page_insert
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
// - If there is already a page mapped at 'va', it should be page_remove()d.
// - If necessary, on demand, a page table should be allocated and inserted
// into 'pgdir'.
// - pp->pp_ref should be incremented if the insertion succeeds.
// - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// However, try not to distinguish this case in your code, as this
// frequently leads to subtle bugs; there's an elegant way to handle
// everything in one code path.
//
// RETURNS:
// 0 on success
// -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
// Fill this function in
// SUNUS, 28, October, 2013
struct PageInfo *page;
pte_t *pte;
pte = pgdir_walk(pgdir, va, 1);
if (!pte) {
// indicate that there is no free pages.
return -E_NO_MEM;
}
pp->pp_ref++;
if (*pte) {
page_remove(pgdir, va);
}
*pte = page2pa(pp);
*pte |= (PTE_P|perm);
tlb_invalidate(pgdir, va);
return 0;
}
示例10: page_insert
/**
* page_insert - build the map of phy addr of an Page with the linear addr @la
* @param pgdir page directory
* @param page the page descriptor of the page to be inserted
* @param la logical address of the page
* @param perm permission of the page
* @return 0 on success and error code when failed
*/
int
page_insert(pgd_t *pgdir, struct Page *page, uintptr_t la, pte_perm_t perm) {
pte_t *ptep = get_pte(pgdir, la, 1);
if (ptep == NULL) {
return -E_NO_MEM;
}
page_ref_inc(page);
if (*ptep != 0) {
if (ptep_present(ptep) && pte2page(*ptep) == page) {
page_ref_dec(page);
goto out;
}
page_remove_pte(pgdir, la, ptep);
}
out:
ptep_map(ptep, page2pa(page));
ptep_set_perm(ptep, perm);
mp_tlb_update(pgdir, la);
return 0;
}
示例11: page_free
//
// Return a page to the free list.
// (This function should only be called when pp->pp_ref reaches 0.)
//
void
page_free(struct Page *pp)
{
// Fill this function in
if(pp->pp_ref==0)
{
if(page_free_list==NULL)
{
pp->pp_link=page_free_list;
page_free_list=pp;
return;
}
if(page2pa(pp)<page2pa(page_free_list))
{
pp->pp_link=page_free_list;
page_free_list=pp;
return;
}
struct Page* skip=page_free_list;
int found=0;
while(skip->pp_link!=NULL)
{
if(page2pa(pp)>page2pa(skip)&&
page2pa(pp)<page2pa(skip->pp_link))
{
found=1;
break;
}
skip=skip->pp_link;
}
if(found==0)
{
skip->pp_link=pp;
pp->pp_link=NULL;
return;
}
if(found==1)
{
struct Page* temp=skip->pp_link;
skip->pp_link=pp;
pp->pp_link=temp;
}
}
else
{
panic("still have reference:%d\n",pp->pp_ref);
}
}
示例12: check_page_installed_pgdir
// check page_insert, page_remove, &c, with an installed kern_pgdir
static void
check_page_installed_pgdir(void)
{
struct Page *pp, *pp0, *pp1, *pp2;
struct Page *fl;
pte_t *ptep, *ptep1;
uintptr_t va;
int i;
// check that we can read and write installed pages
pp1 = pp2 = 0;
assert((pp0 = page_alloc(0)));
assert((pp1 = page_alloc(0)));
assert((pp2 = page_alloc(0)));
page_free(pp0);
memset(page2kva(pp1), 1, PGSIZE);
memset(page2kva(pp2), 2, PGSIZE);
page_insert(kern_pgdir, pp1, (void*) PGSIZE, PTE_W);
assert(pp1->pp_ref == 1);
assert(*(uint32_t *)PGSIZE == 0x01010101U);
page_insert(kern_pgdir, pp2, (void*) PGSIZE, PTE_W);
assert(*(uint32_t *)PGSIZE == 0x02020202U);
assert(pp2->pp_ref == 1);
assert(pp1->pp_ref == 0);
*(uint32_t *)PGSIZE = 0x03030303U;
assert(*(uint32_t *)page2kva(pp2) == 0x03030303U);
page_remove(kern_pgdir, (void*) PGSIZE);
assert(pp2->pp_ref == 0);
// forcibly take pp0 back
assert(PTE_ADDR(kern_pgdir[0]) == page2pa(pp0));
kern_pgdir[0] = 0;
assert(pp0->pp_ref == 1);
pp0->pp_ref = 0;
// free the pages we took
page_free(pp0);
cprintf("check_page_installed_pgdir() succeeded!\n");
}
示例13: pgdir_walk
// Given 'pgdir', a pointer to a page directory, pgdir_walk returns
// a pointer to the page table entry (PTE) for linear address 'va'.
// This requires walking the two-level page table structure.
//
// bluesea
// pgdir_walk具体返回的是:
// 虚拟地址va, 所在的页面对应的page table 表项的地址,所以是二级页表page table
// 的表项的地址,而非page dir的表项
// (理由分析见check_page()中的相关分析)
// 并且是该地址的虚拟地址!
//
//
// 下面这个需求可能和这个想法有矛盾:PTE_P置为0,即缺页的时候本应该由缺页中断处理。
// 那是另外故事,在这儿,pgdir_walk基本上只用于初始化内核虚拟内存的映射,
// 所以缺页新alloc page table没什么问题。
//
// The relevant page table page might not exist yet.
// If this is true, and create == false, then pgdir_walk returns NULL.
// Otherwise, pgdir_walk allocates a new page table page with page_alloc.
// - If the allocation fails, pgdir_walk returns NULL.
// - Otherwise, the new page's reference count is incremented,
// the page is cleared,
// and pgdir_walk returns a pointer into the new page table page.
// (注:这种情况下也是返回页表项的地址,而页目录的地址。页表项的各个FLAG不用管
// 只需要把页目录对应的位置PTE_P置位即可。)
//
// Hint 1: you can turn a PageInfo * into the physical address of the
// page it refers to with page2pa() from kern/pmap.h.
//
// Hint 2: the x86 MMU checks permission bits in both the page directory
// and the page table, so it's safe to leave permissions in the page
// more permissive than strictly necessary.
//
// Hint 3: look at inc/mmu.h for useful macros that mainipulate page
// table and page directory entries.
//
pte_t *
pgdir_walk(pde_t *pgdir, const void *va, int create)
{
// Fill this function in
// bluesea
uint32_t pdx = PDX(va), ptx = PTX(va);
pde_t *pt = 0;
if (pgdir[pdx] & PTE_P){
pt = KADDR(PTE_ADDR(pgdir[pdx]));
return &pt[ptx];
}
if (!create)
return NULL;
struct PageInfo *page = page_alloc(ALLOC_ZERO);
if (!page)
return NULL;
page->pp_ref = 1;
pgdir[pdx] = page2pa(page) | PTE_P | PTE_U;
pt = page2kva(page);
//pt[ptx] = PTE_U;
return &pt[ptx];
}
示例14: page_insert
//
// Map the physical page 'pp' at virtual address 'va'.
// The permissions (the low 12 bits) of the page table entry
// should be set to 'perm|PTE_P'.
//
// Requirements
// - If there is already a page mapped at 'va', it should be page_remove()d.
// - If necessary, on demand, a page table should be allocated and inserted
// into 'pgdir'.
// - pp->pp_ref should be incremented if the insertion succeeds.
// - The TLB must be invalidated if a page was formerly present at 'va'.
//
// Corner-case hint: Make sure to consider what happens when the same
// pp is re-inserted at the same virtual address in the same pgdir.
// However, try not to distinguish this case in your code, as this
// frequently leads to subtle bugs; there's an elegant way to handle
// everything in one code path.
//
// RETURNS:
// 0 on success
// -E_NO_MEM, if page table couldn't be allocated
//
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
// Find the page_table_entry and create if needed
pte_t * page_table_entry = pgdir_walk(pgdir, va, 1);
if (page_table_entry == NULL) {
return -E_NO_MEM;
}
pp->pp_ref++;
// If it already exists, then remove it
if (*page_table_entry & PTE_P) {
// This will remove the page and tlb invalidate it
page_remove(pgdir, va);
}
*page_table_entry = page2pa(pp) | perm | PTE_P;
return 0;
}
示例15: ap_init
void ap_init(void)
{
gdt_init(per_cpu_ptr(cpus, bcpuid));
tls_init(per_cpu_ptr(cpus, bcpuid));
kprintf("CPU%d alive\n", myid());
/* load new pagetable(shared with bsp) */
pmm_init_ap();
idt_init(); // init interrupt descriptor table
/* test pmm */
struct Page *p = alloc_pages(2);
kprintf("I'm %d, get 0x%016llx(PA)\n", myid(), page2pa(p));
free_pages(p, 2);
lapic_init();
proc_init_ap();
atomic_inc(&bsync); /* let BSP know we are up */
intr_enable(); // enable irq interrupt
cpu_idle();
}