Changeset 965dc18 in mainline for kernel/arch/sparc64/include/mm/tlb.h


Ignore:
Timestamp:
2008-12-05T19:59:03Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
49093a4
Parents:
0258e67
Message:

Merge sparc branch to trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/include/mm/tlb.h

    r0258e67 r965dc18  
    3636#define KERN_sparc64_TLB_H_
    3737
     38#if defined (US)
    3839#define ITLB_ENTRY_COUNT                64
    3940#define DTLB_ENTRY_COUNT                64
     41#define DTLB_MAX_LOCKED_ENTRIES         DTLB_ENTRY_COUNT
     42#endif
     43
     44/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */
     45#if defined (US3)
     46#define DTLB_MAX_LOCKED_ENTRIES         16
     47#endif
    4048
    4149#define MEM_CONTEXT_KERNEL              0
     
    5462#define TLB_DEMAP_PAGE          0
    5563#define TLB_DEMAP_CONTEXT       1
     64#if defined (US3)
     65#define TLB_DEMAP_ALL           2
     66#endif
    5667
    5768#define TLB_DEMAP_TYPE_SHIFT    6
     
    6172#define TLB_DEMAP_SECONDARY     1
    6273#define TLB_DEMAP_NUCLEUS       2
     74
     75/* There are more TLBs in one MMU in US3, their codes are defined here. */
     76#if defined (US3)
     77/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
     78#define TLB_DSMALL      0
     79#define TLB_DBIG_0      2
     80#define TLB_DBIG_1      3
     81       
     82/* I-MMU: one small (16-entry) TLB and one big TLB */
     83#define TLB_ISMALL      0
     84#define TLB_IBIG        2
     85#endif
    6386
    6487#define TLB_DEMAP_CONTEXT_SHIFT 4
     
    77100#include <arch/barrier.h>
    78101#include <arch/types.h>
     102#include <arch/register.h>
     103#include <arch/cpu.h>
    79104
    80105union tlb_context_reg {
     
    91116
    92117/** I-/D-TLB Data Access Address in Alternate Space. */
     118
     119#if defined (US)
     120
    93121union tlb_data_access_addr {
    94122        uint64_t value;
     
    99127        } __attribute__ ((packed));
    100128};
    101 typedef union tlb_data_access_addr tlb_data_access_addr_t;
    102 typedef union tlb_data_access_addr tlb_tag_read_addr_t;
     129typedef union tlb_data_access_addr dtlb_data_access_addr_t;
     130typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
     131typedef union tlb_data_access_addr itlb_data_access_addr_t;
     132typedef union tlb_data_access_addr itlb_tag_read_addr_t;
     133
     134#elif defined (US3)
     135
     136/*
     137 * In US3, I-MMU and D-MMU have different formats of the data
     138 * access register virtual address. In the corresponding
     139 * structures the member variable for the entry number is
     140 * called "local_tlb_entry" - it contrasts with the "tlb_entry"
     141 * for the US data access register VA structure. The rationale
     142 * behind this is to prevent careless mistakes in the code
     143 * caused by setting only the entry number and not the TLB
     144 * number in the US3 code (when taking the code from US).
     145 */
     146
     147union dtlb_data_access_addr {
     148        uint64_t value;
     149        struct {
     150                uint64_t : 45;
     151                unsigned : 1;
     152                unsigned tlb_number : 2;
     153                unsigned : 4;
     154                unsigned local_tlb_entry : 9;
     155                unsigned : 3;
     156        } __attribute__ ((packed));
     157};
     158typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
     159typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
     160
     161union itlb_data_access_addr {
     162        uint64_t value;
     163        struct {
     164                uint64_t : 45;
     165                unsigned : 1;
     166                unsigned tlb_number : 2;
     167                unsigned : 6;
     168                unsigned local_tlb_entry : 7;
     169                unsigned : 3;
     170        } __attribute__ ((packed));
     171};
     172typedef union itlb_data_access_addr itlb_data_access_addr_t;
     173typedef union itlb_data_access_addr itlb_tag_read_addr_t;
     174
     175#endif
    103176
    104177/** I-/D-TLB Tag Read Register. */
     
    119192        struct {
    120193                uint64_t vpn: 51;       /**< Virtual Address bits 63:13. */
     194#if defined (US)
    121195                unsigned : 6;           /**< Ignored. */
    122196                unsigned type : 1;      /**< The type of demap operation. */
     197#elif defined (US3)
     198                unsigned : 5;           /**< Ignored. */
     199                unsigned type: 2;       /**< The type of demap operation. */
     200#endif
    123201                unsigned context : 2;   /**< Context register selection. */
    124202                unsigned : 4;           /**< Zero. */
     
    131209        uint64_t value;
    132210        struct {
     211#if defined (US)
    133212                unsigned long : 40;     /**< Implementation dependent. */
    134213                unsigned asi : 8;       /**< ASI. */
    135214                unsigned : 2;
    136215                unsigned ft : 7;        /**< Fault type. */
     216#elif defined (US3)
     217                unsigned long : 39;     /**< Implementation dependent. */
     218                unsigned nf : 1;        /**< Non-faulting load. */
     219                unsigned asi : 8;       /**< ASI. */
     220                unsigned tm : 1;        /**< I-TLB miss. */
     221                unsigned : 3;           /**< Reserved. */
     222                unsigned ft : 5;        /**< Fault type. */
     223#endif
    137224                unsigned e : 1;         /**< Side-effect bit. */
    138225                unsigned ct : 2;        /**< Context Register selection. */
     
    145232typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
    146233
     234#if defined (US3)
     235
     236/*
     237 * Functions for determining the number of entries in TLBs. They either return
     238 * a constant value or a value based on the CPU autodetection.
     239 */
     240
     241/**
     242 * Determine the number of entries in the DMMU's small TLB.
     243 */
     244static inline uint16_t tlb_dsmall_size(void)
     245{
     246        return 16;
     247}
     248
     249/**
     250 * Determine the number of entries in each DMMU's big TLB.
     251 */
     252static inline uint16_t tlb_dbig_size(void)
     253{
     254        return 512;
     255}
     256
     257/**
     258 * Determine the number of entries in the IMMU's small TLB.
     259 */
     260static inline uint16_t tlb_ismall_size(void)
     261{
     262        return 16;
     263}
     264
     265/**
     266 * Determine the number of entries in the IMMU's big TLB.
     267 */
     268static inline uint16_t tlb_ibig_size(void)
     269{
     270        if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
     271                return 512;
     272        else
     273                return 128;
     274}
     275
     276#endif
     277
    147278/** Read MMU Primary Context Register.
    148279 *
    149  * @return Current value of Primary Context Register.
     280 * @return              Current value of Primary Context Register.
    150281 */
    151282static inline uint64_t mmu_primary_context_read(void)
     
    156287/** Write MMU Primary Context Register.
    157288 *
    158  * @param v New value of Primary Context Register.
     289 * @param v             New value of Primary Context Register.
    159290 */
    160291static inline void mmu_primary_context_write(uint64_t v)
     
    166297/** Read MMU Secondary Context Register.
    167298 *
    168  * @return Current value of Secondary Context Register.
     299 * @return              Current value of Secondary Context Register.
    169300 */
    170301static inline uint64_t mmu_secondary_context_read(void)
     
    175306/** Write MMU Primary Context Register.
    176307 *
    177  * @param v New value of Primary Context Register.
     308 * @param v             New value of Primary Context Register.
    178309 */
    179310static inline void mmu_secondary_context_write(uint64_t v)
     
    183314}
    184315
     316#if defined (US)
     317
    185318/** Read IMMU TLB Data Access Register.
    186319 *
    187  * @param entry TLB Entry index.
    188  *
    189  * @return Current value of specified IMMU TLB Data Access Register.
     320 * @param entry         TLB Entry index.
     321 *
     322 * @return              Current value of specified IMMU TLB Data Access
     323 *                      Register.
    190324 */
    191325static inline uint64_t itlb_data_access_read(index_t entry)
    192326{
    193         tlb_data_access_addr_t reg;
     327        itlb_data_access_addr_t reg;
    194328       
    195329        reg.value = 0;
     
    200334/** Write IMMU TLB Data Access Register.
    201335 *
    202  * @param entry TLB Entry index.
    203  * @param value Value to be written.
     336 * @param entry         TLB Entry index.
     337 * @param value         Value to be written.
    204338 */
    205339static inline void itlb_data_access_write(index_t entry, uint64_t value)
    206340{
    207         tlb_data_access_addr_t reg;
     341        itlb_data_access_addr_t reg;
    208342       
    209343        reg.value = 0;
     
    215349/** Read DMMU TLB Data Access Register.
    216350 *
    217  * @param entry TLB Entry index.
    218  *
    219  * @return Current value of specified DMMU TLB Data Access Register.
     351 * @param entry         TLB Entry index.
     352 *
     353 * @return              Current value of specified DMMU TLB Data Access
     354 *                      Register.
    220355 */
    221356static inline uint64_t dtlb_data_access_read(index_t entry)
    222357{
    223         tlb_data_access_addr_t reg;
     358        dtlb_data_access_addr_t reg;
    224359       
    225360        reg.value = 0;
     
    230365/** Write DMMU TLB Data Access Register.
    231366 *
    232  * @param entry TLB Entry index.
    233  * @param value Value to be written.
     367 * @param entry         TLB Entry index.
     368 * @param value         Value to be written.
    234369 */
    235370static inline void dtlb_data_access_write(index_t entry, uint64_t value)
    236371{
    237         tlb_data_access_addr_t reg;
     372        dtlb_data_access_addr_t reg;
    238373       
    239374        reg.value = 0;
     
    245380/** Read IMMU TLB Tag Read Register.
    246381 *
    247  * @param entry TLB Entry index.
    248  *
    249  * @return Current value of specified IMMU TLB Tag Read Register.
     382 * @param entry         TLB Entry index.
     383 *
     384 * @return              Current value of specified IMMU TLB Tag Read Register.
    250385 */
    251386static inline uint64_t itlb_tag_read_read(index_t entry)
    252387{
    253         tlb_tag_read_addr_t tag;
     388        itlb_tag_read_addr_t tag;
    254389
    255390        tag.value = 0;
     
    260395/** Read DMMU TLB Tag Read Register.
    261396 *
    262  * @param entry TLB Entry index.
    263  *
    264  * @return Current value of specified DMMU TLB Tag Read Register.
     397 * @param entry         TLB Entry index.
     398 *
     399 * @return              Current value of specified DMMU TLB Tag Read Register.
    265400 */
    266401static inline uint64_t dtlb_tag_read_read(index_t entry)
    267402{
    268         tlb_tag_read_addr_t tag;
     403        dtlb_tag_read_addr_t tag;
    269404
    270405        tag.value = 0;
     
    273408}
    274409
     410#elif defined (US3)
     411
     412
     413/** Read IMMU TLB Data Access Register.
     414 *
     415 * @param tlb           TLB number (one of TLB_ISMALL or TLB_IBIG)
     416 * @param entry         TLB Entry index.
     417 *
     418 * @return              Current value of specified IMMU TLB Data Access
     419 *                      Register.
     420 */
     421static inline uint64_t itlb_data_access_read(int tlb, index_t entry)
     422{
     423        itlb_data_access_addr_t reg;
     424       
     425        reg.value = 0;
     426        reg.tlb_number = tlb;
     427        reg.local_tlb_entry = entry;
     428        return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
     429}
     430
     431/** Write IMMU TLB Data Access Register.
     432 * @param tlb           TLB number (one of TLB_ISMALL or TLB_IBIG)
     433 * @param entry         TLB Entry index.
     434 * @param value         Value to be written.
     435 */
     436static inline void itlb_data_access_write(int tlb, index_t entry,
     437        uint64_t value)
     438{
     439        itlb_data_access_addr_t reg;
     440       
     441        reg.value = 0;
     442        reg.tlb_number = tlb;
     443        reg.local_tlb_entry = entry;
     444        asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
     445        flush_pipeline();
     446}
     447
     448/** Read DMMU TLB Data Access Register.
     449 *
     450 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG)
     451 * @param entry         TLB Entry index.
     452 *
     453 * @return              Current value of specified DMMU TLB Data Access
     454 *                      Register.
     455 */
     456static inline uint64_t dtlb_data_access_read(int tlb, index_t entry)
     457{
     458        dtlb_data_access_addr_t reg;
     459       
     460        reg.value = 0;
     461        reg.tlb_number = tlb;
     462        reg.local_tlb_entry = entry;
     463        return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
     464}
     465
     466/** Write DMMU TLB Data Access Register.
     467 *
     468 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) 
     469 * @param entry         TLB Entry index.
     470 * @param value         Value to be written.
     471 */
     472static inline void dtlb_data_access_write(int tlb, index_t entry,
     473        uint64_t value)
     474{
     475        dtlb_data_access_addr_t reg;
     476       
     477        reg.value = 0;
     478        reg.tlb_number = tlb;
     479        reg.local_tlb_entry = entry;
     480        asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
     481        membar();
     482}
     483
     484/** Read IMMU TLB Tag Read Register.
     485 *
     486 * @param tlb           TLB number (one of TLB_ISMALL or TLB_IBIG)
     487 * @param entry         TLB Entry index.
     488 *
     489 * @return              Current value of specified IMMU TLB Tag Read Register.
     490 */
     491static inline uint64_t itlb_tag_read_read(int tlb, index_t entry)
     492{
     493        itlb_tag_read_addr_t tag;
     494
     495        tag.value = 0;
     496        tag.tlb_number = tlb;
     497        tag.local_tlb_entry = entry;
     498        return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
     499}
     500
     501/** Read DMMU TLB Tag Read Register.
     502 *
     503 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
     504 * @param entry         TLB Entry index.
     505 *
     506 * @return              Current value of specified DMMU TLB Tag Read Register.
     507 */
     508static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry)
     509{
     510        dtlb_tag_read_addr_t tag;
     511
     512        tag.value = 0;
     513        tag.tlb_number = tlb;
     514        tag.local_tlb_entry = entry;
     515        return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
     516}
     517
     518#endif
     519
     520
    275521/** Write IMMU TLB Tag Access Register.
    276522 *
    277  * @param v Value to be written.
     523 * @param v             Value to be written.
    278524 */
    279525static inline void itlb_tag_access_write(uint64_t v)
     
    285531/** Read IMMU TLB Tag Access Register.
    286532 *
    287  * @return Current value of IMMU TLB Tag Access Register.
     533 * @return              Current value of IMMU TLB Tag Access Register.
    288534 */
    289535static inline uint64_t itlb_tag_access_read(void)
     
    294540/** Write DMMU TLB Tag Access Register.
    295541 *
    296  * @param v Value to be written.
     542 * @param v             Value to be written.
    297543 */
    298544static inline void dtlb_tag_access_write(uint64_t v)
     
    304550/** Read DMMU TLB Tag Access Register.
    305551 *
    306  * @return Current value of DMMU TLB Tag Access Register.
     552 * @return              Current value of DMMU TLB Tag Access Register.
    307553 */
    308554static inline uint64_t dtlb_tag_access_read(void)
     
    314560/** Write IMMU TLB Data in Register.
    315561 *
    316  * @param v Value to be written.
     562 * @param v             Value to be written.
    317563 */
    318564static inline void itlb_data_in_write(uint64_t v)
     
    324570/** Write DMMU TLB Data in Register.
    325571 *
    326  * @param v Value to be written.
     572 * @param v             Value to be written.
    327573 */
    328574static inline void dtlb_data_in_write(uint64_t v)
     
    334580/** Read ITLB Synchronous Fault Status Register.
    335581 *
    336  * @return Current content of I-SFSR register.
     582 * @return              Current content of I-SFSR register.
    337583 */
    338584static inline uint64_t itlb_sfsr_read(void)
     
    343589/** Write ITLB Synchronous Fault Status Register.
    344590 *
    345  * @param v New value of I-SFSR register.
     591 * @param v             New value of I-SFSR register.
    346592 */
    347593static inline void itlb_sfsr_write(uint64_t v)
     
    353599/** Read DTLB Synchronous Fault Status Register.
    354600 *
    355  * @return Current content of D-SFSR register.
     601 * @return              Current content of D-SFSR register.
    356602 */
    357603static inline uint64_t dtlb_sfsr_read(void)
     
    362608/** Write DTLB Synchronous Fault Status Register.
    363609 *
    364  * @param v New value of D-SFSR register.
     610 * @param v             New value of D-SFSR register.
    365611 */
    366612static inline void dtlb_sfsr_write(uint64_t v)
     
    372618/** Read DTLB Synchronous Fault Address Register.
    373619 *
    374  * @return Current content of D-SFAR register.
     620 * @return              Current content of D-SFAR register.
    375621 */
    376622static inline uint64_t dtlb_sfar_read(void)
     
    381627/** Perform IMMU TLB Demap Operation.
    382628 *
    383  * @param type Selects between context and page demap.
     629 * @param type          Selects between context and page demap (and entire MMU
     630 *                      demap on US3).
    384631 * @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.
     632 *                      demap.
     633 * @param page          Address which is on the page to be demapped.
    387634 */
    388635static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
     
    398645        da.vpn = pg.vpn;
    399646       
    400         asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);     /* da.value is the
    401                                                          * address within the
    402                                                          * ASI */
     647        /* da.value is the address within the ASI */
     648        asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
     649
    403650        flush_pipeline();
    404651}
     
    406653/** Perform DMMU TLB Demap Operation.
    407654 *
    408  * @param type Selects between context and page demap.
     655 * @param type          Selects between context and page demap (and entire MMU
     656 *                      demap on US3).
    409657 * @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.
     658 *                      demap.
     659 * @param page          Address which is on the page to be demapped.
    412660 */
    413661static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
     
    423671        da.vpn = pg.vpn;
    424672       
    425         asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);     /* da.value is the
    426                                                          * address within the
    427                                                          * ASI */
     673        /* da.value is the address within the ASI */
     674        asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
     675
    428676        membar();
    429677}
    430678
    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);
     679extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
     680extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
     681extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
     682
     683extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
    436684
    437685extern void dump_sfsr_and_sfar(void);
Note: See TracChangeset for help on using the changeset viewer.