Changeset 9ad03fe in mainline for arch/ia64/src/mm/tlb.c


Ignore:
Timestamp:
2006-03-01T12:58:13Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
03427d0
Parents:
a0d74fd
Message:

ia64 work.
More capable TLB miss handlers.
The ia64 kernel now passes mm/mapping1 test.

Fix generic hash table to properly initialize lists.

Change page_ht() to properly initialize inserted PTE's.
Change format of generic page hash table PTE's.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • arch/ia64/src/mm/tlb.c

    ra0d74fd r9ad03fe  
    3333#include <mm/tlb.h>
    3434#include <mm/asid.h>
     35#include <mm/page.h>
     36#include <mm/as.h>
    3537#include <arch/mm/tlb.h>
    3638#include <arch/mm/page.h>
     
    3941#include <typedefs.h>
    4042#include <panic.h>
    41 #include <print.h>
     43#include <arch.h>
    4244
    4345/** Invalidate all TLB entries. */
     
    8789        region_register rr;
    8890        bool restore_rr = false;
    89 
    90         if (!(entry.p))
    91                 return;
    9291
    9392        rr.word = rr_read(VA2VRN(va));
     
    167166        bool restore_rr = false;
    168167
    169         if (!(entry.p))
    170                 return;
    171 
    172168        rr.word = rr_read(VA2VRN(va));
    173169        if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
     
    217213 * @param tr Translation register if dtr is true, ignored otherwise.
    218214 */
    219 void dtlb_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
     215void dtlb_kernel_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
    220216{
    221217        tlb_entry_t entry;
     
    239235}
    240236
     237/** Copy content of PTE into data translation cache.
     238 *
     239 * @param t PTE.
     240 */
     241void dtc_pte_copy(pte_t *t)
     242{
     243        tlb_entry_t entry;
     244
     245        entry.word[0] = 0;
     246        entry.word[1] = 0;
     247       
     248        entry.p = t->p;
     249        entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
     250        entry.a = t->a;
     251        entry.d = t->d;
     252        entry.pl = t->k ? PL_KERNEL : PL_USER;
     253        entry.ar = t->w ? AR_WRITE : AR_READ;
     254        entry.ppn = t->frame >> PPN_SHIFT;
     255        entry.ps = PAGE_WIDTH;
     256       
     257        dtc_mapping_insert(t->page, t->as->asid, entry);
     258}
     259
     260/** Copy content of PTE into instruction translation cache.
     261 *
     262 * @param t PTE.
     263 */
     264void itc_pte_copy(pte_t *t)
     265{
     266        tlb_entry_t entry;
     267
     268        entry.word[0] = 0;
     269        entry.word[1] = 0;
     270       
     271        ASSERT(t->x);
     272       
     273        entry.p = t->p;
     274        entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
     275        entry.a = t->a;
     276        entry.pl = t->k ? PL_KERNEL : PL_USER;
     277        entry.ar = t->x ? (AR_EXECUTE | AR_READ) : AR_READ;
     278        entry.ppn = t->frame >> PPN_SHIFT;
     279        entry.ps = PAGE_WIDTH;
     280       
     281        itc_mapping_insert(t->page, t->as->asid, entry);
     282}
     283
     284/** Instruction TLB fault handler for faults with VHPT turned off.
     285 *
     286 * @param vector Interruption vector.
     287 * @param pstate Structure with saved interruption state.
     288 */
    241289void alternate_instruction_tlb_fault(__u64 vector, struct exception_regdump *pstate)
    242290{
    243         panic("%s\n", __FUNCTION__);
    244 }
    245 
    246 /** Data TLB fault with VHPT turned off.
     291        region_register rr;
     292        __address va;
     293        pte_t *t;
     294       
     295        va = pstate->cr_ifa;    /* faulting address */
     296        t = page_mapping_find(AS, va);
     297        if (t) {
     298                /*
     299                 * The mapping was found in software page hash table.
     300                 * Insert it into data translation cache.
     301                 */
     302                itc_pte_copy(t);
     303        } else {
     304                /*
     305                 * Forward the page fault to address space page fault handler.
     306                 */
     307                if (!as_page_fault(va)) {
     308                        panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
     309                }
     310        }
     311}
     312
     313/** Data TLB fault handler for faults with VHPT turned off.
    247314 *
    248315 * @param vector Interruption vector.
     
    254321        rid_t rid;
    255322        __address va;
     323        pte_t *t;
    256324       
    257325        va = pstate->cr_ifa;    /* faulting address */
     
    264332                         * kernel address space.
    265333                         */
    266                         dtlb_mapping_insert(va, KA2PA(va), false, 0);
     334                        dtlb_kernel_mapping_insert(va, KA2PA(va), false, 0);
    267335                        return;
    268336                }
    269337        }
    270         panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
    271 }
    272 
     338       
     339        t = page_mapping_find(AS, va);
     340        if (t) {
     341                /*
     342                 * The mapping was found in software page hash table.
     343                 * Insert it into data translation cache.
     344                 */
     345                dtc_pte_copy(t);
     346        } else {
     347                /*
     348                 * Forward the page fault to address space page fault handler.
     349                 */
     350                if (!as_page_fault(va)) {
     351                        panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
     352                }
     353        }
     354}
     355
     356/** Data nested TLB fault handler.
     357 *
     358 * This fault should not occur.
     359 *
     360 * @param vector Interruption vector.
     361 * @param pstate Structure with saved interruption state.
     362 */
    273363void data_nested_tlb_fault(__u64 vector, struct exception_regdump *pstate)
    274364{
     
    276366}
    277367
     368/** Data Dirty bit fault handler.
     369 *
     370 * @param vector Interruption vector.
     371 * @param pstate Structure with saved interruption state.
     372 */
    278373void data_dirty_bit_fault(__u64 vector, struct exception_regdump *pstate)
    279374{
    280         panic("%s\n", __FUNCTION__);
    281 }
    282 
     375        pte_t *t;
     376
     377        t = page_mapping_find(AS, pstate->cr_ifa);
     378        ASSERT(t && t->p);
     379        if (t && t->p) {
     380                /*
     381                 * Update the Dirty bit in page tables and reinsert
     382                 * the mapping into DTC.
     383                 */
     384                t->d = true;
     385                dtc_pte_copy(t);
     386        }
     387}
     388
     389/** Instruction access bit fault handler.
     390 *
     391 * @param vector Interruption vector.
     392 * @param pstate Structure with saved interruption state.
     393 */
    283394void instruction_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
    284395{
    285         panic("%s\n", __FUNCTION__);
    286 }
    287 
     396        pte_t *t;
     397
     398        t = page_mapping_find(AS, pstate->cr_ifa);
     399        ASSERT(t && t->p);
     400        if (t && t->p) {
     401                /*
     402                 * Update the Accessed bit in page tables and reinsert
     403                 * the mapping into ITC.
     404                 */
     405                t->a = true;
     406                itc_pte_copy(t);
     407        }
     408}
     409
     410/** Data access bit fault handler.
     411 *
     412 * @param vector Interruption vector.
     413 * @param pstate Structure with saved interruption state.
     414 */
    288415void data_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
    289416{
    290         panic("%s\n", __FUNCTION__);
    291 }
    292 
     417        pte_t *t;
     418
     419        t = page_mapping_find(AS, pstate->cr_ifa);
     420        ASSERT(t && t->p);
     421        if (t && t->p) {
     422                /*
     423                 * Update the Accessed bit in page tables and reinsert
     424                 * the mapping into DTC.
     425                 */
     426                t->a = true;
     427                dtc_pte_copy(t);
     428        }
     429}
     430
     431/** Page not present fault handler.
     432 *
     433 * @param vector Interruption vector.
     434 * @param pstate Structure with saved interruption state.
     435 */
    293436void page_not_present(__u64 vector, struct exception_regdump *pstate)
    294437{
    295         panic("%s\n", __FUNCTION__);
    296 }
     438        region_register rr;
     439        __address va;
     440        pte_t *t;
     441       
     442        va = pstate->cr_ifa;    /* faulting address */
     443        t = page_mapping_find(AS, va);
     444        ASSERT(t);
     445       
     446        if (t->p) {
     447                /*
     448                 * If the Present bit is set in page hash table, just copy it
     449                 * and update ITC/DTC.
     450                 */
     451                if (t->x)
     452                        itc_pte_copy(t);
     453                else
     454                        dtc_pte_copy(t);
     455        } else {
     456                if (!as_page_fault(va)) {
     457                        panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
     458                }
     459        }
     460}
Note: See TracChangeset for help on using the changeset viewer.