diff options
Diffstat (limited to 'include/asm-sparc/page.h')
-rw-r--r-- | include/asm-sparc/page.h | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h new file mode 100644 index 000000000..a048ac76c --- /dev/null +++ b/include/asm-sparc/page.h @@ -0,0 +1,181 @@ +/* page.h: Various defines and such for MMU operations on the Sparc for + the Linux kernel. + + Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) +*/ + +#ifndef _SPARC_PAGE_H +#define _SPARC_PAGE_H + +#include <asm/asi.h> /* for get/set segmap/pte routines */ +#include <asm/contregs.h> /* for switch_to_context */ + +#define PAGE_SHIFT 12 /* This is the virtual page... */ + +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1UL << PAGE_SHIFT) + +/* to mask away the intra-page address bits */ +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +/* The following structure is used to hold the physical + * memory configuration of the machine. This is filled + * in probe_memory() and is later used by mem_init() to + * set up mem_map[]. We statically allocate 14 of these + * structs, this is arbitrary. The entry after the last + * valid one has num_bytes==0. + */ + +struct sparc_phys_banks { + unsigned long base_addr; + unsigned long num_bytes; +}; + +#define CONFIG_STRICT_MM_TYPECHECKS + +#ifdef CONFIG_STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +/* The current va context is global and known, so all that is needed to + * do an invalidate is flush the VAC. + */ + +#define invalidate() flush_vac_context() /* how conveeeiiiiinnnient :> */ + +#define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +#define PAGE_OFFSET 0 +#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT) +#define MAP_PAGE_RESERVED (1<<15) + + +#endif /* !(__ASSEMBLY__) */ + +/* The rest is kind of funky because on the sparc, the offsets into the mmu + * entries are encoded in magic alternate address space tables. I will + * probably find some nifty inline assembly routines to do the equivalent. + * Much thought must go into this code. (davem@caip.rutgers.edu) + */ + +/* Bitfields within a Sparc sun4c PTE (page table entry). */ + +#define PTE_V 0x80000000 /* valid bit */ +#define PTE_ACC 0x60000000 /* access bits */ +#define PTE_W 0x40000000 /* writable bit */ +#define PTE_P 0x20000000 /* privileged page */ +#define PTE_NC 0x10000000 /* page is non-cacheable */ +#define PTE_TYP 0x0c000000 /* page type field */ +#define PTE_RMEM 0x00000000 /* type == on board real memory */ +#define PTE_IO 0x04000000 /* type == i/o area */ +#define PTE_VME16 0x08000000 /* type == 16-bit VME area */ +#define PTE_VME32 0x0c000000 /* type == 32-bit VME area */ +#define PTE_R 0x02000000 /* page has been referenced */ +#define PTE_M 0x01000000 /* page has been modified */ +#define PTE_RESV 0x00f80000 /* reserved bits */ +#define PTE_PHYPG 0x0007ffff /* phys pg number, sun4c only uses 16bits */ + +extern __inline__ unsigned long get_segmap(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("lduba [%1] 0x3, %0" : + "=r" (entry) : + "r" (addr)); + + return (entry&0x7f); +} + +extern __inline__ void put_segmap(unsigned long addr, unsigned long entry) +{ + + __asm__ __volatile__("stba %1, [%0] 0x3" : : "r" (addr), "r" (entry&0x7f)); + + return; +} + +extern __inline__ unsigned long get_pte(unsigned long addr) +{ + register unsigned long entry; + + __asm__ __volatile__("lda [%1] 0x4, %0" : + "=r" (entry) : + "r" (addr)); + return entry; +} + +extern __inline__ void put_pte(unsigned long addr, unsigned long entry) +{ + __asm__ __volatile__("sta %1, [%0] 0x4" : : + "r" (addr), + "r" (entry)); + + return; +} + +extern __inline__ void switch_to_context(int context) +{ + __asm__ __volatile__("stba %0, [%1] 0x2" : : + "r" (context), + "r" (0x30000000)); + + return; +} + +extern __inline__ int get_context(void) +{ + register int ctx; + + __asm__ __volatile__("lduba [%1] 0x2, %0" : + "=r" (ctx) : + "r" (0x30000000)); + + return ctx; +} + +typedef unsigned short mem_map_t; + +#endif /* __KERNEL__ */ + +#endif /* _SPARC_PAGE_H */ |