Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2005 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. #ifndef KERN_sparc64_TLB_H_
  36. #define KERN_sparc64_TLB_H_
  37.  
  38. #define ITLB_ENTRY_COUNT        64
  39. #define DTLB_ENTRY_COUNT        64
  40.  
  41. #define MEM_CONTEXT_KERNEL      0
  42. #define MEM_CONTEXT_TEMP        1
  43.  
  44. /** Page sizes. */
  45. #define PAGESIZE_8K 0
  46. #define PAGESIZE_64K    1
  47. #define PAGESIZE_512K   2
  48. #define PAGESIZE_4M 3
  49.  
  50. /** Bit width of the TLB-locked portion of kernel address space. */
  51. #define KERNEL_PAGE_WIDTH       22  /* 4M */
  52.  
  53. /* TLB Demap Operation types. */
  54. #define TLB_DEMAP_PAGE      0
  55. #define TLB_DEMAP_CONTEXT   1
  56.  
  57. #define TLB_DEMAP_TYPE_SHIFT    6
  58.  
  59. /* TLB Demap Operation Context register encodings. */
  60. #define TLB_DEMAP_PRIMARY   0
  61. #define TLB_DEMAP_SECONDARY 1
  62. #define TLB_DEMAP_NUCLEUS   2
  63.  
  64. #define TLB_DEMAP_CONTEXT_SHIFT 4
  65.  
  66. /* TLB Tag Access shifts */
  67. #define TLB_TAG_ACCESS_CONTEXT_SHIFT    0
  68. #define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
  69. #define TLB_TAG_ACCESS_VPN_SHIFT    13
  70.  
  71. #ifndef __ASM__
  72.  
  73. #include <arch/mm/tte.h>
  74. #include <arch/mm/mmu.h>
  75. #include <arch/mm/page.h>
  76. #include <arch/asm.h>
  77. #include <arch/barrier.h>
  78. #include <arch/types.h>
  79.  
  80. union tlb_context_reg {
  81.     uint64_t v;
  82.     struct {
  83.         unsigned long : 51;
  84.         unsigned context : 13;      /**< Context/ASID. */
  85.     } __attribute__ ((packed));
  86. };
  87. typedef union tlb_context_reg tlb_context_reg_t;
  88.  
  89. /** I-/D-TLB Data In/Access Register type. */
  90. typedef tte_data_t tlb_data_t;
  91.  
  92. /** I-/D-TLB Data Access Address in Alternate Space. */
  93. union tlb_data_access_addr {
  94.     uint64_t value;
  95.     struct {
  96.         uint64_t : 55;
  97.         unsigned tlb_entry : 6;
  98.         unsigned : 3;
  99.     } __attribute__ ((packed));
  100. };
  101. typedef union tlb_data_access_addr tlb_data_access_addr_t;
  102. typedef union tlb_data_access_addr tlb_tag_read_addr_t;
  103.  
  104. /** I-/D-TLB Tag Read Register. */
  105. union tlb_tag_read_reg {
  106.     uint64_t value;
  107.     struct {
  108.         uint64_t vpn : 51;  /**< Virtual Address bits 63:13. */
  109.         unsigned context : 13;  /**< Context identifier. */
  110.     } __attribute__ ((packed));
  111. };
  112. typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
  113. typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
  114.  
  115.  
  116. /** TLB Demap Operation Address. */
  117. union tlb_demap_addr {
  118.     uint64_t value;
  119.     struct {
  120.         uint64_t vpn: 51;   /**< Virtual Address bits 63:13. */
  121.         unsigned : 6;       /**< Ignored. */
  122.         unsigned type : 1;  /**< The type of demap operation. */
  123.         unsigned context : 2;   /**< Context register selection. */
  124.         unsigned : 4;       /**< Zero. */
  125.     } __attribute__ ((packed));
  126. };
  127. typedef union tlb_demap_addr tlb_demap_addr_t;
  128.  
  129. /** TLB Synchronous Fault Status Register. */
  130. union tlb_sfsr_reg {
  131.     uint64_t value;
  132.     struct {
  133.         unsigned long : 40; /**< Implementation dependent. */
  134.         unsigned asi : 8;   /**< ASI. */
  135.         unsigned : 2;
  136.         unsigned ft : 7;    /**< Fault type. */
  137.         unsigned e : 1;     /**< Side-effect bit. */
  138.         unsigned ct : 2;    /**< Context Register selection. */
  139.         unsigned pr : 1;    /**< Privilege bit. */
  140.         unsigned w : 1;     /**< Write bit. */
  141.         unsigned ow : 1;    /**< Overwrite bit. */
  142.         unsigned fv : 1;    /**< Fault Valid bit. */
  143.     } __attribute__ ((packed));
  144. };
  145. typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
  146.  
  147. /** Read MMU Primary Context Register.
  148.  *
  149.  * @return Current value of Primary Context Register.
  150.  */
  151. static inline uint64_t mmu_primary_context_read(void)
  152. {
  153.     return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
  154. }
  155.  
  156. /** Write MMU Primary Context Register.
  157.  *
  158.  * @param v New value of Primary Context Register.
  159.  */
  160. static inline void mmu_primary_context_write(uint64_t v)
  161. {
  162.     asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
  163.     flush_blind();
  164. }
  165.  
  166. /** Read MMU Secondary Context Register.
  167.  *
  168.  * @return Current value of Secondary Context Register.
  169.  */
  170. static inline uint64_t mmu_secondary_context_read(void)
  171. {
  172.     return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
  173. }
  174.  
  175. /** Write MMU Primary Context Register.
  176.  *
  177.  * @param v New value of Primary Context Register.
  178.  */
  179. static inline void mmu_secondary_context_write(uint64_t v)
  180. {
  181.     asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
  182.     flush_blind();
  183. }
  184.  
  185. /** Read IMMU TLB Data Access Register.
  186.  *
  187.  * @param entry TLB Entry index.
  188.  *
  189.  * @return Current value of specified IMMU TLB Data Access Register.
  190.  */
  191. static inline uint64_t itlb_data_access_read(index_t entry)
  192. {
  193.     tlb_data_access_addr_t reg;
  194.    
  195.     reg.value = 0;
  196.     reg.tlb_entry = entry;
  197.     return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
  198. }
  199.  
  200. /** Write IMMU TLB Data Access Register.
  201.  *
  202.  * @param entry TLB Entry index.
  203.  * @param value Value to be written.
  204.  */
  205. static inline void itlb_data_access_write(index_t entry, uint64_t value)
  206. {
  207.     tlb_data_access_addr_t reg;
  208.    
  209.     reg.value = 0;
  210.     reg.tlb_entry = entry;
  211.     asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
  212.     flush_blind();
  213. }
  214.  
  215. /** Read DMMU TLB Data Access Register.
  216.  *
  217.  * @param entry TLB Entry index.
  218.  *
  219.  * @return Current value of specified DMMU TLB Data Access Register.
  220.  */
  221. static inline uint64_t dtlb_data_access_read(index_t entry)
  222. {
  223.     tlb_data_access_addr_t reg;
  224.    
  225.     reg.value = 0;
  226.     reg.tlb_entry = entry;
  227.     return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
  228. }
  229.  
  230. /** Write DMMU TLB Data Access Register.
  231.  *
  232.  * @param entry TLB Entry index.
  233.  * @param value Value to be written.
  234.  */
  235. static inline void dtlb_data_access_write(index_t entry, uint64_t value)
  236. {
  237.     tlb_data_access_addr_t reg;
  238.    
  239.     reg.value = 0;
  240.     reg.tlb_entry = entry;
  241.     asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
  242.     membar();
  243. }
  244.  
  245. /** Read IMMU TLB Tag Read Register.
  246.  *
  247.  * @param entry TLB Entry index.
  248.  *
  249.  * @return Current value of specified IMMU TLB Tag Read Register.
  250.  */
  251. static inline uint64_t itlb_tag_read_read(index_t entry)
  252. {
  253.     tlb_tag_read_addr_t tag;
  254.  
  255.     tag.value = 0;
  256.     tag.tlb_entry = entry;
  257.     return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
  258. }
  259.  
  260. /** Read DMMU TLB Tag Read Register.
  261.  *
  262.  * @param entry TLB Entry index.
  263.  *
  264.  * @return Current value of specified DMMU TLB Tag Read Register.
  265.  */
  266. static inline uint64_t dtlb_tag_read_read(index_t entry)
  267. {
  268.     tlb_tag_read_addr_t tag;
  269.  
  270.     tag.value = 0;
  271.     tag.tlb_entry = entry;
  272.     return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
  273. }
  274.  
  275. /** Write IMMU TLB Tag Access Register.
  276.  *
  277.  * @param v Value to be written.
  278.  */
  279. static inline void itlb_tag_access_write(uint64_t v)
  280. {
  281.     asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
  282.     flush_blind();
  283. }
  284.  
  285. /** Read IMMU TLB Tag Access Register.
  286.  *
  287.  * @return Current value of IMMU TLB Tag Access Register.
  288.  */
  289. static inline uint64_t itlb_tag_access_read(void)
  290. {
  291.     return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
  292. }
  293.  
  294. /** Write DMMU TLB Tag Access Register.
  295.  *
  296.  * @param v Value to be written.
  297.  */
  298. static inline void dtlb_tag_access_write(uint64_t v)
  299. {
  300.     asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
  301.     membar();
  302. }
  303.  
  304. /** Read DMMU TLB Tag Access Register.
  305.  *
  306.  * @return Current value of DMMU TLB Tag Access Register.
  307.  */
  308. static inline uint64_t dtlb_tag_access_read(void)
  309. {
  310.     return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
  311. }
  312.  
  313.  
  314. /** Write IMMU TLB Data in Register.
  315.  *
  316.  * @param v Value to be written.
  317.  */
  318. static inline void itlb_data_in_write(uint64_t v)
  319. {
  320.     asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
  321.     flush_blind();
  322. }
  323.  
  324. /** Write DMMU TLB Data in Register.
  325.  *
  326.  * @param v Value to be written.
  327.  */
  328. static inline void dtlb_data_in_write(uint64_t v)
  329. {
  330.     asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
  331.     membar();
  332. }
  333.  
  334. /** Read ITLB Synchronous Fault Status Register.
  335.  *
  336.  * @return Current content of I-SFSR register.
  337.  */
  338. static inline uint64_t itlb_sfsr_read(void)
  339. {
  340.     return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
  341. }
  342.  
  343. /** Write ITLB Synchronous Fault Status Register.
  344.  *
  345.  * @param v New value of I-SFSR register.
  346.  */
  347. static inline void itlb_sfsr_write(uint64_t v)
  348. {
  349.     asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
  350.     flush_blind();
  351. }
  352.  
  353. /** Read DTLB Synchronous Fault Status Register.
  354.  *
  355.  * @return Current content of D-SFSR register.
  356.  */
  357. static inline uint64_t dtlb_sfsr_read(void)
  358. {
  359.     return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
  360. }
  361.  
  362. /** Write DTLB Synchronous Fault Status Register.
  363.  *
  364.  * @param v New value of D-SFSR register.
  365.  */
  366. static inline void dtlb_sfsr_write(uint64_t v)
  367. {
  368.     asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
  369.     membar();
  370. }
  371.  
  372. /** Read DTLB Synchronous Fault Address Register.
  373.  *
  374.  * @return Current content of D-SFAR register.
  375.  */
  376. static inline uint64_t dtlb_sfar_read(void)
  377. {
  378.     return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
  379. }
  380.  
  381. /** Perform IMMU TLB Demap Operation.
  382.  *
  383.  * @param type Selects between context and page demap.
  384.  * @param context_encoding Specifies which Context register has Context ID for
  385.  *  demap.
  386.  * @param page Address which is on the page to be demapped.
  387.  */
  388. static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
  389. {
  390.     tlb_demap_addr_t da;
  391.     page_address_t pg;
  392.    
  393.     da.value = 0;
  394.     pg.address = page;
  395.    
  396.     da.type = type;
  397.     da.context = context_encoding;
  398.     da.vpn = pg.vpn;
  399.    
  400.     asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
  401.                              * address within the
  402.                              * ASI */
  403.     flush_blind();
  404. }
  405.  
  406. /** Perform DMMU TLB Demap Operation.
  407.  *
  408.  * @param type Selects between context and page demap.
  409.  * @param context_encoding Specifies which Context register has Context ID for
  410.  *   demap.
  411.  * @param page Address which is on the page to be demapped.
  412.  */
  413. static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
  414. {
  415.     tlb_demap_addr_t da;
  416.     page_address_t pg;
  417.    
  418.     da.value = 0;
  419.     pg.address = page;
  420.    
  421.     da.type = type;
  422.     da.context = context_encoding;
  423.     da.vpn = pg.vpn;
  424.    
  425.     asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
  426.                              * address within the
  427.                              * ASI */
  428.     membar();
  429. }
  430.  
  431. extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
  432. extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
  433. extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
  434.  
  435. extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
  436.  
  437. extern void dump_sfsr_and_sfar(void);
  438.  
  439. #endif /* !def __ASM__ */
  440.  
  441. #endif
  442.  
  443. /** @}
  444.  */
  445.