Ignore:
File:
1 edited

Legend:

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

    ra000878c r8f80c77  
    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)
     
    123120}
    124121
    125 
    126122static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
    127123{
     
    129125        uint32_t api = (vaddr >> 22) & 0x3f;
    130126       
    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         );
     127        uint32_t vsid = sr_get(vaddr);
     128        uint32_t sdr1 = sdr1_get();
     129       
     130        // FIXME: compute size of PHT exactly
    143131        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    144132       
     
    215203}
    216204
    217 
    218205/** Process Instruction/Data Storage Exception
    219206 *
     
    224211void pht_refill(int n, istate_t *istate)
    225212{
     213        as_t *as = (AS == NULL) ? AS_KERNEL : AS;
    226214        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         }
    239215       
    240216        if (n == VECTOR_DATA_STORAGE)
     
    242218        else
    243219                badvaddr = istate->pc;
    244                
    245         page_table_lock(as, lock);
    246        
    247         pte = find_mapping_and_check(as, lock, badvaddr,
     220       
     221        page_table_lock(as, true);
     222       
     223        int pfrc;
     224        pte_t *pte = find_mapping_and_check(as, badvaddr,
    248225            PF_ACCESS_READ /* FIXME */, istate, &pfrc);
     226       
    249227        if (!pte) {
    250228                switch (pfrc) {
     
    257235                         * or copy_to_uspace().
    258236                         */
    259                         page_table_unlock(as, lock);
     237                        page_table_unlock(as, true);
    260238                        return;
    261239                default:
     
    264242        }
    265243       
    266         pte->accessed = 1; /* Record access to PTE */
     244        /* Record access to PTE */
     245        pte->accessed = 1;
    267246        pht_insert(badvaddr, pte);
    268247       
    269         page_table_unlock(as, lock);
     248        page_table_unlock(as, true);
    270249        return;
    271250       
    272251fail:
    273         page_table_unlock(as, lock);
     252        page_table_unlock(as, true);
    274253        pht_refill_fail(badvaddr, istate);
    275254}
    276 
    277255
    278256/** Process Instruction/Data Storage Exception in Real Mode
     
    291269                badvaddr = istate->pc;
    292270       
    293         uint32_t physmem;
    294         asm volatile (
    295                 "mfsprg3 %0\n"
    296                 : "=r" (physmem)
    297         );
     271        uint32_t physmem = physmem_top();
    298272       
    299273        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    303277        uint32_t api = (badvaddr >> 22) & 0x3f;
    304278       
    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         );
     279        uint32_t vsid = sr_get(badvaddr);
     280        uint32_t sdr1 = sdr1_get();
     281       
     282        // FIXME: compute size of PHT exactly
    317283        phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
    318284       
     
    396362}
    397363
    398 
    399364/** Process ITLB/DTLB Miss Exception in Real Mode
    400365 *
     
    404369{
    405370        uint32_t badvaddr = tlbmiss & 0xfffffffc;
    406        
    407         uint32_t physmem;
    408         asm volatile (
    409                 "mfsprg3 %0\n"
    410                 : "=r" (physmem)
    411         );
     371        uint32_t physmem = physmem_top();
    412372       
    413373        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    420380        uint32_t index = 0;
    421381        asm volatile (
    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)
     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)
    429389        );
    430390}
    431391
    432 
    433392void tlb_arch_init(void)
    434393{
     
    436395}
    437396
    438 
    439397void tlb_invalidate_all(void)
    440398{
    441399        uint32_t index;
     400       
    442401        asm volatile (
    443                 "li %0, 0\n"
     402                "li %[index], 0\n"
    444403                "sync\n"
    445404               
    446405                ".rept 64\n"
    447                 "tlbie %0\n"
    448                 "addi %0, %0, 0x1000\n"
     406                "       tlbie %[index]\n"
     407                "       addi %[index], %[index], 0x1000\n"
    449408                ".endr\n"
    450409               
     
    452411                "tlbsync\n"
    453412                "sync\n"
    454                 : "=r" (index)
     413                : [index] "=r" (index)
    455414        );
    456415}
    457416
    458 
    459417void tlb_invalidate_asid(asid_t asid)
    460418{
    461         uint32_t sdr1;
    462         asm volatile (
    463                 "mfsdr1 %0\n"
    464                 : "=r" (sdr1)
    465         );
     419        uint32_t sdr1 = sdr1_get();
     420       
     421        // FIXME: compute size of PHT exactly
    466422        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    467423       
    468         uint32_t i;
     424        size_t i;
    469425        for (i = 0; i < 8192; i++) {
    470426                if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) &&
     
    472428                        phte[i].v = 0;
    473429        }
     430       
    474431        tlb_invalidate_all();
    475432}
    476 
    477433
    478434void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
     
    482438}
    483439
    484 
    485440#define PRINT_BAT(name, ureg, lreg) \
    486441        asm volatile ( \
    487                 "mfspr %0," #ureg "\n" \
    488                 "mfspr %1," #lreg "\n" \
    489                 : "=r" (upper), "=r" (lower) \
     442                "mfspr %[upper], " #ureg "\n" \
     443                "mfspr %[lower], " #lreg "\n" \
     444                : [upper] "=r" (upper), \
     445                  [lower] "=r" (lower) \
    490446        ); \
     447        \
    491448        mask = (upper & 0x1ffc) >> 2; \
    492449        if (upper & 3) { \
    493450                uint32_t tmp = mask; \
    494451                length = 128; \
     452                \
    495453                while (tmp) { \
    496454                        if ((tmp & 1) == 0) { \
     
    503461        } else \
    504462                length = 0; \
     463        \
    505464        printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \
    506465            sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \
     
    515474       
    516475        for (sr = 0; sr < 16; sr++) {
    517                 uint32_t vsid;
    518                 asm volatile (
    519                         "mfsrin %0, %1\n"
    520                         : "=r" (vsid)
    521                         : "r" (sr << 28)
    522                 );
     476                uint32_t vsid = sr_get(sr << 28);
     477               
    523478                printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
    524479                    sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
Note: See TracChangeset for help on using the changeset viewer.