Subversion Repositories HelenOS-historic

Rev

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