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


Ignore:
Timestamp:
2006-03-01T11:07:04Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9ad03fe
Parents:
2c49fbbe
Message:

ia64 work.
Provide PA2KA(identity) mapping for kernel data references via Alternate Data TLB Fault handler.
Add before_thread_runs_arch() that maps kstack, if necessary.
Add easy to use dtlb_mapping_insert() for comfortable insertion of kernel data mappings.

File:
1 edited

Legend:

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

    r2c49fbbe ra0d74fd  
    3232
    3333#include <mm/tlb.h>
     34#include <mm/asid.h>
    3435#include <arch/mm/tlb.h>
     36#include <arch/mm/page.h>
    3537#include <arch/barrier.h>
    3638#include <arch/interrupt.h>
    3739#include <typedefs.h>
    3840#include <panic.h>
     41#include <print.h>
    3942
    4043/** Invalidate all TLB entries. */
     
    8588        bool restore_rr = false;
    8689
    87         if (!(entry.not_present.p))
     90        if (!(entry.p))
    8891                return;
    8992
    90         rr.word = rr_read(VA_REGION(va));
    91         if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
     93        rr.word = rr_read(VA2VRN(va));
     94        if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
    9295                /*
    9396                 * The selected region register does not contain required RID.
     
    97100
    98101                rr0 = rr;
    99                 rr0.map.rid = ASID2RID(asid, VA_REGION(va));
    100                 rr_write(VA_REGION(va), rr0.word);
     102                rr0.map.rid = ASID2RID(asid, VA2VRN(va));
     103                rr_write(VA2VRN(va), rr0.word);
    101104                srlz_d();
    102105                srlz_i();
     
    121124       
    122125        if (restore_rr) {
    123                 rr_write(VA_REGION(va),rr.word);
     126                rr_write(VA2VRN(va), rr.word);
    124127                srlz_d();
    125128                srlz_i();
     
    164167        bool restore_rr = false;
    165168
    166         if (!(entry.not_present.p))
     169        if (!(entry.p))
    167170                return;
    168171
    169         rr.word = rr_read(VA_REGION(va));
    170         if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA_REGION(va))))) {
     172        rr.word = rr_read(VA2VRN(va));
     173        if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
    171174                /*
    172175                 * The selected region register does not contain required RID.
     
    176179
    177180                rr0 = rr;
    178                 rr0.map.rid = ASID2RID(asid, VA_REGION(va));
    179                 rr_write(VA_REGION(va), rr0.word);
     181                rr0.map.rid = ASID2RID(asid, VA2VRN(va));
     182                rr_write(VA2VRN(va), rr0.word);
    180183                srlz_d();
    181184                srlz_i();
     
    200203       
    201204        if (restore_rr) {
    202                 rr_write(VA_REGION(va),rr.word);
    203                 srlz_d();
    204                 srlz_i();
    205         }
     205                rr_write(VA2VRN(va), rr.word);
     206                srlz_d();
     207                srlz_i();
     208        }
     209}
     210
     211/** Insert data into DTLB.
     212 *
     213 * @param va Virtual page address.
     214 * @param asid Address space identifier.
     215 * @param entry The rest of TLB entry as required by TLB insertion format.
     216 * @param dtr If true, insert into data translation register, use data translation cache otherwise.
     217 * @param tr Translation register if dtr is true, ignored otherwise.
     218 */
     219void dtlb_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
     220{
     221        tlb_entry_t entry;
     222       
     223        entry.word[0] = 0;
     224        entry.word[1] = 0;
     225       
     226        entry.p = true;                 /* present */
     227        entry.ma = MA_WRITEBACK;
     228        entry.a = true;                 /* already accessed */
     229        entry.d = true;                 /* already dirty */
     230        entry.pl = PL_KERNEL;
     231        entry.ar = AR_READ | AR_WRITE;
     232        entry.ppn = frame >> PPN_SHIFT;
     233        entry.ps = PAGE_WIDTH;
     234       
     235        if (dtr)
     236                dtr_mapping_insert(page, ASID_KERNEL, entry, tr);
     237        else
     238                dtc_mapping_insert(page, ASID_KERNEL, entry);
    206239}
    207240
     
    211244}
    212245
     246/** Data TLB fault with VHPT turned off.
     247 *
     248 * @param vector Interruption vector.
     249 * @param pstate Structure with saved interruption state.
     250 */
    213251void alternate_data_tlb_fault(__u64 vector, struct exception_regdump *pstate)
    214252{
    215         panic("%s: %P\n", __FUNCTION__, pstate->cr_ifa);
     253        region_register rr;
     254        rid_t rid;
     255        __address va;
     256       
     257        va = pstate->cr_ifa;    /* faulting address */
     258        rr.word = rr_read(VA2VRN(va));
     259        rid = rr.map.rid;
     260        if (RID2ASID(rid) == ASID_KERNEL) {
     261                if (VA2VRN(va) == VRN_KERNEL) {
     262                        /*
     263                         * Provide KA2PA(identity) mapping for faulting piece of
     264                         * kernel address space.
     265                         */
     266                        dtlb_mapping_insert(va, KA2PA(va), false, 0);
     267                        return;
     268                }
     269        }
     270        panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
    216271}
    217272
Note: See TracChangeset for help on using the changeset viewer.