Ignore:
File:
1 edited

Legend:

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

    r8f80c77 ra000878c  
    4545
    4646static unsigned int seed = 10;
    47 static unsigned int seed_real
    48     __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
     47static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
     48
    4949
    5050/** Try to find PTE for faulting address
    5151 *
    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  */
    63 static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
     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 */
     66static pte_t *
     67find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access,
    6468    istate_t *istate, int *pfrc)
    6569{
    66         ASSERT(mutex_locked(&as->lock));
    67 
    6870        /*
    6971         * Check if the mapping exists in page tables.
    70          */
     72         */     
    7173        pte_t *pte = page_mapping_find(as, badvaddr);
    7274        if ((pte) && (pte->present)) {
     
    7779                return pte;
    7880        } else {
     81                int rc;
     82       
    7983                /*
    8084                 * Mapping not found in page tables.
    8185                 * Resort to higher-level page fault handler.
    8286                 */
    83                 page_table_unlock(as, true);
    84                
    85                 int rc = as_page_fault(badvaddr, access, istate);
    86                 switch (rc) {
     87                page_table_unlock(as, lock);
     88                switch (rc = as_page_fault(badvaddr, access, istate)) {
    8789                case AS_PF_OK:
    8890                        /*
     
    9092                         * The mapping ought to be in place.
    9193                         */
    92                         page_table_lock(as, true);
     94                        page_table_lock(as, lock);
    9395                        pte = page_mapping_find(as, badvaddr);
    9496                        ASSERT((pte) && (pte->present));
     
    9698                        return pte;
    9799                case AS_PF_DEFER:
    98                         page_table_lock(as, true);
     100                        page_table_lock(as, lock);
    99101                        *pfrc = rc;
    100102                        return NULL;
    101103                case AS_PF_FAULT:
    102                         page_table_lock(as, true);
     104                        page_table_lock(as, lock);
    103105                        *pfrc = rc;
    104106                        return NULL;
    105107                default:
    106108                        panic("Unexpected rc (%d).", rc);
    107                 }
    108         }
    109 }
     109                }       
     110        }
     111}
     112
    110113
    111114static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
     
    120123}
    121124
     125
    122126static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
    123127{
     
    125129        uint32_t api = (vaddr >> 22) & 0x3f;
    126130       
    127         uint32_t vsid = sr_get(vaddr);
    128         uint32_t sdr1 = sdr1_get();
    129        
    130         // FIXME: compute size of PHT exactly
     131        uint32_t vsid;
     132        asm volatile (
     133                "mfsrin %0, %1\n"
     134                : "=r" (vsid)
     135                : "r" (vaddr)
     136        );
     137       
     138        uint32_t sdr1;
     139        asm volatile (
     140                "mfsdr1 %0\n"
     141                : "=r" (sdr1)
     142        );
    131143        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    132144       
     
    203215}
    204216
     217
    205218/** Process Instruction/Data Storage Exception
    206219 *
     
    211224void pht_refill(int n, istate_t *istate)
    212225{
    213         as_t *as = (AS == NULL) ? AS_KERNEL : AS;
    214226        uintptr_t badvaddr;
     227        pte_t *pte;
     228        int pfrc;
     229        as_t *as;
     230        bool lock;
     231       
     232        if (AS == NULL) {
     233                as = AS_KERNEL;
     234                lock = false;
     235        } else {
     236                as = AS;
     237                lock = true;
     238        }
    215239       
    216240        if (n == VECTOR_DATA_STORAGE)
     
    218242        else
    219243                badvaddr = istate->pc;
    220        
    221         page_table_lock(as, true);
    222        
    223         int pfrc;
    224         pte_t *pte = find_mapping_and_check(as, badvaddr,
     244               
     245        page_table_lock(as, lock);
     246       
     247        pte = find_mapping_and_check(as, lock, badvaddr,
    225248            PF_ACCESS_READ /* FIXME */, istate, &pfrc);
    226        
    227249        if (!pte) {
    228250                switch (pfrc) {
     
    235257                         * or copy_to_uspace().
    236258                         */
    237                         page_table_unlock(as, true);
     259                        page_table_unlock(as, lock);
    238260                        return;
    239261                default:
     
    242264        }
    243265       
    244         /* Record access to PTE */
    245         pte->accessed = 1;
     266        pte->accessed = 1; /* Record access to PTE */
    246267        pht_insert(badvaddr, pte);
    247268       
    248         page_table_unlock(as, true);
     269        page_table_unlock(as, lock);
    249270        return;
    250271       
    251272fail:
    252         page_table_unlock(as, true);
     273        page_table_unlock(as, lock);
    253274        pht_refill_fail(badvaddr, istate);
    254275}
     276
    255277
    256278/** Process Instruction/Data Storage Exception in Real Mode
     
    269291                badvaddr = istate->pc;
    270292       
    271         uint32_t physmem = physmem_top();
     293        uint32_t physmem;
     294        asm volatile (
     295                "mfsprg3 %0\n"
     296                : "=r" (physmem)
     297        );
    272298       
    273299        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    277303        uint32_t api = (badvaddr >> 22) & 0x3f;
    278304       
    279         uint32_t vsid = sr_get(badvaddr);
    280         uint32_t sdr1 = sdr1_get();
    281        
    282         // FIXME: compute size of PHT exactly
     305        uint32_t vsid;
     306        asm volatile (
     307                "mfsrin %0, %1\n"
     308                : "=r" (vsid)
     309                : "r" (badvaddr)
     310        );
     311       
     312        uint32_t sdr1;
     313        asm volatile (
     314                "mfsdr1 %0\n"
     315                : "=r" (sdr1)
     316        );
    283317        phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
    284318       
     
    362396}
    363397
     398
    364399/** Process ITLB/DTLB Miss Exception in Real Mode
    365400 *
     
    369404{
    370405        uint32_t badvaddr = tlbmiss & 0xfffffffc;
    371         uint32_t physmem = physmem_top();
     406       
     407        uint32_t physmem;
     408        asm volatile (
     409                "mfsprg3 %0\n"
     410                : "=r" (physmem)
     411        );
    372412       
    373413        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    380420        uint32_t index = 0;
    381421        asm volatile (
    382                 "mtspr 981, %[ptehi]\n"
    383                 "mtspr 982, %[ptelo]\n"
    384                 "tlbld %[index]\n"
    385                 "tlbli %[index]\n"
    386                 : [index] "=r" (index)
    387                 : [ptehi] "r" (ptehi),
    388                   [ptelo] "r" (ptelo)
    389         );
    390 }
     422                "mtspr 981, %0\n"
     423                "mtspr 982, %1\n"
     424                "tlbld %2\n"
     425                "tlbli %2\n"
     426                : "=r" (index)
     427                : "r" (ptehi),
     428                  "r" (ptelo)
     429        );
     430}
     431
    391432
    392433void tlb_arch_init(void)
     
    395436}
    396437
     438
    397439void tlb_invalidate_all(void)
    398440{
    399441        uint32_t index;
    400        
    401         asm volatile (
    402                 "li %[index], 0\n"
     442        asm volatile (
     443                "li %0, 0\n"
    403444                "sync\n"
    404445               
    405446                ".rept 64\n"
    406                 "       tlbie %[index]\n"
    407                 "       addi %[index], %[index], 0x1000\n"
     447                "tlbie %0\n"
     448                "addi %0, %0, 0x1000\n"
    408449                ".endr\n"
    409450               
     
    411452                "tlbsync\n"
    412453                "sync\n"
    413                 : [index] "=r" (index)
    414         );
    415 }
     454                : "=r" (index)
     455        );
     456}
     457
    416458
    417459void tlb_invalidate_asid(asid_t asid)
    418460{
    419         uint32_t sdr1 = sdr1_get();
    420        
    421         // FIXME: compute size of PHT exactly
     461        uint32_t sdr1;
     462        asm volatile (
     463                "mfsdr1 %0\n"
     464                : "=r" (sdr1)
     465        );
    422466        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    423467       
    424         size_t i;
     468        uint32_t i;
    425469        for (i = 0; i < 8192; i++) {
    426470                if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) &&
     
    428472                        phte[i].v = 0;
    429473        }
    430        
    431474        tlb_invalidate_all();
    432475}
     476
    433477
    434478void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
     
    438482}
    439483
     484
    440485#define PRINT_BAT(name, ureg, lreg) \
    441486        asm volatile ( \
    442                 "mfspr %[upper], " #ureg "\n" \
    443                 "mfspr %[lower], " #lreg "\n" \
    444                 : [upper] "=r" (upper), \
    445                   [lower] "=r" (lower) \
     487                "mfspr %0," #ureg "\n" \
     488                "mfspr %1," #lreg "\n" \
     489                : "=r" (upper), "=r" (lower) \
    446490        ); \
    447         \
    448491        mask = (upper & 0x1ffc) >> 2; \
    449492        if (upper & 3) { \
    450493                uint32_t tmp = mask; \
    451494                length = 128; \
    452                 \
    453495                while (tmp) { \
    454496                        if ((tmp & 1) == 0) { \
     
    461503        } else \
    462504                length = 0; \
    463         \
    464505        printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \
    465506            sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \
     
    474515       
    475516        for (sr = 0; sr < 16; sr++) {
    476                 uint32_t vsid = sr_get(sr << 28);
    477                
     517                uint32_t vsid;
     518                asm volatile (
     519                        "mfsrin %0, %1\n"
     520                        : "=r" (vsid)
     521                        : "r" (sr << 28)
     522                );
    478523                printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
    479524                    sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
Note: See TracChangeset for help on using the changeset viewer.