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

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