123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
- * The President and Fellows of Harvard College.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #include <kern/mips/regdefs.h>
- #include <mips/specialreg.h>
- /*
- * TLB handling for mips-1 (r2000/r3000)
- */
- .text
- .set noreorder
- /*
- * tlb_random: use the "tlbwr" instruction to write a TLB entry
- * into a (very pseudo-) random slot in the TLB.
- *
- * Pipeline hazard: must wait between setting entryhi/lo and
- * doing the tlbwr. Use two cycles; some processors may vary.
- */
- .globl tlb_random
- .type tlb_random,@function
- .ent tlb_random
- tlb_random:
- mtc0 a0, c0_entryhi /* store the passed entry into the */
- mtc0 a1, c0_entrylo /* tlb entry registers */
- nop /* wait for pipeline hazard */
- nop
- tlbwr /* do it */
- j ra
- nop
- .end tlb_random
- /*
- * tlb_write: use the "tlbwi" instruction to write a TLB entry
- * into a selected slot in the TLB.
- *
- * Pipeline hazard: must wait between setting entryhi/lo and
- * doing the tlbwi. Use two cycles; some processors may vary.
- */
- .text
- .globl tlb_write
- .type tlb_write,@function
- .ent tlb_write
- tlb_write:
- mtc0 a0, c0_entryhi /* store the passed entry into the */
- mtc0 a1, c0_entrylo /* tlb entry registers */
- sll t0, a2, CIN_INDEXSHIFT /* shift the passed index into place */
- mtc0 t0, c0_index /* store the shifted index into the index register */
- nop /* wait for pipeline hazard */
- nop
- tlbwi /* do it */
- j ra
- nop
- .end tlb_write
- /*
- * tlb_read: use the "tlbr" instruction to read a TLB entry
- * from a selected slot in the TLB.
- *
- * Pipeline hazard: must wait between setting c0_index and
- * doing the tlbr. Use two cycles; some processors may vary.
- * Similarly, three more cycles before reading c0_entryhi/lo.
- */
- .text
- .globl tlb_read
- .type tlb_read,@function
- .ent tlb_read
- tlb_read:
- sll t0, a2, CIN_INDEXSHIFT /* shift the passed index into place */
- mtc0 t0, c0_index /* store the shifted index into the index register */
- nop /* wait for pipeline hazard */
- nop
- tlbr /* do it */
- nop /* wait for pipeline hazard */
- nop
- nop
- mfc0 t0, c0_entryhi /* get the tlb entry out of the */
- mfc0 t1, c0_entrylo /* tlb entry registers */
- sw t0, 0(a0) /* store through the passed pointer */
- j ra
- sw t1, 0(a1) /* store (in delay slot) */
- .end tlb_read
- /*
- * tlb_probe: use the "tlbp" instruction to find the index in the
- * TLB of a TLB entry matching the relevant parts of the one supplied.
- *
- * Pipeline hazard: must wait between setting c0_entryhi/lo and
- * doing the tlbp. Use two cycles; some processors may vary.
- * Similarly, two more cycles before reading c0_index.
- */
- .text
- .globl tlb_probe
- .type tlb_probe,@function
- .ent tlb_probe
- tlb_probe:
- mtc0 a0, c0_entryhi /* store the passed entry into the */
- mtc0 a1, c0_entrylo /* tlb entry registers */
- nop /* wait for pipeline hazard */
- nop
- tlbp /* do it */
- nop /* wait for pipeline hazard */
- nop
- mfc0 t0, c0_index /* fetch the index back in t0 */
- /*
- * If the high bit (CIN_P) of c0_index is set, the probe failed.
- * The high bit is not set <--> c0_index (now in t0) >= 0.
- */
- bgez t0, 1f /* did probe succeed? if so, skip forward */
- nop /* delay slot */
- addi v0, z0, -1 /* set return value to -1 to indicate failure */
- j ra /* done */
- nop /* delay slot */
- 1:
- /* succeeded - get the index field from the index register value */
- andi t1, t0, CIN_INDEX /* mask off the field */
- j ra /* done */
- sra v0, t1, CIN_INDEXSHIFT /* shift it (in delay slot) */
- .end tlb_probe
- /*
- * tlb_reset
- *
- * Initialize the TLB. At processor startup, the TLB state is completely
- * undefined. So be sure to avoid creating any duplicates. Also make sure
- * that the initialization entries don't duplicate the INVALID entries
- * defined in tlb.h. (This way you can write the invalid entries in
- * without having to use tlbp to find out if they're going to cause dups.)
- *
- * This function is not defined in tlb.h because it's only called from
- * start.S.
- *
- * Pipeline hazards are as above.
- */
- .text
- .globl tlb_reset
- .type tlb_reset,@function
- .ent tlb_reset
- tlb_reset:
- li t0, 0 /* t0 <- tlb index number (shifted) */
- li t1, 0x81000000 /* t1 <- tlb reset vaddr */
- 1:
- mtc0 $0, c0_entrylo /* set up proposed tlb entry for reset */
- mtc0 t1, c0_entryhi
- nop /* wait for pipeline hazard */
- nop
- tlbp /* check if it already exists */
- nop /* wait for pipeline hazard */
- nop
- mfc0 t2, c0_index
- bgez t2, 1b /* if it does, loop back */
- addiu t1, t1, 0x1000 /* next vaddr (in delay slot) */
- mtc0 t0, c0_index /* doesn't exist, set index to write to */
- /* nop */ /* don't wait for pipeline hazard */
- /* nop */ /* (have enough other instructions) */
- addiu t0, t0, 0x100 /* next tlb index (shifted) */
- bne t0, 0x4000, 1b /* if it's not the last tlb index, loop */
- tlbwi /* write tlb entry (in delay slot) */
- j ra /* done */
- nop /* delay slot */
- .end tlb_reset
|