Subversion Repositories HelenOS

Rev

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