Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2006 Jakub Jermar
  3.  * Copyright (c) 2009 Pavel Rimsky
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  * - Redistributions in binary form must reproduce the above copyright
  13.  *   notice, this list of conditions and the following disclaimer in the
  14.  *   documentation and/or other materials provided with the distribution.
  15.  * - The name of the author may not be used to endorse or promote products
  16.  *   derived from this software without specific prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28.  */
  29.  
  30. /** @addtogroup sparc64mm  
  31.  * @{
  32.  */
  33. /** @file
  34.  */
  35.  
  36. #include <arch/mm/tsb.h>
  37. #include <arch/mm/pagesize.h>
  38. #include <arch/mm/tlb.h>
  39. #include <arch/mm/page.h>
  40. #include <arch/barrier.h>
  41. #include <mm/as.h>
  42. #include <arch/types.h>
  43. #include <macros.h>
  44. #include <debug.h>
  45.  
  46. #define TSB_INDEX_MASK  ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1)
  47.  
  48. /** Invalidate portion of TSB.
  49.  *
  50.  * We assume that the address space is already locked. Note that respective
  51.  * portions of both TSBs are invalidated at a time.
  52.  *
  53.  * @param as    Address space.
  54.  * @param page  First page to invalidate in TSB.
  55.  * @param pages Number of pages to invalidate. Value of (count_t) -1 means the
  56.  *      whole TSB.
  57.  */
  58. void tsb_invalidate(as_t *as, uintptr_t page, count_t pages)
  59. {
  60.     index_t i0, i;
  61.     count_t cnt;
  62.    
  63.     ASSERT(as->arch.tsb_description.tsb_base);
  64.    
  65.     i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
  66.     ASSERT(i0 < TSB_ENTRY_COUNT);
  67.  
  68.     if (pages == (count_t) - 1 || (pages) > TSB_ENTRY_COUNT)
  69.         cnt = TSB_ENTRY_COUNT;
  70.     else
  71.         cnt = pages;
  72.    
  73.     for (i = 0; i < cnt; i++) {
  74.         ((tsb_entry_t *) as->arch.tsb_description.tsb_base)[
  75.             (i0 + i) & (TSB_ENTRY_COUNT - 1)].data.v = false;
  76.     }
  77. }
  78.  
  79. /** Copy software PTE to ITSB.
  80.  *
  81.  * @param t     Software PTE.
  82.  */
  83. void itsb_pte_copy(pte_t *t)
  84. {
  85.     as_t *as;
  86.     tsb_entry_t *tsb;
  87.     index_t entry;
  88.  
  89.     as = t->as;
  90.     entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
  91.     ASSERT(entry < TSB_ENTRY_COUNT);
  92.     tsb = &((tsb_entry_t *) as->arch.tsb_description.tsb_base)[entry];
  93.  
  94.     /*
  95.      * We use write barriers to make sure that the TSB load
  96.      * won't use inconsistent data or that the fault will
  97.      * be repeated.
  98.      */
  99.  
  100.     tsb->data.v = false;
  101.  
  102.     write_barrier();
  103.  
  104.     tsb->tag.context = as->asid;
  105.     tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
  106.  
  107.     tsb->data.value = 0;
  108.     tsb->data.nfo = false;
  109.     tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
  110.     tsb->data.ie = false;
  111.     tsb->data.e = false;
  112.     tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
  113.     tsb->data.cv = false;
  114.     tsb->data.p = t->k; /* p as privileged, k as kernel */
  115.     tsb->data.x = true;
  116.     tsb->data.w = false;
  117.     tsb->data.size = PAGESIZE_8K;
  118.    
  119.     write_barrier();
  120.    
  121.     tsb->data.v = t->p; /* v as valid, p as present */
  122. }
  123.  
  124. /** Copy software PTE to DTSB.
  125.  *
  126.  * @param t Software PTE.
  127.  * @param ro    If true, the mapping is copied read-only.
  128.  */
  129. void dtsb_pte_copy(pte_t *t, bool ro)
  130. {
  131.     as_t *as;
  132.     tsb_entry_t *tsb;
  133.     index_t entry;
  134.  
  135.     as = t->as;
  136.     entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
  137.     ASSERT(entry < TSB_ENTRY_COUNT);
  138.     tsb = &((tsb_entry_t *) as->arch.tsb_description.tsb_base)[entry];
  139.  
  140.     /*
  141.      * We use write barriers to make sure that the TSB load
  142.      * won't use inconsistent data or that the fault will
  143.      * be repeated.
  144.      */
  145.  
  146.     tsb->data.v = false;
  147.  
  148.     write_barrier();
  149.  
  150.     tsb->tag.context = as->asid;
  151.     tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
  152.  
  153.     tsb->data.value = 0;
  154.     tsb->data.nfo = false;
  155.     tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
  156.     tsb->data.ie = false;
  157.     tsb->data.e = false;
  158.     tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
  159. #ifdef CONFIG_VIRT_IDX_DCACHE
  160.     tsb->data.cv = t->c;
  161. #endif /* CONFIG_VIRT_IDX_DCACHE */
  162.     tsb->data.p = t->k; /* p as privileged, k as kernel */
  163.     tsb->data.x = true;
  164.     tsb->data.w = ro ? false : t->w;
  165.     tsb->data.size = PAGESIZE_8K;
  166.    
  167.     write_barrier();
  168.    
  169.     tsb->data.v = t->p; /* v as valid, p as present */
  170. }
  171.  
  172. /** @}
  173.  */
  174.  
  175.  
  176.