Subversion Repositories HelenOS-historic

Rev

Rev 899 | Rev 901 | 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 <arch/interrupt.h>
  37. #include <typedefs.h>
  38. #include <panic.h>
  39.  
  40. /** Invalidate all TLB entries. */
  41. void tlb_invalidate_all(void)
  42. {
  43.     /* TODO */
  44. }
  45.  
  46. /** Invalidate entries belonging to an address space.
  47.  *
  48.  * @param asid Address space identifier.
  49.  */
  50. void tlb_invalidate_asid(asid_t asid)
  51. {
  52.     /* TODO */
  53. }
  54.  
  55. /** Insert data into data translation cache.
  56.  *
  57.  * @param va Virtual page address.
  58.  * @param asid Address space identifier.
  59.  * @param entry The rest of TLB entry as required by TLB insertion format.
  60.  */
  61. void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
  62.     tc_mapping_insert(va, asid, entry, true);
  63. }
  64.  
  65. /** Insert data into instruction translation cache.
  66.  *
  67.  * @param va Virtual page address.
  68.  * @param asid Address space identifier.
  69.  * @param entry The rest of TLB entry as required by TLB insertion format.
  70.  */
  71. void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
  72.     tc_mapping_insert(va, asid, entry, false);
  73. }
  74.  
  75. /** Insert data into instruction or data translation cache.
  76.  *
  77.  * @param va Virtual page address.
  78.  * @param asid Address space identifier.
  79.  * @param entry The rest of TLB entry as required by TLB insertion format.
  80.  * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
  81.  */
  82. void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc)
  83. {
  84.     region_register rr;
  85.     bool restore_rr = false;
  86.  
  87.     if (!(entry.not_present.p))
  88.         return;
  89.  
  90.     rr.word = rr_read(VA_REGION(va));
  91.     if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
  92.         /*
  93.          * The selected region register does not contain required RID.
  94.          * Save the old content of the register and replace the RID.
  95.          */
  96.         region_register rr0;
  97.  
  98.         rr0 = rr;
  99.         rr0.map.rid = ASID2RID(asid, VA_REGION(va));
  100.         rr_write(VA_REGION(va), rr0.word);
  101.         srlz_d();
  102.         srlz_i();
  103.     }
  104.    
  105.     __asm__ volatile (
  106.         "mov r8=psr;;\n"
  107.         "rsm %0;;\n"            /* PSR_IC_MASK */
  108.         "srlz.d;;\n"
  109.         "srlz.i;;\n"
  110.         "mov cr.ifa=%1\n"       /* va */
  111.         "mov cr.itir=%2;;\n"        /* entry.word[1] */
  112.         "cmp.eq p6,p7 = %4,r0;;\n"  /* decide between itc and dtc */
  113.         "(p6) itc.i %3;;\n"
  114.         "(p7) itc.d %3;;\n"
  115.         "mov psr.l=r8;;\n"
  116.         "srlz.d;;\n"
  117.         :
  118.         : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
  119.         : "p6", "p7", "r8"
  120.     );
  121.    
  122.     if (restore_rr) {
  123.         rr_write(VA_REGION(va),rr.word);
  124.         srlz_d();
  125.         srlz_i();
  126.     }
  127. }
  128.  
  129. /** Insert data into instruction translation register.
  130.  *
  131.  * @param va Virtual page address.
  132.  * @param asid Address space identifier.
  133.  * @param entry The rest of TLB entry as required by TLB insertion format.
  134.  * @param tr Translation register.
  135.  */
  136. void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
  137. {
  138.     tr_mapping_insert(va, asid, entry, false, tr);
  139. }
  140.  
  141. /** Insert data into data translation register.
  142.  *
  143.  * @param va Virtual page address.
  144.  * @param asid Address space identifier.
  145.  * @param entry The rest of TLB entry as required by TLB insertion format.
  146.  * @param tr Translation register.
  147.  */
  148. void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
  149. {
  150.     tr_mapping_insert(va, asid, entry, true, tr);
  151. }
  152.  
  153. /** Insert data into instruction or data translation register.
  154.  *
  155.  * @param va Virtual page address.
  156.  * @param asid Address space identifier.
  157.  * @param entry The rest of TLB entry as required by TLB insertion format.
  158.  * @param dtc If true, insert into data translation register, use instruction translation register otherwise.
  159.  * @param tr Translation register.
  160.  */
  161. void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
  162. {
  163.     region_register rr;
  164.     bool restore_rr = false;
  165.  
  166.     if (!(entry.not_present.p))
  167.         return;
  168.  
  169.     rr.word = rr_read(VA_REGION(va));
  170.     if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
  171.         /*
  172.          * The selected region register does not contain required RID.
  173.          * Save the old content of the register and replace the RID.
  174.          */
  175.         region_register rr0;
  176.  
  177.         rr0 = rr;
  178.         rr0.map.rid = ASID2RID(asid, VA_REGION(va));
  179.         rr_write(VA_REGION(va), rr0.word);
  180.         srlz_d();
  181.         srlz_i();
  182.     }
  183.  
  184.     __asm__ volatile (
  185.         "mov r8=psr;;\n"
  186.         "rsm %0;;\n"            /* PSR_IC_MASK */
  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.         : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
  198.         : "p6", "p7", "r8"
  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(__u64 vector, struct exception_regdump *pstate)
  209. {
  210.     panic("%s\n", __FUNCTION__);
  211. }
  212.  
  213. void alternate_data_tlb_fault(__u64 vector, struct exception_regdump *pstate)
  214. {
  215.     panic("%s: %P\n", __FUNCTION__, pstate->cr_ifa);
  216. }
  217.  
  218. void data_nested_tlb_fault(__u64 vector, struct exception_regdump *pstate)
  219. {
  220.     panic("%s\n", __FUNCTION__);
  221. }
  222.  
  223. void data_dirty_bit_fault(__u64 vector, struct exception_regdump *pstate)
  224. {
  225.     panic("%s\n", __FUNCTION__);
  226. }
  227.  
  228. void instruction_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
  229. {
  230.     panic("%s\n", __FUNCTION__);
  231. }
  232.  
  233. void data_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
  234. {
  235.     panic("%s\n", __FUNCTION__);
  236. }
  237.  
  238. void page_not_present(__u64 vector, struct exception_regdump *pstate)
  239. {
  240.     panic("%s\n", __FUNCTION__);
  241. }
  242.