Changeset 965dc18 in mainline for kernel/arch/sparc64/src/mm


Ignore:
Timestamp:
2008-12-05T19:59:03Z (17 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.

Location:
kernel/arch/sparc64/src/mm
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/src/mm/as.c

    r0258e67 r965dc18  
    165165        tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH;
    166166        dtsb_base_write(tsb_base.value);
     167       
     168#if defined (US3)
     169        /*
     170         * Clear the extension registers.
     171         * In HelenOS, primary and secondary context registers contain
     172         * equal values and kernel misses (context 0, ie. the nucleus context)
     173         * are excluded from the TSB miss handler, so it makes no sense
     174         * to have separate TSBs for primary, secondary and nucleus contexts.
     175         * Clearing the extension registers will ensure that the value of the
     176         * TSB Base register will be used as an address of TSB, making the code
     177         * compatible with the US port.
     178         */
     179        itsb_primary_extension_write(0);
     180        itsb_nucleus_extension_write(0);
     181        dtsb_primary_extension_write(0);
     182        dtsb_secondary_extension_write(0);
     183        dtsb_nucleus_extension_write(0);
     184#endif
    167185#endif
    168186}
  • kernel/arch/sparc64/src/mm/cache.S

    r0258e67 r965dc18  
    4848        ! beware SF Erratum #51, do not put the MEMBAR here
    4949        nop                             
    50 
    51 /** Flush only D-cache lines of one virtual color.
    52  *
    53  * @param o0    Virtual color to be flushed.
    54  */
    55 .global dcache_flush_color
    56 dcache_flush_color:
    57         mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
    58         set DCACHE_SIZE / 2, %g2
    59         sllx %g2, %o0, %g2
    60         sub %g2, DCACHE_LINE_SIZE, %g2
    61 0:      stxa %g0, [%g2] ASI_DCACHE_TAG
    62         membar #Sync
    63         subcc %g1, 1, %g1
    64         bnz,pt %xcc, 0b
    65         sub %g2, DCACHE_LINE_SIZE, %g2
    66         retl
    67         nop
    68 
    69 /** Flush only D-cache lines of one virtual color and one tag.
    70  *
    71  * @param o0    Virtual color to lookup the tag.
    72  * @param o1    Tag of the cachelines to be flushed.
    73  */
    74 .global dcache_flush_tag
    75 dcache_flush_tag:
    76         mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
    77         set DCACHE_SIZE / 2, %g2
    78         sllx %g2, %o0, %g2
    79         sub %g2, DCACHE_LINE_SIZE, %g2
    80 0:      ldxa [%g2] ASI_DCACHE_TAG, %g3
    81         srlx %g3, DCACHE_TAG_SHIFT, %g3
    82         cmp %g3, %o1
    83         bnz 1f
    84         nop
    85         stxa %g0, [%g2] ASI_DCACHE_TAG
    86         membar #Sync
    87 1:      subcc %g1, 1, %g1
    88         bnz,pt %xcc, 0b
    89         sub %g2, DCACHE_LINE_SIZE, %g2
    90         retl
    91         nop
  • kernel/arch/sparc64/src/mm/page.c

    r0258e67 r965dc18  
    5353        uintptr_t phys_page;
    5454        int pagesize_code;
    55 } bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT];
     55} bsp_locked_dtlb_entry[DTLB_MAX_LOCKED_ENTRIES];
    5656
    5757/** Number of entries in bsp_locked_dtlb_entry array. */
     
    167167/** @}
    168168 */
     169
  • kernel/arch/sparc64/src/mm/tlb.c

    r0258e67 r965dc18  
    5555#endif
    5656
    57 static void dtlb_pte_copy(pte_t *t, index_t index, bool ro);
    58 static void itlb_pte_copy(pte_t *t, index_t index);
    59 static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
    60     const char *str);
    61 static void do_fast_data_access_mmu_miss_fault(istate_t *istate,
    62     tlb_tag_access_reg_t tag, const char *str);
    63 static void do_fast_data_access_protection_fault(istate_t *istate,
    64     tlb_tag_access_reg_t tag, const char *str);
     57static void dtlb_pte_copy(pte_t *, index_t, bool);
     58static void itlb_pte_copy(pte_t *, index_t);
     59static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
     60static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
     61    const char *);
     62static void do_fast_data_access_protection_fault(istate_t *,
     63    tlb_tag_access_reg_t, const char *);
    6564
    6665char *context_encoding[] = {
     
    8786/** Insert privileged mapping into DMMU TLB.
    8887 *
    89  * @param page Virtual page address.
    90  * @param frame Physical frame address.
    91  * @param pagesize Page size.
    92  * @param locked True for permanent mappings, false otherwise.
    93  * @param cacheable True if the mapping is cacheable, false otherwise.
     88 * @param page          Virtual page address.
     89 * @param frame         Physical frame address.
     90 * @param pagesize      Page size.
     91 * @param locked        True for permanent mappings, false otherwise.
     92 * @param cacheable     True if the mapping is cacheable, false otherwise.
    9493 */
    9594void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
     
    104103        fr.address = frame;
    105104
    106         tag.value = ASID_KERNEL;
     105        tag.context = ASID_KERNEL;
    107106        tag.vpn = pg.vpn;
    108107
     
    127126/** Copy PTE to TLB.
    128127 *
    129  * @param t     Page Table Entry to be copied.
    130  * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
    131  * @param ro    If true, the entry will be created read-only, regardless of its
    132  *              w field.
     128 * @param t             Page Table Entry to be copied.
     129 * @param index         Zero if lower 8K-subpage, one if higher 8K-subpage.
     130 * @param ro            If true, the entry will be created read-only, regardless
     131 *                      of its w field.
    133132 */
    134133void dtlb_pte_copy(pte_t *t, index_t index, bool ro)
     
    166165/** Copy PTE to ITLB.
    167166 *
    168  * @param t     Page Table Entry to be copied.
    169  * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
     167 * @param t             Page Table Entry to be copied.
     168 * @param index         Zero if lower 8K-subpage, one if higher 8K-subpage.
    170169 */
    171170void itlb_pte_copy(pte_t *t, index_t index)
     
    236235 * low-level, assembly language part of the fast_data_access_mmu_miss handler.
    237236 *
    238  * @param tag Content of the TLB Tag Access register as it existed when the
    239  *    trap happened. This is to prevent confusion created by clobbered
    240  *    Tag Access register during a nested DTLB miss.
    241  * @param istate Interrupted state saved on the stack.
     237 * @param tag           Content of the TLB Tag Access register as it existed
     238 *                      when the trap happened. This is to prevent confusion
     239 *                      created by clobbered Tag Access register during a nested
     240 *                      DTLB miss.
     241 * @param istate        Interrupted state saved on the stack.
    242242 */
    243243void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
     
    288288/** DTLB protection fault handler.
    289289 *
    290  * @param tag Content of the TLB Tag Access register as it existed when the
    291  *    trap happened. This is to prevent confusion created by clobbered
    292  *    Tag Access register during a nested DTLB miss.
    293  * @param istate Interrupted state saved on the stack.
     290 * @param tag           Content of the TLB Tag Access register as it existed
     291 *                      when the trap happened. This is to prevent confusion
     292 *                      created by clobbered Tag Access register during a nested
     293 *                      DTLB miss.
     294 * @param istate        Interrupted state saved on the stack.
    294295 */
    295296void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
     
    332333}
    333334
     335/** Print TLB entry (for debugging purposes).
     336 *
     337 * The diag field has been left out in order to make this function more generic
     338 * (there is no diag field in US3 architeture).
     339 *
     340 * @param i             TLB entry number
     341 * @param t             TLB entry tag
     342 * @param d             TLB entry data
     343 */
     344static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
     345{
     346        printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
     347            "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
     348            "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
     349            t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
     350            d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
     351}
     352
     353#if defined (US)
     354
    334355/** Print contents of both TLBs. */
    335356void tlb_print(void)
     
    343364                d.value = itlb_data_access_read(i);
    344365                t.value = itlb_tag_read_read(i);
    345 
    346                 printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
    347                     "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
    348                     "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
    349                     t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
    350                     d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
     366                print_tlb_entry(i, t, d);
    351367        }
    352368
     
    355371                d.value = dtlb_data_access_read(i);
    356372                t.value = dtlb_tag_read_read(i);
    357                
    358                 printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
    359                     "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
    360                     "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
    361                     t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
    362                     d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
    363         }
    364 
    365 }
     373                print_tlb_entry(i, t, d);
     374        }
     375}
     376
     377#elif defined (US3)
     378
     379/** Print contents of all TLBs. */
     380void tlb_print(void)
     381{
     382        int i;
     383        tlb_data_t d;
     384        tlb_tag_read_reg_t t;
     385       
     386        printf("TLB_ISMALL contents:\n");
     387        for (i = 0; i < tlb_ismall_size(); i++) {
     388                d.value = dtlb_data_access_read(TLB_ISMALL, i);
     389                t.value = dtlb_tag_read_read(TLB_ISMALL, i);
     390                print_tlb_entry(i, t, d);
     391        }
     392       
     393        printf("TLB_IBIG contents:\n");
     394        for (i = 0; i < tlb_ibig_size(); i++) {
     395                d.value = dtlb_data_access_read(TLB_IBIG, i);
     396                t.value = dtlb_tag_read_read(TLB_IBIG, i);
     397                print_tlb_entry(i, t, d);
     398        }
     399       
     400        printf("TLB_DSMALL contents:\n");
     401        for (i = 0; i < tlb_dsmall_size(); i++) {
     402                d.value = dtlb_data_access_read(TLB_DSMALL, i);
     403                t.value = dtlb_tag_read_read(TLB_DSMALL, i);
     404                print_tlb_entry(i, t, d);
     405        }
     406       
     407        printf("TLB_DBIG_1 contents:\n");
     408        for (i = 0; i < tlb_dbig_size(); i++) {
     409                d.value = dtlb_data_access_read(TLB_DBIG_0, i);
     410                t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
     411                print_tlb_entry(i, t, d);
     412        }
     413       
     414        printf("TLB_DBIG_2 contents:\n");
     415        for (i = 0; i < tlb_dbig_size(); i++) {
     416                d.value = dtlb_data_access_read(TLB_DBIG_1, i);
     417                t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
     418                print_tlb_entry(i, t, d);
     419        }
     420}
     421
     422#endif
    366423
    367424void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
     
    412469        sfar = dtlb_sfar_read();
    413470       
     471#if defined (US)
    414472        printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
    415473            "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
    416474            sfsr.ow, sfsr.fv);
     475#elif defined (US3)
     476        printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
     477            "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
     478            sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
     479#endif
     480           
    417481        printf("DTLB SFAR: address=%p\n", sfar);
    418482       
    419483        dtlb_sfsr_write(0);
    420484}
     485
     486#if defined (US3)
     487/** Invalidates given TLB entry if and only if it is non-locked or global.
     488 *
     489 * @param tlb           TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1,
     490 *                      TLB_ISMALL, TLB_IBIG).
     491 * @param entry         Entry index within the given TLB.
     492 */
     493static void tlb_invalidate_entry(int tlb, index_t entry)
     494{
     495        tlb_data_t d;
     496        tlb_tag_read_reg_t t;
     497       
     498        if (tlb == TLB_DSMALL || tlb == TLB_DBIG_0 || tlb == TLB_DBIG_1) {
     499                d.value = dtlb_data_access_read(tlb, entry);
     500                if (!d.l || d.g) {
     501                        t.value = dtlb_tag_read_read(tlb, entry);
     502                        d.v = false;
     503                        dtlb_tag_access_write(t.value);
     504                        dtlb_data_access_write(tlb, entry, d.value);
     505                }
     506        } else if (tlb == TLB_ISMALL || tlb == TLB_IBIG) {
     507                d.value = itlb_data_access_read(tlb, entry);
     508                if (!d.l || d.g) {
     509                        t.value = itlb_tag_read_read(tlb, entry);
     510                        d.v = false;
     511                        itlb_tag_access_write(t.value);
     512                        itlb_data_access_write(tlb, entry, d.value);
     513                }
     514        }
     515}
     516#endif
    421517
    422518/** Invalidate all unlocked ITLB and DTLB entries. */
     
    424520{
    425521        int i;
    426         tlb_data_t d;
    427         tlb_tag_read_reg_t t;
    428 
     522       
    429523        /*
    430524         * Walk all ITLB and DTLB entries and remove all unlocked mappings.
    431525         *
    432526         * The kernel doesn't use global mappings so any locked global mappings
    433          * found  must have been created by someone else. Their only purpose now
     527         * found must have been created by someone else. Their only purpose now
    434528         * is to collide with proper mappings. Invalidate immediately. It should
    435529         * be safe to invalidate them as late as now.
    436530         */
     531
     532#if defined (US)
     533        tlb_data_t d;
     534        tlb_tag_read_reg_t t;
    437535
    438536        for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
     
    445543                }
    446544        }
    447        
     545
    448546        for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
    449547                d.value = dtlb_data_access_read(i);
     
    455553                }
    456554        }
    457        
     555
     556#elif defined (US3)
     557
     558        for (i = 0; i < tlb_ismall_size(); i++)
     559                tlb_invalidate_entry(TLB_ISMALL, i);
     560        for (i = 0; i < tlb_ibig_size(); i++)
     561                tlb_invalidate_entry(TLB_IBIG, i);
     562        for (i = 0; i < tlb_dsmall_size(); i++)
     563                tlb_invalidate_entry(TLB_DSMALL, i);
     564        for (i = 0; i < tlb_dbig_size(); i++)
     565                tlb_invalidate_entry(TLB_DBIG_0, i);
     566        for (i = 0; i < tlb_dbig_size(); i++)
     567                tlb_invalidate_entry(TLB_DBIG_1, i);
     568#endif
     569
    458570}
    459571
     
    485597 * address space.
    486598 *
    487  * @param asid Address Space ID.
    488  * @param page First page which to sweep out from ITLB and DTLB.
    489  * @param cnt Number of ITLB and DTLB entries to invalidate.
     599 * @param asid          Address Space ID.
     600 * @param page          First page which to sweep out from ITLB and DTLB.
     601 * @param cnt           Number of ITLB and DTLB entries to invalidate.
    490602 */
    491603void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
  • kernel/arch/sparc64/src/mm/tsb.c

    r0258e67 r965dc18  
    113113        tsb->data.size = PAGESIZE_8K;
    114114        tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
    115         tsb->data.cp = t->c;
    116         tsb->data.p = t->k;             /* p as privileged */
    117         tsb->data.v = t->p;
     115        tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
     116        tsb->data.p = t->k;     /* p as privileged, k as kernel */
     117        tsb->data.v = t->p;     /* v as valid, p as present */
    118118       
    119119        write_barrier();
     
    174174/** @}
    175175 */
     176
Note: See TracChangeset for help on using the changeset viewer.