root/arch/sparc/mm/fault.c

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

DEFINITIONS

This source file includes following definitions.
  1. probe_memory
  2. map_the_prom
  3. do_page_fault

   1 #include <linux/string.h>
   2 #include <linux/types.h>
   3 #include <linux/ptrace.h>
   4 #include <linux/mman.h>
   5 #include <linux/signal.h>
   6 #include <linux/mm.h>
   7 
   8 #include <asm/system.h>
   9 #include <asm/segment.h>
  10 #include <asm/openprom.h>
  11 #include <asm/page.h>
  12 #include <asm/pgtable.h>
  13 
  14 extern unsigned long pg0[1024];         /* page table for 0-4MB for everybody */
  15 extern void die_if_kernel(char *,struct pt_regs *,long);
  16 
  17 /* Sparc stuff... I know this is a ugly place to put the PROM vector, don't
  18  * remind me.
  19  */
  20 extern unsigned int trapbase[];
  21 extern unsigned int end[], etext[], msgbuf[];
  22 struct linux_romvec *romvec;
  23 
  24 /* foo */
  25 
  26 int tbase_needs_unmapping;
  27 
  28 /* At boot time we determine these two values necessary for setting
  29  * up the segment maps and page table entries (pte's).
  30  */
  31 
  32 int num_segmaps, num_contexts;
  33 int invalid_segment;
  34 
  35 /* various Virtual Address Cache parameters we find at boot time... */
  36 
  37 int vac_size, vac_linesize, vac_do_hw_vac_flushes;
  38 int vac_entries_per_context, vac_entries_per_segment;
  39 int vac_entries_per_page;
  40 
  41 /*
  42  * Define this if things work differently on a i386 and a i486:
  43  * it will (on a i486) warn about kernel memory accesses that are
  44  * done without a 'verify_area(VERIFY_WRITE,..)'
  45  */
  46 #undef CONFIG_TEST_VERIFY_AREA
  47 
  48 /* Traverse the memory lists in the prom to see how much physical we
  49  * have.
  50  */
  51 
  52 unsigned long
  53 probe_memory(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55   register struct linux_romvec *lprom;
  56   register struct linux_mlist_v0 *mlist;
  57   register unsigned long bytes, base_paddr;
  58   register int i;
  59 
  60   bytes = 0;
  61   base_paddr = 0;
  62   lprom = romvec;
  63   switch(lprom->pv_romvers)
  64     {
  65     case 0:
  66       mlist=(*(lprom->pv_v0mem.v0_totphys));
  67       bytes=mlist->num_bytes;
  68       base_paddr = (unsigned long) mlist->start_adr;
  69       printk("Bank 1: starting at 0x%x holding %d bytes\n", 
  70              (unsigned int) base_paddr, (int) bytes);
  71       i=1;
  72       if(mlist->theres_more != (void *)0)
  73         {
  74           i++;
  75           mlist=mlist->theres_more;
  76           bytes+=mlist->num_bytes;
  77           printk("Bank %d: starting at 0x%x holding %d bytes\n", i,
  78                  (unsigned int) mlist->start_adr, (int) mlist->num_bytes);
  79         }
  80       break;
  81     case 2:
  82       printk("no v2 memory probe support yet.\n");
  83       (*(lprom->pv_halt))();
  84       break;
  85     }
  86   printk("Physical memory: %d bytes  starting at va 0x%x\n",
  87          (unsigned int) bytes, (int) base_paddr);
  88 
  89   return bytes;
  90 }
  91 
  92 /* Sparc routine to reserve the mapping of the open boot prom */
  93 
  94 /* uncomment this for FAME and FORTUNE! */
  95 /* #define DEBUG_MAP_PROM */
  96 
  97 int
  98 map_the_prom(int curr_num_segs)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100   register unsigned long prom_va_begin;
 101   register unsigned long prom_va_end;
 102   register int segmap_entry, i;
 103 
 104   prom_va_begin = LINUX_OPPROM_BEGVM;
 105   prom_va_end   = LINUX_OPPROM_ENDVM;
 106 
 107 #ifdef DEBUG_MAP_PROM
 108   printk("\ncurr_num_segs = 0x%x\n", curr_num_segs);
 109 #endif
 110 
 111   while( prom_va_begin < prom_va_end)
 112     {
 113       segmap_entry=get_segmap(prom_va_begin);
 114 
 115       curr_num_segs = ((segmap_entry<curr_num_segs) 
 116                        ? segmap_entry : curr_num_segs);
 117 
 118       for(i = num_contexts; --i > 0;)
 119           (*romvec->pv_setctxt)(i, (char *) prom_va_begin,
 120                                 segmap_entry);
 121 
 122       if(segmap_entry == invalid_segment)
 123         {
 124 
 125 #ifdef DEBUG_MAP_PROM
 126           printk("invalid_segments, virt_addr 0x%x\n", prom_va_begin);
 127 #endif
 128 
 129           prom_va_begin += 0x40000;  /* num bytes per segment entry */
 130           continue;
 131         }
 132 
 133       /* DUH, prom maps itself so that users can access it. This is
 134        * broken.
 135        */
 136 
 137 #ifdef DEBUG_MAP_PROM
 138       printk("making segmap for prom privileged, va = 0x%x\n",
 139              prom_va_begin);
 140 #endif
 141 
 142       for(i = 0x40; --i >= 0; prom_va_begin+=4096)
 143         {
 144           put_pte(prom_va_begin, get_pte(prom_va_begin) | 0x20000000);
 145         }
 146 
 147     }
 148 
 149   printk("Mapped the PROM in all contexts...\n");
 150 
 151 #ifdef DEBUG_MAP_PROM
 152   printk("curr_num_segs = 0x%x\n", curr_num_segs);
 153 #endif
 154 
 155   return curr_num_segs;
 156 
 157 }
 158 
 159 /*
 160  * This routine handles page faults.  It determines the address,
 161  * and the problem, and then passes it off to one of the appropriate
 162  * routines.
 163  */
 164 asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166         die_if_kernel("Oops", regs, error_code);
 167         do_exit(SIGKILL);
 168 }
 169 
 170 
 171 
 172 

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