root/arch/sparc/mm/s4ckflt.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /* s4ckflt.S:  Quick in window kernel faults on the sun4c.
   2  *
   3  * Copyright (C) 1995 David S. Miller (davem@caipfs.rutgers.edu)
   4  */
   5 
   6 #include "s4clow.h"
   7 
   8         .text
   9         .align 8
  10         .globl  sun4c_quick_kernel_fault
  11 sun4c_quick_kernel_fault:
  12         sethi   %hi(REAL_PGDIR_MASK), %l5
  13         and     %l7, %l5, %l7
  14         sethi   %hi(C_LABEL(invalid_segment)), %l5
  15         lduba   [%l7] 0x3, %l4
  16         ld      [%l5 + %lo(C_LABEL(invalid_segment))], %l5
  17         cmp     %l4, %l5
  18         bne     segment_loaded
  19          nop
  20 
  21         /* We need some breathing room to pull this off, save
  22          * away some globals.
  23          */
  24         std     %g0, [REGSAVE_BASE + KFLTREGS + 0x00]
  25         std     %g2, [REGSAVE_BASE + KFLTREGS + 0x08]
  26         std     %g4, [REGSAVE_BASE + KFLTREGS + 0x10]
  27         std     %g6, [REGSAVE_BASE + KFLTREGS + 0x18]
  28         std     %l0, [REGSAVE_BASE + KFLTREGS + 0x20]
  29         std     %l2, [REGSAVE_BASE + KFLTREGS + 0x28]
  30 
  31         set     C_LABEL(sun4c_kfree_ring), %g1
  32         ld      [%g1 + RING_NENTRIES], %g2
  33         cmp     %g2, 0x0
  34         be,a    pseg_steal
  35          nop
  36 
  37         b       distribute_segmap
  38          ld     [%g1 + RING_RINGHD + MMU_ENTRY_NEXT], %g2
  39 
  40 pseg_steal:
  41         /* This is the hard case. */    
  42         set     C_LABEL(sun4c_kernel_ring), %g1
  43         ld      [%g1 + RING_RINGHD + MMU_ENTRY_PREV], %g2
  44         b       kernel_segment_cache_flush
  45          ld     [%g2 + MMU_ENTRY_VADDR], %l0
  46 
  47 pseg_steal_after_flush:
  48         ld      [%g2 + MMU_ENTRY_VADDR], %l0
  49         sethi   %hi(0x30000000), %l1
  50         lduba   [%l1] 0x02, %g7
  51         sethi   %hi(C_LABEL(num_contexts)), %g6
  52         mov     0, %g5
  53         ld      [%g6 + %lo(C_LABEL(num_contexts))], %g6
  54 1:
  55         stba    %g5, [%l1] 0x02
  56         add     %g5, 1, %g5
  57         cmp     %g5, %g6
  58         bl      1b
  59          stba   %l5, [%l0] 0x03
  60 
  61         stba    %g7, [%l1] 0x02
  62 
  63         
  64 
  65 distribute_segmap:
  66         st      %l7, [%g2 + MMU_ENTRY_VADDR]
  67         ldub    [%g2 + MMU_ENTRY_PSEG], %g3
  68         sethi   %hi(0x30000000), %l0
  69         lduba   [%l0] 0x02, %g7
  70         sethi   %hi(C_LABEL(num_contexts)), %g6
  71         mov     0, %g5
  72         ld      [%g6 + %lo(C_LABEL(num_contexts))], %g6
  73 1:
  74         stba    %g5, [%l0] 0x02
  75         add     %g5, 1, %g5
  76         cmp     %g5, %g6
  77         bl      1b
  78          stba   %g3, [%l7] 0x03
  79 
  80         stba    %g7, [%l0] 0x02
  81 
  82 segment_loaded:
  83         sethi   %hi(VMALLOC_START), %l4
  84         cmp     %l7, %l4
  85         bge     vmalloc_kernel_fault
  86          nop
  87 
  88 
  89 
  90 
  91 
  92 vmalloc_kernel_fault:
  93 
  94 
  95 qkf_exit:
  96         /* Fault serviced, return from trap, but reload
  97          * registers first.
  98          */
  99         ldd     [REGSAVE_BASE + KFLTREGS + 0x00], %g0
 100         ldd     [REGSAVE_BASE + KFLTREGS + 0x08], %g2
 101         ldd     [REGSAVE_BASE + KFLTREGS + 0x10], %g4
 102         ldd     [REGSAVE_BASE + KFLTREGS + 0x18], %g6
 103         ldd     [REGSAVE_BASE + KFLTREGS + 0x20], %l0
 104         ldd     [REGSAVE_BASE + KFLTREGS + 0x28], %l2
 105 

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