linux-old/include/asm-m68k/sun3_pgalloc.h
<<
>>
Prefs
   1/* sun3_pgalloc.h --
   2 * reorganization around 2.3.39, routines moved from sun3_pgtable.h 
   3 *
   4 * moved 1/26/2000 Sam Creasey
   5 */
   6
   7#ifndef _SUN3_PGALLOC_H
   8#define _SUN3_PGALLOC_H
   9
  10/* Pagetable caches. */
  11//todo: should implement for at least ptes. --m
  12#define pgd_quicklist ((unsigned long *) 0)
  13#define pmd_quicklist ((unsigned long *) 0)
  14#define pte_quicklist ((unsigned long *) 0)
  15#define pgtable_cache_size (0L)
  16
  17/* Allocation and deallocation of various flavours of pagetables. */
  18static inline int free_pmd_fast(pmd_t *pmdp) { return 0; }
  19static inline int free_pmd_slow(pmd_t *pmdp) { return 0; }
  20static inline pmd_t *get_pmd_fast (void) { return (pmd_t *) 0; }
  21
  22//todo: implement the following properly.
  23#define get_pte_fast() ((pte_t *) 0)
  24#define get_pte_slow pte_alloc
  25#define free_pte_fast(pte)
  26#define free_pte_slow pte_free
  27
  28/* FIXME - when we get this compiling */
  29/* erm, now that it's compiling, what do we do with it? */
  30#define _KERNPG_TABLE 0
  31
  32static inline void pte_free_kernel(pte_t *pte)
  33{
  34        free_page((unsigned long) pte);
  35}
  36
  37extern const char bad_pmd_string[];
  38
  39static inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
  40{
  41        address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
  42        if (pmd_none(*pmd)) {
  43                pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
  44                if (pmd_none(*pmd)) {
  45                        if (page) {
  46                                pmd_val(*pmd) = _KERNPG_TABLE + __pa(page);
  47                                return page + address;
  48                        }
  49                        pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE);
  50                        return NULL;
  51                }
  52                free_page((unsigned long) page);
  53        }
  54        if (pmd_bad(*pmd)) {
  55                printk(bad_pmd_string, pmd_val(*pmd));
  56                printk("at kernel pgd off %08x\n", (unsigned int)pmd);
  57                pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE);
  58                return NULL;
  59        }
  60        return (pte_t *) __pmd_page(*pmd) + address;
  61}
  62
  63/*
  64 * allocating and freeing a pmd is trivial: the 1-entry pmd is
  65 * inside the pgd, so has no extra memory associated with it.
  66 */
  67static inline void pmd_free_kernel(pmd_t *pmd)
  68{
  69//        pmd_val(*pmd) = 0;
  70}
  71
  72static inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
  73{
  74        return (pmd_t *) pgd;
  75}
  76
  77#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
  78#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
  79
  80static inline void pte_free(pte_t *pte)
  81{
  82        free_page((unsigned long) pte);
  83}
  84
  85static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  86{
  87        unsigned long page = __get_free_page(GFP_KERNEL);
  88
  89        if (!page)
  90                return NULL;
  91                
  92        memset((void *)page, 0, PAGE_SIZE);
  93//      pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(page);
  94/*      pmd_val(*pmd) = __pa(page); */
  95        return (pte_t *) (page);
  96}
  97
  98#define pte_alloc_one_fast(mm,addr) pte_alloc_one(mm,addr)
  99
 100#define pmd_populate(mm, pmd, pte) (pmd_val(*pmd) = __pa((unsigned long)pte))
 101
 102/*
 103 * allocating and freeing a pmd is trivial: the 1-entry pmd is
 104 * inside the pgd, so has no extra memory associated with it.
 105 */
 106static inline void pmd_free(pmd_t *pmd)
 107{
 108        pmd_val(*pmd) = 0;
 109}
 110
 111static inline void pgd_free(pgd_t *pgd)
 112{
 113        free_page((unsigned long) pgd);
 114}
 115
 116static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 117{
 118     pgd_t *new_pgd;
 119
 120     new_pgd = (pgd_t *)get_free_page(GFP_KERNEL);
 121     memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
 122     memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
 123     return new_pgd;
 124}
 125
 126#define pgd_populate(mm, pmd, pte) BUG()
 127
 128/* FIXME: the sun3 doesn't have a page table cache! 
 129   (but the motorola routine should just return 0) */
 130
 131extern int do_check_pgt_cache(int, int);
 132
 133static inline void set_pgdir(unsigned long address, pgd_t entry)
 134{
 135}
 136
 137/* Reserved PMEGs. */
 138extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
 139extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
 140extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
 141extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
 142
 143/* Flush all userspace mappings one by one...  (why no flush command,
 144   sun?) */
 145static inline void flush_tlb_all(void)
 146{
 147       unsigned long addr;
 148       unsigned char ctx, oldctx;
 149
 150       oldctx = sun3_get_context();
 151       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
 152               for(ctx = 0; ctx < 8; ctx++) {
 153                       sun3_put_context(ctx);
 154                       sun3_put_segmap(addr, SUN3_INVALID_PMEG);
 155               }
 156       }
 157
 158       sun3_put_context(oldctx);
 159       /* erase all of the userspace pmeg maps, we've clobbered them
 160          all anyway */
 161       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
 162               if(pmeg_alloc[addr] == 1) {
 163                       pmeg_alloc[addr] = 0;
 164                       pmeg_ctx[addr] = 0;
 165                       pmeg_vaddr[addr] = 0;
 166               }
 167       }
 168
 169}
 170
 171/* Clear user TLB entries within the context named in mm */
 172static inline void flush_tlb_mm (struct mm_struct *mm)
 173{
 174     unsigned char oldctx;
 175     unsigned char seg;
 176     unsigned long i;
 177
 178     oldctx = sun3_get_context();
 179     sun3_put_context(mm->context);
 180
 181     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
 182             seg = sun3_get_segmap(i);
 183             if(seg == SUN3_INVALID_PMEG)
 184                     continue;
 185             
 186             sun3_put_segmap(i, SUN3_INVALID_PMEG);
 187             pmeg_alloc[seg] = 0;
 188             pmeg_ctx[seg] = 0;
 189             pmeg_vaddr[seg] = 0;
 190     }
 191
 192     sun3_put_context(oldctx);
 193                     
 194}
 195
 196/* Flush a single TLB page. In this case, we're limited to flushing a
 197   single PMEG */
 198static inline void flush_tlb_page (struct vm_area_struct *vma,
 199                                   unsigned long addr)
 200{
 201        unsigned char oldctx;
 202        unsigned char i;
 203
 204        oldctx = sun3_get_context();
 205        sun3_put_context(vma->vm_mm->context);
 206        addr &= ~SUN3_PMEG_MASK;
 207        if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
 208        {
 209                pmeg_alloc[i] = 0;
 210                pmeg_ctx[i] = 0;
 211                pmeg_vaddr[i] = 0;
 212                sun3_put_segmap (addr,  SUN3_INVALID_PMEG);     
 213        }
 214        sun3_put_context(oldctx);
 215
 216}
 217/* Flush a range of pages from TLB. */
 218
 219static inline void flush_tlb_range (struct mm_struct *mm,
 220                      unsigned long start, unsigned long end)
 221{
 222        unsigned char seg, oldctx;
 223        
 224        start &= ~SUN3_PMEG_MASK;
 225
 226        oldctx = sun3_get_context();
 227        sun3_put_context(mm->context);
 228
 229        while(start < end)
 230        {
 231                if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) 
 232                     goto next;
 233                if(pmeg_ctx[seg] == mm->context) {
 234                        pmeg_alloc[seg] = 0;
 235                        pmeg_ctx[seg] = 0;
 236                        pmeg_vaddr[seg] = 0;
 237                }
 238                sun3_put_segmap(start, SUN3_INVALID_PMEG);
 239        next:
 240                start += SUN3_PMEG_SIZE;
 241        }
 242}
 243
 244/* Flush kernel page from TLB. */
 245static inline void flush_tlb_kernel_page (unsigned long addr)
 246{
 247        sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
 248}
 249
 250static inline void flush_tlb_pgtables(struct mm_struct *mm,
 251                                      unsigned long start, unsigned long end)
 252{
 253}
 254
 255#endif /* SUN3_PGALLOC_H */
 256
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.