Skip to content

Commit

Permalink
Update MIPS to use the 4-level pagetable code thereby getting rid of
Browse files Browse the repository at this point in the history
the compacrapability headers.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Ralf Baechle committed Oct 29, 2005
1 parent 57f0060 commit c6e8b58
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 99 deletions.
10 changes: 8 additions & 2 deletions arch/mips/lib-32/dump_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned long addr, val;
Expand All @@ -162,7 +163,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %08x, ", (unsigned int) pgd);

pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
printk("pud == %08x, ", (unsigned int) pud);

pmd = pmd_offset(pud, addr);
printk("pmd == %08x, ", (unsigned int) pmd);

pte = pte_offset(pmd, addr);
Expand Down Expand Up @@ -195,13 +199,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;

addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
Expand Down
10 changes: 8 additions & 2 deletions arch/mips/lib-32/r3k_dump_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned int addr;
Expand All @@ -121,7 +122,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %08x, ", (unsigned int) pgd);

pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
printk("pud == %08x, ", (unsigned int) pud);

pmd = pmd_offset(pud, addr);
printk("pmd == %08x, ", (unsigned int) pmd);

pte = pte_offset(pmd, addr);
Expand Down Expand Up @@ -149,13 +153,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;

addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
Expand Down
10 changes: 8 additions & 2 deletions arch/mips/lib-64/dump_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ void dump_tlb_nonwired(void)
void dump_list_process(struct task_struct *t, void *address)
{
pgd_t *page_dir, *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte, page;
unsigned long addr, val;
Expand All @@ -155,7 +156,10 @@ void dump_list_process(struct task_struct *t, void *address)
pgd = pgd_offset(t->mm, addr);
printk("pgd == %016lx\n", (unsigned long) pgd);

pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
printk("pud == %016lx\n", (unsigned long) pud);

pmd = pmd_offset(pud, addr);
printk("pmd == %016lx\n", (unsigned long) pmd);

pte = pte_offset(pmd, addr);
Expand Down Expand Up @@ -184,13 +188,15 @@ void dump_list_current(void *address)
unsigned int vtop(void *address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned int addr, paddr;

addr = (unsigned long) address;
pgd = pgd_offset(current->mm, addr);
pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
paddr |= (addr & ~PAGE_MASK);
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/mm/c-r3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,14 @@ static inline unsigned long get_phys_page (unsigned long addr,
struct mm_struct *mm)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long physpage;

pgd = pgd_offset(mm, addr);
pmd = pmd_offset(pgd, addr);
pud = pud_offset(pgd, addr);
pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);

if ((physpage = pte_val(*pte)) & _PAGE_VALID)
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/mm/c-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,14 @@ static inline void local_r4k_flush_cache_page(void *args)
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;

page &= PAGE_MASK;
pgdp = pgd_offset(mm, page);
pmdp = pmd_offset(pgdp, page);
pudp = pud_offset(pgdp, page);
pmdp = pmd_offset(pudp, page);
ptep = pte_offset(pmdp, page);

/*
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/mm/c-tx39.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;

Expand All @@ -195,7 +196,8 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page

page &= PAGE_MASK;
pgdp = pgd_offset(mm, page);
pmdp = pmd_offset(pgdp, page);
pudp = pud_offset(pgdp, page);
pmdp = pmd_offset(pudp, page);
ptep = pte_offset(pmdp, page);

/*
Expand Down
10 changes: 8 additions & 2 deletions arch/mips/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
*/
int offset = __pgd_offset(address);
pgd_t *pgd, *pgd_k;
pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k;
pte_t *pte_k;

Expand All @@ -222,8 +223,13 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
goto no_context;
set_pgd(pgd, *pgd_k);

pmd = pmd_offset(pgd, address);
pmd_k = pmd_offset(pgd_k, address);
pud = pud_offset(pgd, address);
pud_k = pud_offset(pgd_k, address);
if (!pud_present(*pud_k))
goto no_context;

pmd = pmd_offset(pud, address);
pmd_k = pmd_offset(pud_k, address);
if (!pmd_present(*pmd_k))
goto no_context;
set_pmd(pmd, *pmd_k);
Expand Down
28 changes: 17 additions & 11 deletions arch/mips/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pte_t *kmap_pte;
pgprot_t kmap_prot;

#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))

static void __init kmap_init(void)
{
Expand All @@ -101,26 +101,32 @@ void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int i, j;
int i, j, k;
unsigned long vaddr;

vaddr = start;
i = __pgd_offset(vaddr);
j = __pmd_offset(vaddr);
j = __pud_offset(vaddr);
k = __pmd_offset(vaddr);
pgd = pgd_base + i;

for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
pmd = (pmd_t *)pgd;
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd(pte));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
pud = (pud_t *)pgd;
for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
pmd = (pmd_t *)pud;
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd(pte));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
}
vaddr += PMD_SIZE;
}
vaddr += PMD_SIZE;
k = 0;
}
j = 0;
}
Expand Down
15 changes: 9 additions & 6 deletions arch/mips/mm/ioremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,14 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
BUG();
spin_lock(&init_mm.page_table_lock);
do {
pud_t *pud;
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);

error = -ENOMEM;
pud = pud_alloc(&init_mm, dir, address);
if (!pud)
break;
pmd = pmd_alloc(&init_mm, pud, address);
if (!pmd)
break;
if (remap_area_pmd(pmd, address, end - address,
Expand Down Expand Up @@ -141,7 +146,7 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
*/
if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
flags == _CACHE_UNCACHED)
return (void *) KSEG1ADDR(phys_addr);
return (void *) CKSEG1ADDR(phys_addr);

/*
* Don't allow anybody to remap normal RAM that we're using..
Expand Down Expand Up @@ -180,7 +185,7 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
return (void *) (offset + (char *)addr);
}

#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)

void __iounmap(volatile void __iomem *addr)
{
Expand All @@ -190,10 +195,8 @@ void __iounmap(volatile void __iomem *addr)
return;

p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
if (!p) {
if (!p)
printk(KERN_ERR "iounmap: bad address %p\n", addr);
return;
}

kfree(p);
}
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/mm/pgtable-32.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void __init pagetable_init(void)
#ifdef CONFIG_HIGHMEM
unsigned long vaddr;
pgd_t *pgd, *pgd_base;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
#endif
Expand All @@ -60,7 +61,8 @@ void __init pagetable_init(void)
fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);

pgd = swapper_pg_dir + __pgd_offset(vaddr);
pmd = pmd_offset(pgd, vaddr);
pud = pud_offset(pgd, vaddr);
pmd = pmd_offset(pud, vaddr);
pte = pte_offset_kernel(pmd, vaddr);
pkmap_page_table = pte;
#endif
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/mm/tlb-andes.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
int idx, pid;
Expand All @@ -220,7 +221,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
write_c0_entryhi(address | (pid));
pgdp = pgd_offset(vma->vm_mm, address);
tlb_probe();
pmdp = pmd_offset(pgdp, address);
pudp = pud_offset(pgdp, address);
pmdp = pmd_offset(pudp, address);
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);
write_c0_entrylo0(pte_val(*ptep++) >> 6);
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/mm/tlb-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
int idx, pid;
Expand All @@ -246,7 +247,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
mtc0_tlbw_hazard();
tlb_probe();
BARRIER;
pmdp = pmd_offset(pgdp, address);
pudp = pud_offset(pgdp, address);
pmdp = pmd_offset(pudp, address);
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);

Expand Down
42 changes: 34 additions & 8 deletions include/asm-mips/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,48 @@ static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
typedef struct { unsigned long pte; } pte_t;
#define pte_val(x) ((x).pte)
#endif
#define __pte(x) ((pte_t) { (x) } )

typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
/*
* For 3-level pagetables we defines these ourselves, for 2-level the
* definitions are supplied by <asm-generic/pgtable-nopmd.h>.
*/
#ifdef CONFIG_64BIT

typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
#define __pmd(x) ((pmd_t) { (x) } )

#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
#endif

#define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
/*
* Right now we don't support 4-level pagetables, so all pud-related
* definitions come from <asm-generic/pgtable-nopud.h>.
*/

/*
* Finall the top of the hierarchy, the pgd
*/
typedef struct { unsigned long pgd; } pgd_t;
#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) } )

/*
* Manipulate page protection bits
*/
typedef struct { unsigned long pgprot; } pgprot_t;
#define pgprot_val(x) ((x).pgprot)
#define __pgprot(x) ((pgprot_t) { (x) } )

/*
* On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd
* pair of pages we only have a single global bit per pair of pages. When
* writing to the TLB make sure we always have the bit set for both pages
* or none. This macro is used to access the `buddy' of the pte we're just
* working on.
*/
#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))

#endif /* !__ASSEMBLY__ */

/* to align the pointer to the (next) page boundary */
Expand Down
Loading

0 comments on commit c6e8b58

Please sign in to comment.