root/kern/arch/mips/vm/tlb-mips1.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 #include <kern/mips/regdefs.h>
  31 #include <mips/specialreg.h>
  32 
  33 /*
  34  * TLB handling for mips-1 (r2000/r3000)
  35  */
  36 
  37    .text
  38    .set noreorder
  39 
  40    /*
  41     * tlb_random: use the "tlbwr" instruction to write a TLB entry
  42     * into a (very pseudo-) random slot in the TLB.
  43     *
  44     * Pipeline hazard: must wait between setting entryhi/lo and
  45     * doing the tlbwr. Use two cycles; some processors may vary.
  46     */
  47    .globl tlb_random
  48    .type tlb_random,@function
  49    .ent tlb_random
  50 tlb_random:
  51    mtc0 a0, c0_entryhi  /* store the passed entry into the */
  52    mtc0 a1, c0_entrylo  /*   tlb entry registers */
  53    nop                  /* wait for pipeline hazard */
  54    nop
  55    tlbwr                /* do it */
  56    j ra
  57    nop
  58    .end tlb_random
  59 
  60    /*
  61     * tlb_write: use the "tlbwi" instruction to write a TLB entry
  62     * into a selected slot in the TLB.
  63     *
  64     * Pipeline hazard: must wait between setting entryhi/lo and
  65     * doing the tlbwi. Use two cycles; some processors may vary.
  66     */
  67    .text   
  68    .globl tlb_write
  69    .type tlb_write,@function
  70    .ent tlb_write
  71 tlb_write:
  72    mtc0 a0, c0_entryhi  /* store the passed entry into the */
  73    mtc0 a1, c0_entrylo  /*   tlb entry registers */
  74    sll  t0, a2, CIN_INDEXSHIFT  /* shift the passed index into place */
  75    mtc0 t0, c0_index    /* store the shifted index into the index register */
  76    nop                  /* wait for pipeline hazard */
  77    nop
  78    tlbwi                /* do it */
  79    j ra
  80    nop
  81    .end tlb_write
  82 
  83    /*
  84     * tlb_read: use the "tlbr" instruction to read a TLB entry
  85     * from a selected slot in the TLB.
  86     *
  87     * Pipeline hazard: must wait between setting c0_index and
  88     * doing the tlbr. Use two cycles; some processors may vary.
  89     * Similarly, three more cycles before reading c0_entryhi/lo.
  90     */
  91    .text
  92    .globl tlb_read
  93    .type tlb_read,@function
  94    .ent tlb_read
  95 tlb_read:
  96    sll  t0, a2, CIN_INDEXSHIFT  /* shift the passed index into place */
  97    mtc0 t0, c0_index    /* store the shifted index into the index register */
  98    nop                  /* wait for pipeline hazard */
  99    nop
 100    tlbr                 /* do it */
 101    nop                  /* wait for pipeline hazard */
 102    nop
 103    nop
 104    mfc0 t0, c0_entryhi  /* get the tlb entry out of the */
 105    mfc0 t1, c0_entrylo  /*   tlb entry registers */
 106    sw t0, 0(a0)         /* store through the passed pointer */
 107    j ra
 108    sw t1, 0(a1)         /* store (in delay slot) */
 109    .end tlb_read
 110 
 111    /*
 112     * tlb_probe: use the "tlbp" instruction to find the index in the
 113     * TLB of a TLB entry matching the relevant parts of the one supplied.
 114     *
 115     * Pipeline hazard: must wait between setting c0_entryhi/lo and
 116     * doing the tlbp. Use two cycles; some processors may vary.
 117     * Similarly, two more cycles before reading c0_index.
 118     */
 119    .text
 120    .globl tlb_probe
 121    .type tlb_probe,@function
 122    .ent tlb_probe
 123 tlb_probe:
 124    mtc0 a0, c0_entryhi  /* store the passed entry into the */
 125    mtc0 a1, c0_entrylo  /*   tlb entry registers */
 126    nop                  /* wait for pipeline hazard */
 127    nop
 128    tlbp                 /* do it */
 129    nop                  /* wait for pipeline hazard */
 130    nop
 131    mfc0 t0, c0_index    /* fetch the index back in t0 */
 132 
 133    /*
 134     * If the high bit (CIN_P) of c0_index is set, the probe failed.
 135     * The high bit is not set <--> c0_index (now in t0) >= 0.
 136     */
 137 
 138    bgez t0, 1f          /* did probe succeed? if so, skip forward */
 139    nop                  /* delay slot */
 140    addi v0, z0, -1      /* set return value to -1 to indicate failure */
 141    j ra                 /* done */
 142    nop                  /* delay slot */
 143 
 144 1:
 145    /* succeeded - get the index field from the index register value */
 146    andi t1, t0, CIN_INDEX       /* mask off the field */
 147    j ra                         /* done */
 148    sra  v0, t1, CIN_INDEXSHIFT  /* shift it (in delay slot) */
 149    .end tlb_probe
 150 
 151 
 152    /*
 153     * tlb_reset
 154     *
 155     * Initialize the TLB. At processor startup, the TLB state is completely
 156     * undefined. So be sure to avoid creating any duplicates. Also make sure
 157     * that the initialization entries don't duplicate the INVALID entries
 158     * defined in tlb.h. (This way you can write the invalid entries in
 159     * without having to use tlbp to find out if they're going to cause dups.)
 160     *
 161     * This function is not defined in tlb.h because it's only called from
 162     * start.S.
 163     *
 164     * Pipeline hazards are as above.
 165     */
 166    .text
 167    .globl tlb_reset
 168    .type tlb_reset,@function
 169    .ent tlb_reset
 170 tlb_reset:
 171    li t0, 0                     /* t0 <- tlb index number (shifted) */
 172    li t1, 0x81000000            /* t1 <- tlb reset vaddr */
 173 1:
 174    mtc0 $0, c0_entrylo          /* set up proposed tlb entry for reset */
 175    mtc0 t1, c0_entryhi
 176    nop                          /* wait for pipeline hazard */
 177    nop
 178    tlbp                         /* check if it already exists */
 179    nop                          /* wait for pipeline hazard */
 180    nop
 181    mfc0 t2, c0_index
 182    bgez t2, 1b                  /* if it does, loop back */
 183    addiu t1, t1, 0x1000         /* next vaddr (in delay slot) */
 184    mtc0 t0, c0_index            /* doesn't exist, set index to write to */
 185    /* nop */                    /* don't wait for pipeline hazard */
 186    /* nop */                    /*   (have enough other instructions) */
 187    addiu t0, t0, 0x100          /* next tlb index (shifted) */
 188    bne t0, 0x4000, 1b           /* if it's not the last tlb index, loop */
 189    tlbwi                        /* write tlb entry (in delay slot) */
 190    j ra                         /* done */
 191    nop                          /* delay slot */        
 192    .end tlb_reset

/* [<][>][^][v][top][bottom][index][help] */