Subversion Repositories HelenOS

Rev

Rev 819 | Rev 900 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2006 Jakub Jermar
  3.  * All rights reserved.
  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.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /*
  30.  * TLB management.
  31.  */
  32.  
  33. #include <mm/tlb.h>
  34. #include <arch/mm/tlb.h>
  35. #include <arch/barrier.h>
  36. #include <typedefs.h>
  37.  
  38. /** Invalidate all TLB entries. */
  39. void tlb_invalidate_all(void)
  40. {
  41.     /* TODO */
  42. }
  43.  
  44. /** Invalidate entries belonging to an address space.
  45.  *
  46.  * @param asid Address space identifier.
  47.  */
  48. void tlb_invalidate_asid(asid_t asid)
  49. {
  50.     /* TODO */
  51. }
  52.  
  53. /** Insert data into data translation cache.
  54.  *
  55.  * @param va Virtual page address.
  56.  * @param asid Address space identifier.
  57.  * @param entry The rest of TLB entry as required by TLB insertion format.
  58.  */
  59. void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
  60.     tc_mapping_insert(va, asid, entry, true);
  61. }
  62.  
  63. /** Insert data into instruction translation cache.
  64.  *
  65.  * @param va Virtual page address.
  66.  * @param asid Address space identifier.
  67.  * @param entry The rest of TLB entry as required by TLB insertion format.
  68.  */
  69. void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
  70.     tc_mapping_insert(va, asid, entry, false);
  71. }
  72.  
  73. /** Insert data into instruction or data translation cache.
  74.  *
  75.  * @param va Virtual page address.
  76.  * @param asid Address space identifier.
  77.  * @param entry The rest of TLB entry as required by TLB insertion format.
  78.  * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
  79.  */
  80. void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc)
  81. {
  82.     region_register rr;
  83.     bool restore_rr = false;
  84.  
  85.     if (!(entry.not_present.p))
  86.         return;
  87.  
  88.     rr.word = rr_read(VA_REGION(va));
  89.     if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
  90.         /*
  91.          * The selected region register does not contain required RID.
  92.          * Save the old content of the register and replace the RID.
  93.          */
  94.         region_register rr0;
  95.  
  96.         rr0 = rr;
  97.         rr0.map.rid = ASID2RID(asid, VA_REGION(va));
  98.         rr_write(VA_REGION(va), rr0.word);
  99.         srlz_d();
  100.         srlz_i();
  101.     }
  102.    
  103.     __asm__ volatile (
  104.         "mov r8=psr;;\n"
  105.         "and r9=r8,%0;;\n"          /* (~PSR_IC_MASK) */
  106.         "mov psr.l=r9;;\n"
  107.         "srlz.d;;\n"
  108.         "srlz.i;;\n"
  109.         "mov cr.ifa=%1\n"       /* va */
  110.         "mov cr.itir=%2;;\n"        /* entry.word[1] */
  111.         "cmp.eq p6,p7 = %4,r0;;\n"  /* decide between itc and dtc */
  112.         "(p6) itc.i %3;;\n"
  113.         "(p7) itc.d %3;;\n"
  114.         "mov psr.l=r8;;\n"
  115.         "srlz.d;;\n"
  116.         :
  117.         : "r" (~PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
  118.         : "p6", "p7", "r8", "r9"
  119.     );
  120.    
  121.     if (restore_rr) {
  122.         rr_write(VA_REGION(va),rr.word);
  123.         srlz_d();
  124.         srlz_i();
  125.     }
  126. }
  127.  
  128. /** Insert data into instruction translation register.
  129.  *
  130.  * @param va Virtual page address.
  131.  * @param asid Address space identifier.
  132.  * @param entry The rest of TLB entry as required by TLB insertion format.
  133.  * @param tr Translation register.
  134.  */
  135. void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
  136. {
  137.     tr_mapping_insert(va, asid, entry, false, tr);
  138. }
  139.  
  140. /** Insert data into data translation register.
  141.  *
  142.  * @param va Virtual page address.
  143.  * @param asid Address space identifier.
  144.  * @param entry The rest of TLB entry as required by TLB insertion format.
  145.  * @param tr Translation register.
  146.  */
  147. void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
  148. {
  149.     tr_mapping_insert(va, asid, entry, true, tr);
  150. }
  151.  
  152. /** Insert data into instruction or data translation register.
  153.  *
  154.  * @param va Virtual page address.
  155.  * @param asid Address space identifier.
  156.  * @param entry The rest of TLB entry as required by TLB insertion format.
  157.  * @param dtc If true, insert into data translation register, use instruction translation register otherwise.
  158.  * @param tr Translation register.
  159.  */
  160. void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
  161. {
  162.     region_register rr;
  163.     bool restore_rr = false;
  164.  
  165.     if (!(entry.not_present.p))
  166.         return;
  167.  
  168.     rr.word = rr_read(VA_REGION(va));
  169.     if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
  170.         /*
  171.          * The selected region register does not contain required RID.
  172.          * Save the old content of the register and replace the RID.
  173.          */
  174.         region_register rr0;
  175.  
  176.         rr0 = rr;
  177.         rr0.map.rid = ASID2RID(asid, VA_REGION(va));
  178.         rr_write(VA_REGION(va), rr0.word);
  179.         srlz_d();
  180.         srlz_i();
  181.     }
  182.  
  183.     __asm__ volatile (
  184.         "mov r8=psr;;\n"
  185.         "and r9=r8,%0;;\n"      /* (~PSR_IC_MASK) */
  186.         "mov psr.l=r9;;\n"
  187.         "srlz.d;;\n"
  188.         "srlz.i;;\n"
  189.         "mov cr.ifa=%1\n"           /* va */         
  190.         "mov cr.itir=%2;;\n"        /* entry.word[1] */
  191.         "cmp.eq p6,p7=%5,r0;;\n"    /* decide between itr and dtr */
  192.         "(p6) itr.i itr[%4]=%3;;\n"
  193.         "(p7) itr.d dtr[%4]=%3;;\n"
  194.         "mov psr.l=r8;;\n"
  195.         "srlz.d;;\n"
  196.         :
  197.         :"r" (~PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
  198.         : "p6", "p7", "r8", "r9"
  199.     );
  200.    
  201.     if (restore_rr) {
  202.         rr_write(VA_REGION(va),rr.word);
  203.         srlz_d();
  204.         srlz_i();
  205.     }
  206. }
  207.  
  208. void alternate_instruction_tlb_fault(void)
  209. {
  210.     panic("%s\n", __FUNCTION__);
  211. }
  212.  
  213. void alternate_data_tlb_fault(void)
  214. {
  215.     panic("%s\n", __FUNCTION__);
  216. }
  217.  
  218. void data_nested_tlb_fault(void)
  219. {
  220.     panic("%s\n", __FUNCTION__);
  221. }
  222.  
  223. void data_dirty_bit_fault(void)
  224. {
  225.     panic("%s\n", __FUNCTION__);
  226. }
  227.  
  228. void instruction_access_bit_fault(void)
  229. {
  230.     panic("%s\n", __FUNCTION__);
  231. }
  232.  
  233. void data_access_bit_fault(void)
  234. {
  235.     panic("%s\n", __FUNCTION__);
  236. }
  237.  
  238. void page_not_present(void)
  239. {
  240.     panic("%s\n", __FUNCTION__);
  241. }
  242.