📄 pgtable.h
字号:
if (!mem_map[MAP_NR(pgdp)].reserved)
mem_map[MAP_NR(pgdp)].count++;
}
*/
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
extern inline int pte_cow(pte_t pte) { return pte_val(pte) & _PAGE_COW; }
extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; }
extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
extern inline pte_t pte_uncow(pte_t pte) { pte_val(pte) &= ~_PAGE_COW; return pte; }
extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; }
extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
extern inline pte_t pte_mkcow(pte_t pte) { pte_val(pte) |= _PAGE_COW; return pte; }
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
{ pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
/*extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
{ pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
*/
extern inline unsigned long pte_page(pte_t pte)
{ return pte_val(pte) & PAGE_MASK; }
extern inline unsigned long pmd_page(pmd_t pmd)
{ return pmd_val(pmd) & PAGE_MASK; }
/* to find an entry in a page-table-directory */
extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
{
return mm->pgd + (address >> PGDIR_SHIFT);
}
/* Find an entry in the second-level page table.. */
extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) dir;
}
/* Find an entry in the third-level page table.. */
extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
{
return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
}
/*
* Allocate and free page tables. The xxx_kernel() versions are
* used to allocate a kernel page table - this turns on ASN bits
* if any, and marks the page tables reserved.
*/
extern inline void pte_free_kernel(pte_t * pte)
{
free_page((unsigned long) pte);
}
/*extern inline void pte_free_kernel(pte_t * pte)
{
mem_map[MAP_NR(pte)] = 1;
free_page((unsigned long) pte);
}
*/
/*
extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
{
address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
if (pmd_none(*pmd)) {
pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
return page + address;
}
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
return NULL;
}
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
return NULL;
}
return (pte_t *) pmd_page(*pmd) + address;
}*/
/*
extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
{
printk("pte_alloc_kernel pmd = %08X, address = %08X\n", pmd, address);
address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
printk("address now = %08X\n", address);
if (pmd_none(*pmd)) {
pte_t *page;
printk("pmd_none(*pmd) true\n");
page = (pte_t *) get_free_page(GFP_KERNEL);
printk("page = %08X after get_free_page(%08X)\n",page,GFP_KERNEL);
if (pmd_none(*pmd)) {
printk("pmd_none(*pmd=%08X) still\n",*pmd);
if (page) {
printk("page true = %08X\n",page);
pmd_set(pmd, page);
printk("pmd_set(%08X,%08X)\n",pmd,page);
mem_map[MAP_NR(page)].reserved = 1;
printk("did mem_map\n",pmd,page);
return page + address;
}
printk("did pmd_set(%08X, %08X\n",pmd,BAD_PAGETABLE);
pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
return NULL;
}
printk("did free_page(%08X)\n",page);
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
return NULL;
}
printk("returning pmd_page(%08X) + %08X\n",pmd_page(*pmd) , address);
return (pte_t *) pmd_page(*pmd) + address;
}
*/
extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
{
address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
if (pmd_none(*pmd)) {
pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
/* pmd_set(pmd,page);*/
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
return page + address;
}
/* pmd_set(pmd, BAD_PAGETABLE);*/
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
return NULL;
}
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
/* pmd_set(pmd, (pte_t *) BAD_PAGETABLE); */
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
return NULL;
}
return (pte_t *) pmd_page(*pmd) + address;
}
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
*/
extern inline void pmd_free_kernel(pmd_t * pmd)
{
}
extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
{
return (pmd_t *) pgd;
}
extern inline void pte_free(pte_t * pte)
{
free_page((unsigned long) pte);
}
extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
{
address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
if (pmd_none(*pmd)) {
pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
return page + address;
}
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
return NULL;
}
free_page((unsigned long) page);
}
if (pmd_bad(*pmd)) {
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
return NULL;
}
return (pte_t *) pmd_page(*pmd) + address;
}
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
*/
extern inline void pmd_free(pmd_t * pmd)
{
}
extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
{
return (pmd_t *) pgd;
}
extern inline void pgd_free(pgd_t * pgd)
{
free_page((unsigned long) pgd);
}
extern inline pgd_t * pgd_alloc(void)
{
return (pgd_t *) get_free_page(GFP_KERNEL);
}
extern pgd_t swapper_pg_dir[1024*8];
/*extern pgd_t *swapper_pg_dir;*/
/*
* Software maintained MMU tables may have changed -- update the
* hardware [aka cache]
*/
extern inline void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t _pte)
{
#if 0
printk("Update MMU cache - VMA: %x, Addr: %x, PTE: %x\n", vma, address, *(long *)&_pte);
_printk("Update MMU cache - VMA: %x, Addr: %x, PTE: %x\n", vma, address, *(long *)&_pte);
/* MMU_hash_page(&(vma->vm_task)->tss, address & PAGE_MASK, (pte *)&_pte);*/
#endif
MMU_hash_page(&(current)->tss, address & PAGE_MASK, (pte *)&_pte);
}
#ifdef _SCHED_INIT_
#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
#endif
#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
#define SWP_OFFSET(entry) ((entry) >> 8)
#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
#endif /* _PPC_PAGE_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -