Changeset 9d47440 in mainline for kernel/arch/ppc32/src/mm/tlb.c


Ignore:
Timestamp:
2011-05-21T16:23:17Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0ff03f3
Parents:
8d308b9 (diff), 13f2461 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r8d308b9 r9d47440  
    4444#include <symtab.h>
    4545
    46 static unsigned int seed = 10;
    47 static unsigned int seed_real
    48     __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
     46static unsigned int seed = 42;
    4947
    5048/** Try to find PTE for faulting address
     
    225223                switch (pfrc) {
    226224                case AS_PF_FAULT:
    227                         goto fail;
    228                         break;
     225                        page_table_unlock(as, true);
     226                        pht_refill_fail(badvaddr, istate);
     227                        return;
    229228                case AS_PF_DEFER:
    230229                        /*
     
    244243       
    245244        page_table_unlock(as, true);
    246         return;
    247        
    248 fail:
    249         page_table_unlock(as, true);
    250         pht_refill_fail(badvaddr, istate);
    251 }
    252 
    253 /** Process Instruction/Data Storage Exception in Real Mode
    254  *
    255  * @param n      Exception vector number.
    256  * @param istate Interrupted register context.
    257  *
    258  */
    259 bool pht_refill_real(unsigned int n, istate_t *istate)
    260 {
    261         uintptr_t badvaddr;
    262        
    263         if (n == VECTOR_DATA_STORAGE)
    264                 badvaddr = istate->dar;
    265         else
    266                 badvaddr = istate->pc;
    267        
    268         uint32_t physmem = physmem_top();
    269        
    270         if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
    271                 return false;
    272        
    273         uint32_t page = (badvaddr >> 12) & 0xffff;
    274         uint32_t api = (badvaddr >> 22) & 0x3f;
    275        
    276         uint32_t vsid = sr_get(badvaddr);
    277         uint32_t sdr1 = sdr1_get();
    278        
    279         // FIXME: compute size of PHT exactly
    280         phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
    281        
    282         /* Primary hash (xor) */
    283         uint32_t h = 0;
    284         uint32_t hash = vsid ^ page;
    285         uint32_t base = (hash & 0x3ff) << 3;
    286         uint32_t i;
    287         bool found = false;
    288        
    289         /* Find colliding PTE in PTEG */
    290         for (i = 0; i < 8; i++) {
    291                 if ((phte_real[base + i].v)
    292                     && (phte_real[base + i].vsid == vsid)
    293                     && (phte_real[base + i].api == api)
    294                     && (phte_real[base + i].h == 0)) {
    295                         found = true;
    296                         break;
    297                 }
    298         }
    299        
    300         if (!found) {
    301                 /* Find unused PTE in PTEG */
    302                 for (i = 0; i < 8; i++) {
    303                         if (!phte_real[base + i].v) {
    304                                 found = true;
    305                                 break;
    306                         }
    307                 }
    308         }
    309        
    310         if (!found) {
    311                 /* Secondary hash (not) */
    312                 uint32_t base2 = (~hash & 0x3ff) << 3;
    313                
    314                 /* Find colliding PTE in PTEG */
    315                 for (i = 0; i < 8; i++) {
    316                         if ((phte_real[base2 + i].v)
    317                             && (phte_real[base2 + i].vsid == vsid)
    318                             && (phte_real[base2 + i].api == api)
    319                             && (phte_real[base2 + i].h == 1)) {
    320                                 found = true;
    321                                 base = base2;
    322                                 h = 1;
    323                                 break;
    324                         }
    325                 }
    326                
    327                 if (!found) {
    328                         /* Find unused PTE in PTEG */
    329                         for (i = 0; i < 8; i++) {
    330                                 if (!phte_real[base2 + i].v) {
    331                                         found = true;
    332                                         base = base2;
    333                                         h = 1;
    334                                         break;
    335                                 }
    336                         }
    337                 }
    338                
    339                 if (!found) {
    340                         /* Use secondary hash to avoid collisions
    341                            with usual PHT refill handler. */
    342                         i = RANDI(seed_real) % 8;
    343                         base = base2;
    344                         h = 1;
    345                 }
    346         }
    347        
    348         phte_real[base + i].v = 1;
    349         phte_real[base + i].vsid = vsid;
    350         phte_real[base + i].h = h;
    351         phte_real[base + i].api = api;
    352         phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
    353         phte_real[base + i].r = 0;
    354         phte_real[base + i].c = 0;
    355         phte_real[base + i].wimg = 0;
    356         phte_real[base + i].pp = 2; // FIXME
    357        
    358         return true;
    359 }
    360 
    361 /** Process ITLB/DTLB Miss Exception in Real Mode
    362  *
    363  *
    364  */
    365 void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi,
    366     ptelo_t ptelo, istate_t *istate)
    367 {
     245}
     246
     247void tlb_refill(unsigned int n, istate_t *istate)
     248{
     249        uint32_t tlbmiss;
     250        ptehi_t ptehi;
     251        ptelo_t ptelo;
     252       
     253        asm volatile (
     254                "mfspr %[tlbmiss], 980\n"
     255                "mfspr %[ptehi], 981\n"
     256                "mfspr %[ptelo], 982\n"
     257                : [tlbmiss] "=r" (tlbmiss),
     258                  [ptehi] "=r" (ptehi),
     259                  [ptelo] "=r" (ptelo)
     260        );
     261       
    368262        uint32_t badvaddr = tlbmiss & 0xfffffffc;
    369263        uint32_t physmem = physmem_top();
Note: See TracChangeset for help on using the changeset viewer.