Subversion Repositories HelenOS

Rev

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