root/arch/alpha/mm/init.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __bad_pagetable
  2. __bad_page
  3. __zero_page
  4. show_mem
  5. load_PCB
  6. paging_init
  7. mem_init
  8. si_meminfo

   1 /*
   2  *  linux/arch/alpha/mm/init.c
   3  *
   4  *  Copyright (C) 1995  Linus Torvalds
   5  */
   6 
   7 #include <linux/config.h>
   8 #include <linux/signal.h>
   9 #include <linux/sched.h>
  10 #include <linux/head.h>
  11 #include <linux/kernel.h>
  12 #include <linux/errno.h>
  13 #include <linux/string.h>
  14 #include <linux/types.h>
  15 #include <linux/ptrace.h>
  16 #include <linux/mman.h>
  17 #include <linux/mm.h>
  18 
  19 #include <asm/system.h>
  20 #include <asm/segment.h>
  21 #include <asm/pgtable.h>
  22 #include <asm/hwrpb.h>
  23 
  24 extern void scsi_mem_init(unsigned long);
  25 extern void sound_mem_init(void);
  26 extern void die_if_kernel(char *,struct pt_regs *,long);
  27 extern void show_net_buffers(void);
  28 
  29 /*
  30  * BAD_PAGE is the page that is used for page faults when linux
  31  * is out-of-memory. Older versions of linux just did a
  32  * do_exit(), but using this instead means there is less risk
  33  * for a process dying in kernel mode, possibly leaving a inode
  34  * unused etc..
  35  *
  36  * BAD_PAGETABLE is the accompanying page-table: it is initialized
  37  * to point to BAD_PAGE entries.
  38  *
  39  * ZERO_PAGE is a special page that is used for zero-initialized
  40  * data and COW.
  41  */
  42 pmd_t * __bad_pagetable(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44         memset((void *) EMPTY_PGT, 0, PAGE_SIZE);
  45         return (pmd_t *) EMPTY_PGT;
  46 }
  47 
  48 pte_t __bad_page(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
  51         return pte_mkdirty(mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED));
  52 }
  53 
  54 unsigned long __zero_page(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56         memset((void *) ZERO_PGE, 0, PAGE_SIZE);
  57         return (unsigned long) ZERO_PGE;
  58 }
  59 
  60 void show_mem(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62         int i,free = 0,total = 0,reserved = 0;
  63         int shared = 0;
  64 
  65         printk("Mem-info:\n");
  66         show_free_areas();
  67         printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
  68         i = high_memory >> PAGE_SHIFT;
  69         while (i-- > 0) {
  70                 total++;
  71                 if (mem_map[i] & MAP_PAGE_RESERVED)
  72                         reserved++;
  73                 else if (!mem_map[i])
  74                         free++;
  75                 else
  76                         shared += mem_map[i]-1;
  77         }
  78         printk("%d pages of RAM\n",total);
  79         printk("%d free pages\n",free);
  80         printk("%d reserved pages\n",reserved);
  81         printk("%d pages shared\n",shared);
  82         show_buffers();
  83 #ifdef CONFIG_NET
  84         show_net_buffers();
  85 #endif
  86 }
  87 
  88 extern unsigned long free_area_init(unsigned long, unsigned long);
  89 
  90 static void load_PCB(struct thread_struct * pcb)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         __asm__ __volatile__(
  93                 "stq $30,0(%0)\n\t"
  94                 "bis %0,%0,$16\n\t"
  95                 ".long %1"
  96                 : /* no outputs */
  97                 : "r" (pcb), "i" (PAL_swpctx)
  98                 : "$0", "$1", "$16", "$22", "$23", "$24", "$25");
  99 }
 100 
 101 /*
 102  * paging_init() sets up the page tables: in the alpha version this actually
 103  * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
 104  */
 105 unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107         int i;
 108         unsigned long newptbr;
 109         struct memclust_struct * cluster;
 110         struct memdesc_struct * memdesc;
 111 
 112         /* initialize mem_map[] */
 113         start_mem = free_area_init(start_mem, end_mem);
 114 
 115         /* find free clusters, update mem_map[] accordingly */
 116         memdesc = (struct memdesc_struct *) (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
 117         cluster = memdesc->cluster;
 118         for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
 119                 unsigned long pfn, nr;
 120                 if (cluster->usage & 1)
 121                         continue;
 122                 pfn = cluster->start_pfn;
 123                 nr = cluster->numpages;
 124 
 125                 /* non-volatile memory. We might want to mark this for later */
 126                 if (cluster->usage & 2)
 127                         continue;
 128 
 129                 while (nr--)
 130                         mem_map[pfn++] = 0;
 131         }
 132 
 133         /* unmap the console stuff: we don't need it, and we don't want it */
 134         /* Also set up the real kernel PCB while we're at it.. */
 135         memset((void *) ZERO_PGE, 0, PAGE_SIZE);
 136         memset(swapper_pg_dir, 0, PAGE_SIZE);
 137         newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
 138         pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
 139         init_task.tss.ptbr = newptbr;
 140         load_PCB(&init_task.tss);
 141 
 142         invalidate_all();
 143         return start_mem;
 144 }
 145 
 146 void mem_init(unsigned long start_mem, unsigned long end_mem)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148         unsigned long tmp;
 149 
 150         end_mem &= PAGE_MASK;
 151         high_memory = end_mem;
 152         start_mem = PAGE_ALIGN(start_mem);
 153 
 154         /*
 155          * Mark the pages used by the kernel as reserved..
 156          */
 157         tmp = KERNEL_START;
 158         while (tmp < start_mem) {
 159                 mem_map[MAP_NR(tmp)] = MAP_PAGE_RESERVED;
 160                 tmp += PAGE_SIZE;
 161         }
 162 
 163 
 164 #ifdef CONFIG_SCSI
 165         scsi_mem_init(high_memory);
 166 #endif
 167 #ifdef CONFIG_SOUND
 168         sound_mem_init();
 169 #endif
 170 
 171         for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
 172                 if (mem_map[MAP_NR(tmp)])
 173                         continue;
 174                 mem_map[MAP_NR(tmp)] = 1;
 175                 free_page(tmp);
 176         }
 177         tmp = nr_free_pages << PAGE_SHIFT;
 178         printk("Memory: %luk available\n", tmp >> 10);
 179         return;
 180 }
 181 
 182 void si_meminfo(struct sysinfo *val)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184         int i;
 185 
 186         i = high_memory >> PAGE_SHIFT;
 187         val->totalram = 0;
 188         val->sharedram = 0;
 189         val->freeram = nr_free_pages << PAGE_SHIFT;
 190         val->bufferram = buffermem;
 191         while (i-- > 0)  {
 192                 if (mem_map[i] & MAP_PAGE_RESERVED)
 193                         continue;
 194                 val->totalram++;
 195                 if (!mem_map[i])
 196                         continue;
 197                 val->sharedram += mem_map[i]-1;
 198         }
 199         val->totalram <<= PAGE_SHIFT;
 200         val->sharedram <<= PAGE_SHIFT;
 201         return;
 202 }

/* [previous][next][first][last][top][bottom][index][help] */