User Tools

Site Tools


mywiki:hw:mips:tlb

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
mywiki:hw:mips:tlb [2014/07/25 16:29] – created shaoguohmywiki:hw:mips:tlb [2022/04/02 17:29] (current) – external edit 127.0.0.1
Line 1: Line 1:
-TLB Assemble Example 1+====== TLB Assemble Example 1 ====== 
 +Reference: {{:mywiki:hw:mips:mips_tlb.pdf|{{:mywiki:hw:mips:mips_tlb.pdf|}}}}
  
 <file assemble tlb1.asm> <file assemble tlb1.asm>
Line 513: Line 514:
 </file> </file>
  
 +====== TLB example 2 ======
  
 +<file assembly tlb2.asm>
 +/*
 + * 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
 +</file>
 +
 +====== Shao Guohua TLB ASM test ======
 +<file asm tlb.asm>
 +##probe failure
 +#define TLB_INDEX_P_OFFSET 31
 +#define TLB_INDEX_P_MAKS 0x80000000
 +
 +#define TLB_INDEX_INDEX_OFFSET 0
 +#define TLB_INDEX_INDEX_MASK 0x3F
 +
 +
 +#define TLB_ENTRYLO_R_OFFSET 30
 +#define TLB_ENTRYLO_R_MASK   0xC0000000
 +
 +#define TLB_ENTRYLO_PFN_OFFSET 6
 +#define TLB_ENTRYLO_PFN_MASK   0x3FFFFC0
 +
 +##cache coherency
 +##3 WB Cacheable, noncoherent, write-back, write allocate
 +##4 CWBE Cacheable, write-back, write-allocate, coherent, read misses request Exclusive
 +##5 CWB Cacheable, write-back, write-allocate, coherent, read misses request Shared 
 +##6 - Reserved
 +##7 UCA Uncached Accelerated
 +##
 +#define TLB_ENTRYLO_C_OFFSET 3
 +#define TLB_ENTRYLO_C_MASK   0x38
 +
 +##dirt or writable
 +#define TLB_ENTRYLO_D_OFFSET 2
 +#define TLB_ENTRYLO_D_MASK   0x4
 +##valid bit
 +#define TLB_ENTRYLO_V_OFFSET 1
 +#define TLB_ENTRYLO_V_MASK   0x2
 +
 +##global
 +#define TLB_ENTRYLO_G_OFFSET 0
 +#define TLB_ENTRYLO_G_MASK   0x1
 +
 +#define TLB_ENTRYHI_VPN2_OFFSET  13
 +#define TLB_ENTRYHI_VPN2_MASK    0xFFFFE000
 +#define TLB_ENTRYHI_EHINV_OFFSET 10
 +#define TLB_ENTRYHI_EHINV_MASK   0x400
 +#define TLB_ENTRYHI_ASID_OFFSET  0
 +#define TLB_ENTRYHI_ASI_MASK     0xFF
 +
 +
 +##entry_lo0.reg.field.d = 1;
 +##entry_lo0.reg.field.v = 1;
 +##entry_lo0.reg.field.g = 1;
 +##entry_lo0.reg.field.c = 5;
 +##entry_lo1.reg.field.d = 1;
 +##entry_lo1.reg.field.v = 1;
 +##entry_lo1.reg.field.g = 1;
 +##entry_lo1.reg.field.c = 5;
 +##entry_hi.reg.field.asid = 0x1f;
 +##pagemask = 0x0;
 +##
 +##entry_hi.reg.field.vpn2 = (v_addr + (0x2000 * i)) >> 13;        
 +##entry_lo0.reg.field.pfn = (phy_addr +(0x2000 * i)) >> 12;
 +##entry_lo1.reg.field.pfn = (phy_addr +(0x2000 * i)+0x1000) >> 12;
 +
 +##tlb->tlb[i].pagemask = pagemask;
 +##tlb->tlb[i].entryhi = entry_hi.reg.all;
 +##tlb->tlb[i].entrylo0 = entry_lo0.reg.all;
 +##if ((i == (pages -1)) && !last_odd_page_vld ) ##last odd page not valid
 +##{
 +##   tlb->tlb[i].entrylo1 = 0;
 +##   entry_lo1.reg.field.v = 0;
 +##}    
 +##else
 +##   tlb->tlb[i].entrylo1 = entry_lo1.reg.all;  
 +
 +.data  
 +    str_index: .asciiz "index: "
 + str_entryhi: .asciiz "enryhi: "
 + str_entrylo0: .asciiz "enrylo0: "
 + str_entrylo1: .asciiz "enrylo1: "
 + str_pagemask: .asciiz "pagemask: "
 + str_newline:  .asciiz "\n"
 + str_size:  .asciiz "size:"
 +
 +
 +#define MAP_TLB_BASE    0xC0000000
 +#define TLB_4K_PAGE_OFFSET 12 
 +#define ENTRYHI_DEFAULT 0x0
 +#define TLB_ENTRYLO_DEFAULT_G ( (5<< TLB_ENTRYLO_C_OFFSET) | (1<< TLB_ENTRYLO_D_OFFSET) | (1<< TLB_ENTRYLO_V_OFFSET) | (1<< TLB_ENTRYLO_G_OFFSET))
 +#define TLB_ENTRYLO_DEFAULT_P ( (5<< TLB_ENTRYLO_C_OFFSET) | (1<< TLB_ENTRYLO_D_OFFSET) | (1<< TLB_ENTRYLO_V_OFFSET) )
 +
 +
 +.text
 + .globl __start    # declaration of main as a global variable
 +
 +__start:
 + li $t6, 0x20060000
 + li $t0, 154333
 +
 +_set_tlb_global:
 +    #EntryHi:
 + #---------------------------------
 + #| 31        13| 12   8 | 7    0 |
 + #|    VPN2      0   0 |  ASID  |
 + #---------------------------------
 + #Entrylo0/1
 + #---------------------------------
 + #| 31        6| 5  3 | 2 | 1 | 0 |
 + #| PFN        |  C   | D | V | G |
 + #---------------------------------
 + #Mask
 + #---------------------------------
 + #| 31  29| 28      13| 12     0 |
 + #| 0    0|    Mask   | 0      0 |
 + #---------------------------------
 + #t0 -- MPE shared code/data size need to map 
 + #t1 -- Index
 + #t2-- entryhi
 + #t3 -- entrylo
 + #t4 -- asid
 + #t5 -- pagemask
 + #t6 -- physical address, virtual address is harded coded here, ie, 0xc000 0000
 + #V0 -- tmp register
 +
 + #prepare $t1 for Index
 + li $t1, 0
 +
 + #prepare $t2 for entryhi
 + li $t2, 0xC0000000    
 +
 + #prepare $t3 for entrylo
 + add $t3, $t6, 0     #PHYsical base
 + srl $t3, $t3, 12    #TLB_4K_PAGE_OFFSET
 + sll $t3, $t3, 6     #TLB_ENTRYLO_PFN_OFFSET
 + addi $t3, $t3, 0x2f #TLB_ENTRYLO_DEFAULT_G
 +
 + #$t4 for asid
 + li $t4, 0
 +
 + #$t5 for pagemask
 + li $t5, 0
 +
 +tlb_g_loop:
 + ble $t0, 0, _set_tlb_global_done
 + nop
 +
 + #print size
 + li $v0, 4
 + la $a0, str_size
 + syscall
 + li $v0, 1
 + addi $a0, $t0, 0
 + syscall
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 +
 + #write even index
 + li $v0, 4
 + la $a0, str_index
 + syscall
 + li $v0, 1
 + addi $a0, $t1, 0
 + syscall
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 +
 + #write even entryhi
 + li $v0, 4
 + la $a0, str_entryhi
 + syscall
 + li $v0, 1
 + addi $a0, $t2, 0
 + syscall
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 +
 + #write even entrylo0
 + li $v0, 4
 + la $a0, str_entrylo0
 + syscall
 + li $v0, 1
 + addi $a0, $t3, 0
 + syscall
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 + #write even pagemask
 + li $v0, 4
 + la $a0, str_pagemask
 + syscall
 + li $v0, 1
 + addi $a0, $t5, 0
 + syscall
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 + #wlbwt
 +
 + #update odd page
 + addi $t3, $t3, 0x40
 + #write entrylo1
 + li $v0, 4
 + la $a0, str_entrylo1
 + syscall
 + li $v0, 1
 + addi $a0, $t3, 0
 + syscall
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 + #wlbwt
 +
 + #prepare next tlb index--
 + #update size $t0 reduce 2 * 4K since one tlb support 2 pages
 + li $v0, 0x2000
 + sub $t0, $t0, $v0
 +
 + #update index $t1
 + li $v0, 1
 + add $t1, $t1, $v0
 +
 + #update entryhi $t2
 + addi $t2, $t2, 0x2000 #(2<<TLB_ENTRYHI_VPN2_OFFSET)
 +
 + #update entrylo $t3
 + addi $t3, $t3, 0x40
 +
 + li $v0, 4
 + la $a0, str_newline
 + syscall
 +
 + j tlb_g_loop
 + nop
 +
 +
 +_set_tlb_global_done:
 + li $v0, 10
 + syscall
 +</file>
mywiki/hw/mips/tlb.1406276941.txt.gz · Last modified: (external edit)