Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ppc32/src/mm/tlb.c

    reae4e8f r7e752b2  
    4545
    4646static unsigned int seed = 10;
    47 static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
    48 
     47static unsigned int seed_real
     48    __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
    4949
    5050/** Try to find PTE for faulting address
    5151 *
    52  * Try to find PTE for faulting address.
    53  * The as->lock must be held on entry to this function
    54  * if lock is true.
    55  *
    56  * @param as            Address space.
    57  * @param lock          Lock/unlock the address space.
    58  * @param badvaddr      Faulting virtual address.
    59  * @param access        Access mode that caused the fault.
    60  * @param istate        Pointer to interrupted state.
    61  * @param pfrc          Pointer to variable where as_page_fault() return code
    62  *                      will be stored.
    63  * @return              PTE on success, NULL otherwise.
    64  *
    65  */
    66 static pte_t *
    67 find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access,
     52 * @param as       Address space.
     53 * @param lock     Lock/unlock the address space.
     54 * @param badvaddr Faulting virtual address.
     55 * @param access   Access mode that caused the fault.
     56 * @param istate   Pointer to interrupted state.
     57 * @param pfrc     Pointer to variable where as_page_fault() return code
     58 *                 will be stored.
     59 *
     60 * @return PTE on success, NULL otherwise.
     61 *
     62 */
     63static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    6864    istate_t *istate, int *pfrc)
    6965{
     66        ASSERT(mutex_locked(&as->lock));
     67
    7068        /*
    7169         * Check if the mapping exists in page tables.
    72          */     
     70         */
    7371        pte_t *pte = page_mapping_find(as, badvaddr);
    7472        if ((pte) && (pte->present)) {
     
    7977                return pte;
    8078        } else {
    81                 int rc;
    82        
    8379                /*
    8480                 * Mapping not found in page tables.
    8581                 * Resort to higher-level page fault handler.
    8682                 */
    87                 page_table_unlock(as, lock);
    88                 switch (rc = as_page_fault(badvaddr, access, istate)) {
     83                page_table_unlock(as, true);
     84               
     85                int rc = as_page_fault(badvaddr, access, istate);
     86                switch (rc) {
    8987                case AS_PF_OK:
    9088                        /*
     
    9290                         * The mapping ought to be in place.
    9391                         */
    94                         page_table_lock(as, lock);
     92                        page_table_lock(as, true);
    9593                        pte = page_mapping_find(as, badvaddr);
    9694                        ASSERT((pte) && (pte->present));
     
    9896                        return pte;
    9997                case AS_PF_DEFER:
    100                         page_table_lock(as, lock);
     98                        page_table_lock(as, true);
    10199                        *pfrc = rc;
    102100                        return NULL;
    103101                case AS_PF_FAULT:
    104                         page_table_lock(as, lock);
     102                        page_table_lock(as, true);
    105103                        *pfrc = rc;
    106104                        return NULL;
    107105                default:
    108106                        panic("Unexpected rc (%d).", rc);
    109                 }       
    110         }
    111 }
    112 
     107                }
     108        }
     109}
    113110
    114111static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
    115112{
    116         char *symbol;
    117         char *sym2;
    118 
    119         symbol = symtab_fmt_name_lookup(istate->pc);
    120         sym2 = symtab_fmt_name_lookup(istate->lr);
    121 
    122         fault_if_from_uspace(istate,
    123             "PHT Refill Exception on %p.", badvaddr);
    124         panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
    125             istate->pc, symbol, sym2);
    126 }
    127 
     113        fault_if_from_uspace(istate, "PHT Refill Exception on %p.",
     114            (void *) badvaddr);
     115        panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr,
     116            "PHT Refill Exception.");
     117}
    128118
    129119static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
     
    132122        uint32_t api = (vaddr >> 22) & 0x3f;
    133123       
    134         uint32_t vsid;
    135         asm volatile (
    136                 "mfsrin %0, %1\n"
    137                 : "=r" (vsid)
    138                 : "r" (vaddr)
    139         );
    140        
    141         uint32_t sdr1;
    142         asm volatile (
    143                 "mfsdr1 %0\n"
    144                 : "=r" (sdr1)
    145         );
     124        uint32_t vsid = sr_get(vaddr);
     125        uint32_t sdr1 = sdr1_get();
     126       
     127        // FIXME: compute size of PHT exactly
    146128        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    147129       
     
    218200}
    219201
    220 
    221202/** Process Instruction/Data Storage Exception
    222203 *
     
    225206 *
    226207 */
    227 void pht_refill(int n, istate_t *istate)
    228 {
     208void pht_refill(unsigned int n, istate_t *istate)
     209{
     210        as_t *as = (AS == NULL) ? AS_KERNEL : AS;
    229211        uintptr_t badvaddr;
    230         pte_t *pte;
    231         int pfrc;
    232         as_t *as;
    233         bool lock;
    234        
    235         if (AS == NULL) {
    236                 as = AS_KERNEL;
    237                 lock = false;
    238         } else {
    239                 as = AS;
    240                 lock = true;
    241         }
    242212       
    243213        if (n == VECTOR_DATA_STORAGE)
     
    245215        else
    246216                badvaddr = istate->pc;
    247                
    248         page_table_lock(as, lock);
    249        
    250         pte = find_mapping_and_check(as, lock, badvaddr,
     217       
     218        page_table_lock(as, true);
     219       
     220        int pfrc;
     221        pte_t *pte = find_mapping_and_check(as, badvaddr,
    251222            PF_ACCESS_READ /* FIXME */, istate, &pfrc);
     223       
    252224        if (!pte) {
    253225                switch (pfrc) {
     
    260232                         * or copy_to_uspace().
    261233                         */
    262                         page_table_unlock(as, lock);
     234                        page_table_unlock(as, true);
    263235                        return;
    264236                default:
     
    267239        }
    268240       
    269         pte->accessed = 1; /* Record access to PTE */
     241        /* Record access to PTE */
     242        pte->accessed = 1;
    270243        pht_insert(badvaddr, pte);
    271244       
    272         page_table_unlock(as, lock);
     245        page_table_unlock(as, true);
    273246        return;
    274247       
    275248fail:
    276         page_table_unlock(as, lock);
     249        page_table_unlock(as, true);
    277250        pht_refill_fail(badvaddr, istate);
    278251}
    279 
    280252
    281253/** Process Instruction/Data Storage Exception in Real Mode
     
    285257 *
    286258 */
    287 bool pht_refill_real(int n, istate_t *istate)
     259bool pht_refill_real(unsigned int n, istate_t *istate)
    288260{
    289261        uintptr_t badvaddr;
     
    294266                badvaddr = istate->pc;
    295267       
    296         uint32_t physmem;
    297         asm volatile (
    298                 "mfsprg3 %0\n"
    299                 : "=r" (physmem)
    300         );
     268        uint32_t physmem = physmem_top();
    301269       
    302270        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    306274        uint32_t api = (badvaddr >> 22) & 0x3f;
    307275       
    308         uint32_t vsid;
    309         asm volatile (
    310                 "mfsrin %0, %1\n"
    311                 : "=r" (vsid)
    312                 : "r" (badvaddr)
    313         );
    314        
    315         uint32_t sdr1;
    316         asm volatile (
    317                 "mfsdr1 %0\n"
    318                 : "=r" (sdr1)
    319         );
     276        uint32_t vsid = sr_get(badvaddr);
     277        uint32_t sdr1 = sdr1_get();
     278       
     279        // FIXME: compute size of PHT exactly
    320280        phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
    321281       
     
    399359}
    400360
    401 
    402361/** Process ITLB/DTLB Miss Exception in Real Mode
    403362 *
    404363 *
    405364 */
    406 void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate)
     365void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi,
     366    ptelo_t ptelo, istate_t *istate)
    407367{
    408368        uint32_t badvaddr = tlbmiss & 0xfffffffc;
    409        
    410         uint32_t physmem;
    411         asm volatile (
    412                 "mfsprg3 %0\n"
    413                 : "=r" (physmem)
    414         );
     369        uint32_t physmem = physmem_top();
    415370       
    416371        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    423378        uint32_t index = 0;
    424379        asm volatile (
    425                 "mtspr 981, %0\n"
    426                 "mtspr 982, %1\n"
    427                 "tlbld %2\n"
    428                 "tlbli %2\n"
    429                 : "=r" (index)
    430                 : "r" (ptehi),
    431                   "r" (ptelo)
     380                "mtspr 981, %[ptehi]\n"
     381                "mtspr 982, %[ptelo]\n"
     382                "tlbld %[index]\n"
     383                "tlbli %[index]\n"
     384                : [index] "=r" (index)
     385                : [ptehi] "r" (ptehi),
     386                  [ptelo] "r" (ptelo)
    432387        );
    433388}
    434389
    435 
    436390void tlb_arch_init(void)
    437391{
     
    439393}
    440394
    441 
    442395void tlb_invalidate_all(void)
    443396{
    444397        uint32_t index;
     398       
    445399        asm volatile (
    446                 "li %0, 0\n"
     400                "li %[index], 0\n"
    447401                "sync\n"
    448402               
    449403                ".rept 64\n"
    450                 "tlbie %0\n"
    451                 "addi %0, %0, 0x1000\n"
     404                "       tlbie %[index]\n"
     405                "       addi %[index], %[index], 0x1000\n"
    452406                ".endr\n"
    453407               
     
    455409                "tlbsync\n"
    456410                "sync\n"
    457                 : "=r" (index)
     411                : [index] "=r" (index)
    458412        );
    459413}
    460414
    461 
    462415void tlb_invalidate_asid(asid_t asid)
    463416{
    464         uint32_t sdr1;
    465         asm volatile (
    466                 "mfsdr1 %0\n"
    467                 : "=r" (sdr1)
    468         );
     417        uint32_t sdr1 = sdr1_get();
     418       
     419        // FIXME: compute size of PHT exactly
    469420        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    470421       
    471         uint32_t i;
     422        size_t i;
    472423        for (i = 0; i < 8192; i++) {
    473424                if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) &&
     
    475426                        phte[i].v = 0;
    476427        }
     428       
    477429        tlb_invalidate_all();
    478430}
    479 
    480431
    481432void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
     
    485436}
    486437
    487 
    488438#define PRINT_BAT(name, ureg, lreg) \
    489439        asm volatile ( \
    490                 "mfspr %0," #ureg "\n" \
    491                 "mfspr %1," #lreg "\n" \
    492                 : "=r" (upper), "=r" (lower) \
     440                "mfspr %[upper], " #ureg "\n" \
     441                "mfspr %[lower], " #lreg "\n" \
     442                : [upper] "=r" (upper), \
     443                  [lower] "=r" (lower) \
    493444        ); \
     445        \
    494446        mask = (upper & 0x1ffc) >> 2; \
    495447        if (upper & 3) { \
    496448                uint32_t tmp = mask; \
    497449                length = 128; \
     450                \
    498451                while (tmp) { \
    499452                        if ((tmp & 1) == 0) { \
     
    506459        } else \
    507460                length = 0; \
    508         printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \
    509             sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \
    510             lower & 0xffff0000, length, mask, \
     461        \
     462        printf(name ": page=%#0" PRIx32 " frame=%#0" PRIx32 \
     463            " length=%#0" PRIx32 " KB (mask=%#0" PRIx32 ")%s%s\n", \
     464            upper & UINT32_C(0xffff0000), lower & UINT32_C(0xffff0000), \
     465            length, mask, \
    511466            ((upper >> 1) & 1) ? " supervisor" : "", \
    512467            (upper & 1) ? " user" : "");
    513468
    514 
    515469void tlb_print(void)
    516470{
     
    518472       
    519473        for (sr = 0; sr < 16; sr++) {
    520                 uint32_t vsid;
    521                 asm volatile (
    522                         "mfsrin %0, %1\n"
    523                         : "=r" (vsid)
    524                         : "r" (sr << 28)
    525                 );
    526                 printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
    527                     sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
     474                uint32_t vsid = sr_get(sr << 28);
     475               
     476                printf("sr[%02" PRIu32 "]: vsid=%#0" PRIx32 " (asid=%" PRIu32 ")"
     477                    "%s%s\n", sr, vsid & UINT32_C(0x00ffffff),
     478                    (vsid & UINT32_C(0x00ffffff)) >> 4,
    528479                    ((vsid >> 30) & 1) ? " supervisor" : "",
    529480                    ((vsid >> 29) & 1) ? " user" : "");
Note: See TracChangeset for help on using the changeset viewer.