Subversion Repositories HelenOS

Rev

Rev 1890 | Rev 1892 | 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. /** @addtogroup sparc64mm
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <arch/mm/as.h>
  36. #include <arch/mm/tlb.h>
  37. #include <genarch/mm/as_ht.h>
  38. #include <genarch/mm/asid_fifo.h>
  39. #include <debug.h>
  40.  
  41. #ifdef CONFIG_TSB
  42. #include <arch/mm/tsb.h>
  43. #include <arch/memstr.h>
  44. #include <synch/mutex.h>
  45. #include <arch/asm.h>
  46. #include <mm/frame.h>
  47. #include <bitops.h>
  48. #include <macros.h>
  49. #endif
  50.  
  51. /** Architecture dependent address space init. */
  52. void as_arch_init(void)
  53. {
  54.     as_operations = &as_ht_operations;
  55.     asid_fifo_init();
  56. }
  57.  
  58. int as_constructor_arch(as_t *as, int flags)
  59. {
  60. #ifdef CONFIG_TSB
  61.     int order = fnzb32(((ITSB_ENTRY_COUNT+DTSB_ENTRY_COUNT)*sizeof(tsb_entry_t))>>FRAME_WIDTH);
  62.     uintptr_t tsb = (uintptr_t) frame_alloc(order, flags);
  63.  
  64.     if (!tsb)
  65.         return -1;
  66.  
  67.     as->arch.itsb = (tsb_entry_t *) tsb;
  68.     as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * sizeof(tsb_entry_t));
  69. #endif
  70.     return 0;
  71. }
  72.  
  73. int as_destructor_arch(as_t *as)
  74. {
  75. #ifdef CONFIG_TSB
  76.     count_t cnt = ((ITSB_ENTRY_COUNT+DTSB_ENTRY_COUNT)*sizeof(tsb_entry_t))>>FRAME_WIDTH;
  77.     frame_free((uintptr_t) as->arch.itsb);
  78.     return cnt;
  79. #else
  80.     return 0;
  81. #endif
  82. }
  83.  
  84. int as_create_arch(as_t *as, int flags)
  85. {
  86. #ifdef CONFIG_TSB
  87.     ipl_t ipl;
  88.  
  89.     memsetb((uintptr_t) as->arch.itsb, (ITSB_ENTRY_COUNT+DTSB_ENTRY_COUNT)*sizeof(tsb_entry_t), 0);
  90.     ipl = interrupts_disable();
  91.     mutex_lock_active(&as->lock);   /* completely unnecessary, but polite */
  92.     tsb_invalidate(as, 0, (count_t) -1);
  93.     mutex_unlock(&as->lock);
  94.     interrupts_restore(ipl);
  95. #endif
  96.     return 0;
  97. }
  98.  
  99. /** Perform sparc64-specific tasks when an address space becomes active on the processor.
  100.  *
  101.  * Install ASID and map TSBs.
  102.  *
  103.  * @param as Address space.
  104.  */
  105. void as_install_arch(as_t *as)
  106. {
  107.     tlb_context_reg_t ctx;
  108.    
  109.     /*
  110.      * Note that we don't lock the address space.
  111.      * That's correct - we can afford it here
  112.      * because we only read members that are
  113.      * currently read-only.
  114.      */
  115.    
  116.     /*
  117.      * Write ASID to secondary context register.
  118.      * The primary context register has to be set
  119.      * from TL>0 so it will be filled from the
  120.      * secondary context register from the TL=1
  121.      * code just before switch to userspace.
  122.      */
  123.     ctx.v = 0;
  124.     ctx.context = as->asid;
  125.     mmu_secondary_context_write(ctx.v);
  126.  
  127. #ifdef CONFIG_TSB  
  128.     uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
  129.  
  130.     ASSERT(as->arch.itsb && as->arch.dtsb);
  131.  
  132.     uintptr_t tsb = (uintptr_t) as->arch.itsb;
  133.        
  134.     if (!overlaps(tsb, 8*PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
  135.         /*
  136.          * TSBs were allocated from memory not covered
  137.          * by the locked 4M kernel DTLB entry. We need
  138.          * to map both TSBs explicitly.
  139.          */
  140.         dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
  141.         dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true);
  142.     }
  143.        
  144.     /*
  145.      * Setup TSB Base registers.
  146.      */
  147.     tsb_base_reg_t tsb_base;
  148.        
  149.     tsb_base.value = 0;
  150.     tsb_base.size = TSB_SIZE;
  151.     tsb_base.split = 0;
  152.  
  153.     tsb_base.base = ((uintptr_t) as->arch.itsb) >> PAGE_WIDTH;
  154.     itsb_base_write(tsb_base.value);
  155.     tsb_base.base = ((uintptr_t) as->arch.dtsb) >> PAGE_WIDTH;
  156.     dtsb_base_write(tsb_base.value);
  157. #endif
  158. }
  159.  
  160. /** Perform sparc64-specific tasks when an address space is removed from the processor.
  161.  *
  162.  * Demap TSBs.
  163.  *
  164.  * @param as Address space.
  165.  */
  166. void as_deinstall_arch(as_t *as)
  167. {
  168.  
  169.     /*
  170.      * Note that we don't lock the address space.
  171.      * That's correct - we can afford it here
  172.      * because we only read members that are
  173.      * currently read-only.
  174.      */
  175.  
  176. #ifdef CONFIG_TSB
  177.     uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
  178.  
  179.     ASSERT(as->arch.itsb && as->arch.dtsb);
  180.  
  181.     uintptr_t tsb = (uintptr_t) as->arch.itsb;
  182.        
  183.     if (!overlaps(tsb, 8*PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
  184.         /*
  185.          * TSBs were allocated from memory not covered
  186.          * by the locked 4M kernel DTLB entry. We need
  187.          * to demap the entry installed by as_install_arch().
  188.          */
  189.         dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
  190.     }
  191. #endif
  192. }
  193.  
  194. /** @}
  195.  */
  196.