Subversion Repositories HelenOS

Rev

Rev 3343 | Go to most recent revision | Blame | 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. /* there are more TLBs in one MMU in US3, their codes are defined here */
  65. #if defined (US3)
  66.     /* D-MMU: one 16-entry TLB and two 512-entry TLBs */
  67.     #define TLB_DT16    0
  68.     #define TLB_DT512_1 2
  69.     #define TLB_DT512_2 3
  70.    
  71.     /* I-MMU: one 16-entry TLB and one 128-entry TLB */
  72.     #define TLB_IT16    0
  73.     #define TLB_IT128   2
  74. #endif
  75.  
  76. #define TLB_DEMAP_CONTEXT_SHIFT 4
  77.  
  78. /* TLB Tag Access shifts */
  79. #define TLB_TAG_ACCESS_CONTEXT_SHIFT    0
  80. #define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
  81. #define TLB_TAG_ACCESS_VPN_SHIFT    13
  82.  
  83. #ifndef __ASM__
  84.  
  85. #include <arch/mm/tte.h>
  86. #include <arch/mm/mmu.h>
  87. #include <arch/mm/page.h>
  88. #include <arch/asm.h>
  89. #include <arch/barrier.h>
  90. #include <arch/types.h>
  91.  
  92. union tlb_context_reg {
  93.     uint64_t v;
  94.     struct {
  95.         unsigned long : 51;
  96.         unsigned context : 13;      /**< Context/ASID. */
  97.     } __attribute__ ((packed));
  98. };
  99. typedef union tlb_context_reg tlb_context_reg_t;
  100.  
  101. /** I-/D-TLB Data In/Access Register type. */
  102. typedef tte_data_t tlb_data_t;
  103.  
  104. /** I-/D-TLB Data Access Address in Alternate Space. */
  105.  
  106. #if defined (US)
  107.  
  108. union tlb_data_access_addr {
  109.     uint64_t value;
  110.     struct {
  111.         uint64_t : 55;
  112.         unsigned tlb_entry : 6;
  113.         unsigned : 3;
  114.     } __attribute__ ((packed));
  115. };
  116. typedef union tlb_data_access_addr dtlb_data_access_addr_t;
  117. typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
  118. typedef union tlb_data_access_addr itlb_data_access_addr_t;
  119. typedef union tlb_data_access_addr itlb_tag_read_addr_t;
  120.  
  121. #elif defined (US3)
  122.  
  123. /*
  124.  * In US3, I-MMU and D-MMU have different formats of the data
  125.  * access register virtual address. In the corresponding
  126.  * structures the member variable for the entry number is
  127.  * called "local_tlb_entry" - it contrast with the "tlb_entry"
  128.  * for the US data access register VA structure. The rationale
  129.  * behind this is to prevent careless mistakes in the code
  130.  * caused by setting only the entry number and not the TLB
  131.  * number in the US3 code (when taking the code from US).
  132.  */
  133.  
  134. union dtlb_data_access_addr {
  135.     uint64_t value;
  136.     struct {
  137.         uint64_t : 45;
  138.         unsigned : 1;
  139.         unsigned tlb_number : 2;
  140.         unsigned : 4;
  141.         unsigned local_tlb_entry : 9;
  142.         unsigned : 3;
  143.     } __attribute__ ((packed));
  144. };
  145. typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
  146. typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
  147.  
  148. union itlb_data_access_addr {
  149.     uint64_t value;
  150.     struct {
  151.         uint64_t : 45;
  152.         unsigned : 1;
  153.         unsigned tlb_number : 2;
  154.         unsigned : 6;
  155.         unsigned local_tlb_entry : 7;
  156.         unsigned : 3;
  157.     } __attribute__ ((packed));
  158. };
  159. typedef union itlb_data_access_addr itlb_data_access_addr_t;
  160. typedef union itlb_data_access_addr itlb_tag_read_addr_t;
  161.  
  162. #endif
  163.  
  164. /** I-/D-TLB Tag Read Register. */
  165. union tlb_tag_read_reg {
  166.     uint64_t value;
  167.     struct {
  168.         uint64_t vpn : 51;  /**< Virtual Address bits 63:13. */
  169.         unsigned context : 13;  /**< Context identifier. */
  170.     } __attribute__ ((packed));
  171. };
  172. typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
  173. typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
  174.  
  175.  
  176. /** TLB Demap Operation Address. */
  177. union tlb_demap_addr {
  178.     uint64_t value;
  179.     struct {
  180.         uint64_t vpn: 51;   /**< Virtual Address bits 63:13. */
  181.         unsigned : 6;       /**< Ignored. */
  182.         unsigned type : 1;  /**< The type of demap operation. */
  183.         unsigned context : 2;   /**< Context register selection. */
  184.         unsigned : 4;       /**< Zero. */
  185.     } __attribute__ ((packed));
  186. };
  187. typedef union tlb_demap_addr tlb_demap_addr_t;
  188.  
  189. /** TLB Synchronous Fault Status Register. */
  190. union tlb_sfsr_reg {
  191.     uint64_t value;
  192.     struct {
  193.         unsigned long : 40; /**< Implementation dependent. */
  194.         unsigned asi : 8;   /**< ASI. */
  195.         unsigned : 2;
  196.         unsigned ft : 7;    /**< Fault type. */
  197.         unsigned e : 1;     /**< Side-effect bit. */
  198.         unsigned ct : 2;    /**< Context Register selection. */
  199.         unsigned pr : 1;    /**< Privilege bit. */
  200.         unsigned w : 1;     /**< Write bit. */
  201.         unsigned ow : 1;    /**< Overwrite bit. */
  202.         unsigned fv : 1;    /**< Fault Valid bit. */
  203.     } __attribute__ ((packed));
  204. };
  205. typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
  206.  
  207. /** Read MMU Primary Context Register.
  208.  *
  209.  * @return Current value of Primary Context Register.
  210.  */
  211. static inline uint64_t mmu_primary_context_read(void)
  212. {
  213.     return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
  214. }
  215.  
  216. /** Write MMU Primary Context Register.
  217.  *
  218.  * @param v New value of Primary Context Register.
  219.  */
  220. static inline void mmu_primary_context_write(uint64_t v)
  221. {
  222.     asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
  223.     flush_pipeline();
  224. }
  225.  
  226. /** Read MMU Secondary Context Register.
  227.  *
  228.  * @return Current value of Secondary Context Register.
  229.  */
  230. static inline uint64_t mmu_secondary_context_read(void)
  231. {
  232.     return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
  233. }
  234.  
  235. /** Write MMU Primary Context Register.
  236.  *
  237.  * @param v New value of Primary Context Register.
  238.  */
  239. static inline void mmu_secondary_context_write(uint64_t v)
  240. {
  241.     asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
  242.     flush_pipeline();
  243. }
  244.  
  245. #if defined (US)
  246.  
  247. /** Read IMMU TLB Data Access Register.
  248.  *
  249.  * @param entry TLB Entry index.
  250.  *
  251.  * @return Current value of specified IMMU TLB Data Access Register.
  252.  */
  253. static inline uint64_t itlb_data_access_read(index_t entry)
  254. {
  255.     itlb_data_access_addr_t reg;
  256.    
  257.     reg.value = 0;
  258.     reg.tlb_entry = entry;
  259.     return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
  260. }
  261.  
  262. /** Write IMMU TLB Data Access Register.
  263.  *
  264.  * @param entry TLB Entry index.
  265.  * @param value Value to be written.
  266.  */
  267. static inline void itlb_data_access_write(index_t entry, uint64_t value)
  268. {
  269.     itlb_data_access_addr_t reg;
  270.    
  271.     reg.value = 0;
  272.     reg.tlb_entry = entry;
  273.     asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
  274.     flush_pipeline();
  275. }
  276.  
  277. /** Read DMMU TLB Data Access Register.
  278.  *
  279.  * @param entry TLB Entry index.
  280.  *
  281.  * @return Current value of specified DMMU TLB Data Access Register.
  282.  */
  283. static inline uint64_t dtlb_data_access_read(index_t entry)
  284. {
  285.     dtlb_data_access_addr_t reg;
  286.    
  287.     reg.value = 0;
  288.     reg.tlb_entry = entry;
  289.     return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
  290. }
  291.  
  292. /** Write DMMU TLB Data Access Register.
  293.  *
  294.  * @param entry TLB Entry index.
  295.  * @param value Value to be written.
  296.  */
  297. static inline void dtlb_data_access_write(index_t entry, uint64_t value)
  298. {
  299.     dtlb_data_access_addr_t reg;
  300.    
  301.     reg.value = 0;
  302.     reg.tlb_entry = entry;
  303.     asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
  304.     membar();
  305. }
  306.  
  307. /** Read IMMU TLB Tag Read Register.
  308.  *
  309.  * @param entry TLB Entry index.
  310.  *
  311.  * @return Current value of specified IMMU TLB Tag Read Register.
  312.  */
  313. static inline uint64_t itlb_tag_read_read(index_t entry)
  314. {
  315.     itlb_tag_read_addr_t tag;
  316.  
  317.     tag.value = 0;
  318.     tag.tlb_entry = entry;
  319.     return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
  320. }
  321.  
  322. /** Read DMMU TLB Tag Read Register.
  323.  *
  324.  * @param entry TLB Entry index.
  325.  *
  326.  * @return Current value of specified DMMU TLB Tag Read Register.
  327.  */
  328. static inline uint64_t dtlb_tag_read_read(index_t entry)
  329. {
  330.     dtlb_tag_read_addr_t tag;
  331.  
  332.     tag.value = 0;
  333.     tag.tlb_entry = entry;
  334.     return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
  335. }
  336.  
  337. #elif defined (US3)
  338.  
  339.  
  340. /** Read IMMU TLB Data Access Register.
  341.  *
  342.  * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
  343.  * @param entry TLB Entry index.
  344.  *
  345.  * @return Current value of specified IMMU TLB Data Access Register.
  346.  */
  347. static inline uint64_t itlb_data_access_read(int tlb, index_t entry)
  348. {
  349.     itlb_data_access_addr_t reg;
  350.    
  351.     reg.value = 0;
  352.     reg.tlb_number = tlb;
  353.     reg.local_tlb_entry = entry;
  354.     return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
  355. }
  356.  
  357. /** Write IMMU TLB Data Access Register.
  358.  * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
  359.  * @param entry TLB Entry index.
  360.  * @param value Value to be written.
  361.  */
  362. static inline void itlb_data_access_write(int tlb, index_t entry, uint64_t value)
  363. {
  364.     itlb_data_access_addr_t reg;
  365.    
  366.     reg.value = 0;
  367.     reg.tlb_number = tlb;
  368.     reg.local_tlb_entry = entry;
  369.     asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
  370.     flush_pipeline();
  371. }
  372.  
  373. /** Read DMMU TLB Data Access Register.
  374.  *
  375.  * @param tlb TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2)
  376.  * @param entry TLB Entry index.
  377.  *
  378.  * @return Current value of specified DMMU TLB Data Access Register.
  379.  */
  380. static inline uint64_t dtlb_data_access_read(int tlb, index_t entry)
  381. {
  382.     dtlb_data_access_addr_t reg;
  383.    
  384.     reg.value = 0;
  385.     reg.tlb_number = tlb;
  386.     reg.local_tlb_entry = entry;
  387.     return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
  388. }
  389.  
  390. /** Write DMMU TLB Data Access Register.
  391.  *
  392.  * @param tlb TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2)  
  393.  * @param entry TLB Entry index.
  394.  * @param value Value to be written.
  395.  */
  396. static inline void dtlb_data_access_write(int tlb, index_t entry, uint64_t value)
  397. {
  398.     dtlb_data_access_addr_t reg;
  399.    
  400.     reg.value = 0;
  401.     reg.tlb_number = tlb;
  402.     reg.local_tlb_entry = entry;
  403.     asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
  404.     membar();
  405. }
  406.  
  407. /** Read IMMU TLB Tag Read Register.
  408.  *
  409.  * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
  410.  * @param entry TLB Entry index.
  411.  *
  412.  * @return Current value of specified IMMU TLB Tag Read Register.
  413.  */
  414. static inline uint64_t itlb_tag_read_read(int tlb, index_t entry)
  415. {
  416.     itlb_tag_read_addr_t tag;
  417.  
  418.     tag.value = 0;
  419.     tag.tlb_number = tlb;
  420.     tag.local_tlb_entry = entry;
  421.     return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
  422. }
  423.  
  424. /** Read DMMU TLB Tag Read Register.
  425.  *
  426.  * @param tlb TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2)  
  427.  * @param entry TLB Entry index.
  428.  *
  429.  * @return Current value of specified DMMU TLB Tag Read Register.
  430.  */
  431. static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry)
  432. {
  433.     dtlb_tag_read_addr_t tag;
  434.  
  435.     tag.value = 0;
  436.     tag.tlb_number = tlb;
  437.     tag.local_tlb_entry = entry;
  438.     return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
  439. }
  440.  
  441. #endif
  442.  
  443.  
  444. /** Write IMMU TLB Tag Access Register.
  445.  *
  446.  * @param v Value to be written.
  447.  */
  448. static inline void itlb_tag_access_write(uint64_t v)
  449. {
  450.     asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
  451.     flush_pipeline();
  452. }
  453.  
  454. /** Read IMMU TLB Tag Access Register.
  455.  *
  456.  * @return Current value of IMMU TLB Tag Access Register.
  457.  */
  458. static inline uint64_t itlb_tag_access_read(void)
  459. {
  460.     return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
  461. }
  462.  
  463. /** Write DMMU TLB Tag Access Register.
  464.  *
  465.  * @param v Value to be written.
  466.  */
  467. static inline void dtlb_tag_access_write(uint64_t v)
  468. {
  469.     asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
  470.     membar();
  471. }
  472.  
  473. /** Read DMMU TLB Tag Access Register.
  474.  *
  475.  * @return Current value of DMMU TLB Tag Access Register.
  476.  */
  477. static inline uint64_t dtlb_tag_access_read(void)
  478. {
  479.     return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
  480. }
  481.  
  482.  
  483. /** Write IMMU TLB Data in Register.
  484.  *
  485.  * @param v Value to be written.
  486.  */
  487. static inline void itlb_data_in_write(uint64_t v)
  488. {
  489.     asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
  490.     flush_pipeline();
  491. }
  492.  
  493. /** Write DMMU TLB Data in Register.
  494.  *
  495.  * @param v Value to be written.
  496.  */
  497. static inline void dtlb_data_in_write(uint64_t v)
  498. {
  499.     asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
  500.     membar();
  501. }
  502.  
  503. /** Read ITLB Synchronous Fault Status Register.
  504.  *
  505.  * @return Current content of I-SFSR register.
  506.  */
  507. static inline uint64_t itlb_sfsr_read(void)
  508. {
  509.     return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
  510. }
  511.  
  512. /** Write ITLB Synchronous Fault Status Register.
  513.  *
  514.  * @param v New value of I-SFSR register.
  515.  */
  516. static inline void itlb_sfsr_write(uint64_t v)
  517. {
  518.     asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
  519.     flush_pipeline();
  520. }
  521.  
  522. /** Read DTLB Synchronous Fault Status Register.
  523.  *
  524.  * @return Current content of D-SFSR register.
  525.  */
  526. static inline uint64_t dtlb_sfsr_read(void)
  527. {
  528.     return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
  529. }
  530.  
  531. /** Write DTLB Synchronous Fault Status Register.
  532.  *
  533.  * @param v New value of D-SFSR register.
  534.  */
  535. static inline void dtlb_sfsr_write(uint64_t v)
  536. {
  537.     asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
  538.     membar();
  539. }
  540.  
  541. /** Read DTLB Synchronous Fault Address Register.
  542.  *
  543.  * @return Current content of D-SFAR register.
  544.  */
  545. static inline uint64_t dtlb_sfar_read(void)
  546. {
  547.     return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
  548. }
  549.  
  550. /** Perform IMMU TLB Demap Operation.
  551.  *
  552.  * @param type Selects between context and page demap.
  553.  * @param context_encoding Specifies which Context register has Context ID for
  554.  *  demap.
  555.  * @param page Address which is on the page to be demapped.
  556.  */
  557. static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
  558. {
  559.     tlb_demap_addr_t da;
  560.     page_address_t pg;
  561.    
  562.     da.value = 0;
  563.     pg.address = page;
  564.    
  565.     da.type = type;
  566.     da.context = context_encoding;
  567.     da.vpn = pg.vpn;
  568.    
  569.     asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
  570.                              * address within the
  571.                              * ASI */
  572.     flush_pipeline();
  573. }
  574.  
  575. /** Perform DMMU TLB Demap Operation.
  576.  *
  577.  * @param type Selects between context and page demap.
  578.  * @param context_encoding Specifies which Context register has Context ID for
  579.  *   demap.
  580.  * @param page Address which is on the page to be demapped.
  581.  */
  582. static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
  583. {
  584.     tlb_demap_addr_t da;
  585.     page_address_t pg;
  586.    
  587.     da.value = 0;
  588.     pg.address = page;
  589.    
  590.     da.type = type;
  591.     da.context = context_encoding;
  592.     da.vpn = pg.vpn;
  593.    
  594.     asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
  595.                              * address within the
  596.                              * ASI */
  597.     membar();
  598. }
  599.  
  600. extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
  601. extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
  602. extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
  603.  
  604. extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
  605.  
  606. extern void dump_sfsr_and_sfar(void);
  607.  
  608. #endif /* !def __ASM__ */
  609.  
  610. #endif
  611.  
  612. /** @}
  613.  */