Ignore:
File:
1 edited

Legend:

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

    ra000878c rc15b374  
    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         const char *symbol = symtab_fmt_name_lookup(istate->pc);
    117         const char *sym2 = symtab_fmt_name_lookup(istate->lr);
    118        
    119         fault_if_from_uspace(istate,
    120             "PHT Refill Exception on %p.", badvaddr);
    121         panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
    122             istate->pc, symbol, sym2);
    123 }
    124 
     113        fault_if_from_uspace(istate, "PHT Refill Exception on %p.", badvaddr);
     114        panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr,
     115            "PHT Refill Exception.");
     116}
    125117
    126118static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
     
    129121        uint32_t api = (vaddr >> 22) & 0x3f;
    130122       
    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         );
     123        uint32_t vsid = sr_get(vaddr);
     124        uint32_t sdr1 = sdr1_get();
     125       
     126        // FIXME: compute size of PHT exactly
    143127        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    144128       
     
    215199}
    216200
    217 
    218201/** Process Instruction/Data Storage Exception
    219202 *
     
    222205 *
    223206 */
    224 void pht_refill(int n, istate_t *istate)
    225 {
     207void pht_refill(unsigned int n, istate_t *istate)
     208{
     209        as_t *as = (AS == NULL) ? AS_KERNEL : AS;
    226210        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         }
    239211       
    240212        if (n == VECTOR_DATA_STORAGE)
     
    242214        else
    243215                badvaddr = istate->pc;
    244                
    245         page_table_lock(as, lock);
    246        
    247         pte = find_mapping_and_check(as, lock, badvaddr,
     216       
     217        page_table_lock(as, true);
     218       
     219        int pfrc;
     220        pte_t *pte = find_mapping_and_check(as, badvaddr,
    248221            PF_ACCESS_READ /* FIXME */, istate, &pfrc);
     222       
    249223        if (!pte) {
    250224                switch (pfrc) {
     
    257231                         * or copy_to_uspace().
    258232                         */
    259                         page_table_unlock(as, lock);
     233                        page_table_unlock(as, true);
    260234                        return;
    261235                default:
     
    264238        }
    265239       
    266         pte->accessed = 1; /* Record access to PTE */
     240        /* Record access to PTE */
     241        pte->accessed = 1;
    267242        pht_insert(badvaddr, pte);
    268243       
    269         page_table_unlock(as, lock);
     244        page_table_unlock(as, true);
    270245        return;
    271246       
    272247fail:
    273         page_table_unlock(as, lock);
     248        page_table_unlock(as, true);
    274249        pht_refill_fail(badvaddr, istate);
    275250}
    276 
    277251
    278252/** Process Instruction/Data Storage Exception in Real Mode
     
    282256 *
    283257 */
    284 bool pht_refill_real(int n, istate_t *istate)
     258bool pht_refill_real(unsigned int n, istate_t *istate)
    285259{
    286260        uintptr_t badvaddr;
     
    291265                badvaddr = istate->pc;
    292266       
    293         uint32_t physmem;
    294         asm volatile (
    295                 "mfsprg3 %0\n"
    296                 : "=r" (physmem)
    297         );
     267        uint32_t physmem = physmem_top();
    298268       
    299269        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    303273        uint32_t api = (badvaddr >> 22) & 0x3f;
    304274       
    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         );
     275        uint32_t vsid = sr_get(badvaddr);
     276        uint32_t sdr1 = sdr1_get();
     277       
     278        // FIXME: compute size of PHT exactly
    317279        phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
    318280       
     
    396358}
    397359
    398 
    399360/** Process ITLB/DTLB Miss Exception in Real Mode
    400361 *
    401362 *
    402363 */
    403 void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate)
     364void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi,
     365    ptelo_t ptelo, istate_t *istate)
    404366{
    405367        uint32_t badvaddr = tlbmiss & 0xfffffffc;
    406        
    407         uint32_t physmem;
    408         asm volatile (
    409                 "mfsprg3 %0\n"
    410                 : "=r" (physmem)
    411         );
     368        uint32_t physmem = physmem_top();
    412369       
    413370        if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
     
    420377        uint32_t index = 0;
    421378        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)
     379                "mtspr 981, %[ptehi]\n"
     380                "mtspr 982, %[ptelo]\n"
     381                "tlbld %[index]\n"
     382                "tlbli %[index]\n"
     383                : [index] "=r" (index)
     384                : [ptehi] "r" (ptehi),
     385                  [ptelo] "r" (ptelo)
    429386        );
    430387}
    431388
    432 
    433389void tlb_arch_init(void)
    434390{
     
    436392}
    437393
    438 
    439394void tlb_invalidate_all(void)
    440395{
    441396        uint32_t index;
     397       
    442398        asm volatile (
    443                 "li %0, 0\n"
     399                "li %[index], 0\n"
    444400                "sync\n"
    445401               
    446402                ".rept 64\n"
    447                 "tlbie %0\n"
    448                 "addi %0, %0, 0x1000\n"
     403                "       tlbie %[index]\n"
     404                "       addi %[index], %[index], 0x1000\n"
    449405                ".endr\n"
    450406               
     
    452408                "tlbsync\n"
    453409                "sync\n"
    454                 : "=r" (index)
     410                : [index] "=r" (index)
    455411        );
    456412}
    457413
    458 
    459414void tlb_invalidate_asid(asid_t asid)
    460415{
    461         uint32_t sdr1;
    462         asm volatile (
    463                 "mfsdr1 %0\n"
    464                 : "=r" (sdr1)
    465         );
     416        uint32_t sdr1 = sdr1_get();
     417       
     418        // FIXME: compute size of PHT exactly
    466419        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    467420       
    468         uint32_t i;
     421        size_t i;
    469422        for (i = 0; i < 8192; i++) {
    470423                if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) &&
     
    472425                        phte[i].v = 0;
    473426        }
     427       
    474428        tlb_invalidate_all();
    475429}
    476 
    477430
    478431void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
     
    482435}
    483436
    484 
    485437#define PRINT_BAT(name, ureg, lreg) \
    486438        asm volatile ( \
    487                 "mfspr %0," #ureg "\n" \
    488                 "mfspr %1," #lreg "\n" \
    489                 : "=r" (upper), "=r" (lower) \
     439                "mfspr %[upper], " #ureg "\n" \
     440                "mfspr %[lower], " #lreg "\n" \
     441                : [upper] "=r" (upper), \
     442                  [lower] "=r" (lower) \
    490443        ); \
     444        \
    491445        mask = (upper & 0x1ffc) >> 2; \
    492446        if (upper & 3) { \
    493447                uint32_t tmp = mask; \
    494448                length = 128; \
     449                \
    495450                while (tmp) { \
    496451                        if ((tmp & 1) == 0) { \
     
    503458        } else \
    504459                length = 0; \
     460        \
    505461        printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \
    506462            sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \
     
    515471       
    516472        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                 );
     473                uint32_t vsid = sr_get(sr << 28);
     474               
    523475                printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
    524476                    sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
Note: See TracChangeset for help on using the changeset viewer.