Changeset 10e0cee in mainline


Ignore:
Timestamp:
2006-06-18T00:31:14Z (19 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1bb2e7a
Parents:
8e3bf3e2
Message:

ppc32: BAT-less memory mapping (broken yet)
VSID support (broken yet)
boot API change
cleanup

Location:
arch/ppc32
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • arch/ppc32/Makefile.inc

    r8e3bf3e2 r10e0cee  
    5656DEFS += -DCONFIG_PAGE_PT
    5757
     58## Compile with support for address space identifiers.
     59#
     60
     61CONFIG_ASID = y
     62CONFIG_ASID_FIFO = y
     63
    5864## Compile with support for software integer division.
    5965#
  • arch/ppc32/include/arch.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32 
     29/** @addtogroup ppc32   
    3030 * @{
    3131 */
     
    4040#endif
    4141
    42  /** @}
     42/** @}
    4343 */
    44 
  • arch/ppc32/include/boot/boot.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32 
     29/** @addtogroup ppc32   
    3030 * @{
    3131 */
     
    8383
    8484typedef struct {
     85        memmap_t memmap;
    8586        taskmap_t taskmap;
    86         memmap_t memmap;
    8787        screen_t screen;
    8888        keyboard_t keyboard;
     
    9595#endif
    9696
    97  /** @}
     97/** @}
    9898 */
    99 
  • arch/ppc32/include/exception.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32 
     29/** @addtogroup ppc32   
    3030 * @{
    3131 */
     
    101101#endif
    102102
    103  /** @}
     103/** @}
    104104 */
    105 
  • arch/ppc32/include/interrupt.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32interrupt
     29/** @addtogroup ppc32interrupt
    3030 * @{
    3131 */
     
    5757#endif
    5858
    59  /** @}
     59/** @}
    6060 */
    61 
  • arch/ppc32/include/mm/as.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    4545#define USTACK_ADDRESS_ARCH     (0x7fffffff-(PAGE_SIZE-1))
    4646
    47 #define as_install_arch(as)
    48 
    4947extern void as_arch_init(void);
    5048
    5149#endif
    5250
    53  /** @}
     51/** @}
    5452 */
    55 
  • arch/ppc32/include/mm/asid.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    3636#define __ppc32_ASID_H__
    3737
    38 typedef int asid_t;
     38#include <arch/types.h>
    3939
    40 #define ASID_MAX_ARCH           3
     40#define ASID_MAX_ARCH           4096
    4141
    42 #define asid_get()              (ASID_START+1)
    43 #define asid_put(asid)
     42typedef __u32 asid_t;
    4443
    4544#endif
    4645
    47  /** @}
     46/** @}
    4847 */
    49 
  • arch/ppc32/include/mm/frame.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    5353#endif
    5454
    55  /** @}
     55/** @}
    5656 */
    57 
  • arch/ppc32/include/mm/memory_init.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    4444#endif
    4545
    46  /** @}
     46/** @}
    4747 */
    48 
  • arch/ppc32/include/mm/page.h

    r8e3bf3e2 r10e0cee  
    133133extern void page_arch_init(void);
    134134
    135 typedef struct {
    136         unsigned v : 1;          /**< Valid */
    137         unsigned vsid : 24;      /**< Virtual Segment ID */
    138         unsigned h : 1;          /**< Primary/secondary hash */
    139         unsigned api : 6;        /**< Abbreviated Page Index */
    140         unsigned rpn : 20;       /**< Real Page Number */
    141         unsigned reserved0 : 3;
    142         unsigned r : 1;          /**< Reference */
    143         unsigned c : 1;          /**< Change */
    144         unsigned wimg : 4;       /**< Access control */
    145         unsigned reserved1 : 1;
    146         unsigned pp : 2;         /**< Page protection */
    147 } phte_t;
    148 
    149 extern void pht_refill(int n, istate_t *istate);
    150 extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
    151 extern void pht_init(void);
    152 
    153135#endif /* __ASM__ */
    154136
  • arch/ppc32/include/mm/tlb.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    3636#define __ppc32_TLB_H__
    3737
     38typedef struct {
     39        unsigned v : 1;          /**< Valid */
     40        unsigned vsid : 24;      /**< Virtual Segment ID */
     41        unsigned h : 1;          /**< Primary/secondary hash */
     42        unsigned api : 6;        /**< Abbreviated Page Index */
     43        unsigned rpn : 20;       /**< Real Page Number */
     44        unsigned reserved0 : 3;
     45        unsigned r : 1;          /**< Reference */
     46        unsigned c : 1;          /**< Change */
     47        unsigned wimg : 4;       /**< Access control */
     48        unsigned reserved1 : 1;
     49        unsigned pp : 2;         /**< Page protection */
     50} phte_t;
     51
     52extern void pht_refill(int n, istate_t *istate);
     53extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
     54extern void pht_init(void);
    3855
    3956#endif
    4057
    41  /** @}
     58/** @}
    4259 */
    43 
  • arch/ppc32/include/types.h

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32 
     29/** @addtogroup ppc32   
    3030 * @{
    3131 */
     
    6666#endif
    6767
    68  /** @}
     68/** @}
    6969 */
    70 
  • arch/ppc32/src/exception.S

    r8e3bf3e2 r10e0cee  
    138138        CONTEXT_STORE
    139139       
    140 #       li r3, 2
    141 #       mr r4, sp
    142 #       addi r4, r4, 8
    143 #       bl pht_real_refill
    144        
    145 #       cmpwi r3, 0
    146 #       bne iret_real
     140        li r3, 2
     141        mr r4, sp
     142        addi r4, r4, 8
     143        bl pht_real_refill
     144       
     145        cmpwi r3, 0
     146        bne iret_real
    147147       
    148148        li r3, 2
     
    154154        CONTEXT_STORE
    155155       
    156 #       li r3, 3
    157 #       mr r4, sp
    158 #       addi r4, r4, 8
    159 #       bl pht_real_refill
    160        
    161 #       cmpwi r3, 0
    162 #       bne iret_real
     156        li r3, 3
     157        mr r4, sp
     158        addi r4, r4, 8
     159        bl pht_real_refill
     160       
     161        cmpwi r3, 0
     162        bne iret_real
    163163
    164164        li r3, 3
  • arch/ppc32/src/interrupt.c

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32interrupt
     29/** @addtogroup ppc32interrupt
    3030 * @{
    3131 */
     
    4040#include <ipc/sysipc.h>
    4141#include <arch/drivers/pic.h>
     42#include <arch/mm/tlb.h>
    4243
    4344
     
    9394}
    9495
    95  /** @}
     96/** @}
    9697 */
    97 
  • arch/ppc32/src/mm/as.c

    r8e3bf3e2 r10e0cee  
    3535#include <arch/mm/as.h>
    3636#include <genarch/mm/as_pt.h>
     37#include <genarch/mm/asid_fifo.h>
     38#include <arch.h>
    3739
    3840/** Architecture dependent address space init. */
     
    4042{
    4143        as_operations = &as_pt_operations;
     44        asid_fifo_init();
     45}
     46
     47/** Install address space.
     48 *
     49 * Install ASID.
     50 *
     51 * @param as Address space structure.
     52 *
     53 */
     54void as_install_arch(as_t *as)
     55{
     56        asid_t asid;
     57        ipl_t ipl;
     58        __u8 sr;
     59
     60        ipl = interrupts_disable();
     61        spinlock_lock(&as->lock);
     62       
     63        asid = as->asid;
     64       
     65        /* Lower 2 GB, user and supervisor access */
     66        for (sr = 0; sr < 8; sr++) {
     67                asm volatile (
     68                        "mtsrin %0, %1\n"
     69                        :
     70                        : "r" (0x6000 + (asid << 4) + sr), "r" (sr * 0x1000)
     71                );
     72        }
     73       
     74        /* Upper 2 GB, only supervisor access */
     75        for (sr = 8; sr < 16; sr++) {
     76                asm volatile (
     77                        "mtsrin %0, %1\n"
     78                        :
     79                        : "r" (0x4000 + (asid << 4) + sr), "r" (sr * 0x1000)
     80                );
     81        }
     82       
     83        spinlock_unlock(&as->lock);
     84        interrupts_restore(ipl);
    4285}
    4386
  • arch/ppc32/src/mm/frame.c

    r8e3bf3e2 r10e0cee  
    6767        frame_mark_unavailable(0, 8);
    6868       
     69        /* Mark the Page Hash Table frames as unavailable */
     70        __u32 sdr1;
     71        asm volatile (
     72                "mfsdr1 %0\n"
     73                : "=r" (sdr1)
     74        );
     75        frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME
    6976}
    7077
  • arch/ppc32/src/mm/memory_init.c

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    5353}
    5454
    55  /** @}
     55/** @}
    5656 */
    57 
  • arch/ppc32/src/mm/page.c

    r8e3bf3e2 r10e0cee  
    3333 */
    3434
    35 #include <arch/mm/page.h>
    3635#include <genarch/mm/page_pt.h>
    37 #include <arch/mm/frame.h>
    38 #include <arch/asm.h>
    39 #include <arch/interrupt.h>
    4036#include <mm/frame.h>
    41 #include <mm/page.h>
    4237#include <mm/as.h>
    43 #include <arch.h>
    44 #include <arch/types.h>
    45 #include <arch/exception.h>
    4638#include <align.h>
    4739#include <config.h>
    48 #include <print.h>
    49 #include <symtab.h>
    50 
    51 
    52 /** Try to find PTE for faulting address
    53  *
    54  * Try to find PTE for faulting address.
    55  * The as->lock must be held on entry to this function
    56  * if lock is true.
    57  *
    58  * @param as       Address space.
    59  * @param lock     Lock/unlock the address space.
    60  * @param badvaddr Faulting virtual address.
    61  * @param access   Access mode that caused the fault.
    62  * @param istate   Pointer to interrupted state.
    63  * @param pfrc     Pointer to variable where as_page_fault() return code will be stored.
    64  * @return         PTE on success, NULL otherwise.
    65  *
    66  */
    67 static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, istate_t *istate, int *pfrc)
    68 {
    69         /*
    70          * Check if the mapping exists in page tables.
    71          */     
    72         pte_t *pte = page_mapping_find(as, badvaddr);
    73         if ((pte) && (pte->p)) {
    74                 /*
    75                  * Mapping found in page tables.
    76                  * Immediately succeed.
    77                  */
    78                 return pte;
    79         } else {
    80                 int rc;
    81        
    82                 /*
    83                  * Mapping not found in page tables.
    84                  * Resort to higher-level page fault handler.
    85                  */
    86                 page_table_unlock(as, lock);
    87                 switch (rc = as_page_fault(badvaddr, access, istate)) {
    88                         case AS_PF_OK:
    89                                 /*
    90                                  * The higher-level page fault handler succeeded,
    91                                  * The mapping ought to be in place.
    92                                  */
    93                                 page_table_lock(as, lock);
    94                                 pte = page_mapping_find(as, badvaddr);
    95                                 ASSERT((pte) && (pte->p));
    96                                 return pte;
    97                         case AS_PF_DEFER:
    98                                 page_table_lock(as, lock);
    99                                 *pfrc = rc;
    100                                 return NULL;
    101                         case AS_PF_FAULT:
    102                                 page_table_lock(as, lock);
    103                                 printf("Page fault.\n");
    104                                 *pfrc = rc;
    105                                 return NULL;
    106                         default:
    107                                 panic("unexpected rc (%d)\n", rc);
    108                 }       
    109         }
    110 }
    111 
    112 
    113 static void pht_refill_fail(__address badvaddr, istate_t *istate)
    114 {
    115         char *symbol = "";
    116         char *sym2 = "";
    117 
    118         char *s = get_symtab_entry(istate->pc);
    119         if (s)
    120                 symbol = s;
    121         s = get_symtab_entry(istate->lr);
    122         if (s)
    123                 sym2 = s;
    124         panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
    125 }
    126 
    127 
    128 static void pht_insert(const __address vaddr, const pfn_t pfn)
    129 {
    130         __u32 page = (vaddr >> 12) & 0xffff;
    131         __u32 api = (vaddr >> 22) & 0x3f;
    132        
    133         __u32 vsid;
    134         asm volatile (
    135                 "mfsrin %0, %1\n"
    136                 : "=r" (vsid)
    137                 : "r" (vaddr)
    138         );
    139        
    140         __u32 sdr1;
    141         asm volatile (
    142                 "mfsdr1 %0\n"
    143                 : "=r" (sdr1)
    144         );
    145         phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    146        
    147         /* Primary hash (xor) */
    148         __u32 h = 0;
    149         __u32 hash = vsid ^ page;
    150         __u32 base = (hash & 0x3ff) << 3;
    151         __u32 i;
    152         bool found = false;
    153        
    154         /* Find unused or colliding
    155            PTE in PTEG */
    156         for (i = 0; i < 8; i++) {
    157                 if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) {
    158                         found = true;
    159                         break;
    160                 }
    161         }
    162        
    163         if (!found) {
    164                 /* Secondary hash (not) */
    165                 __u32 base2 = (~hash & 0x3ff) << 3;
    166                
    167                 /* Find unused or colliding
    168                    PTE in PTEG */
    169                 for (i = 0; i < 8; i++) {
    170                         if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {
    171                                 found = true;
    172                                 base = base2;
    173                                 h = 1;
    174                                 break;
    175                         }
    176                 }
    177                
    178                 if (!found) {
    179                         // TODO: A/C precedence groups
    180                         i = page % 8;
    181                 }
    182         }
    183        
    184         phte[base + i].v = 1;
    185         phte[base + i].vsid = vsid;
    186         phte[base + i].h = h;
    187         phte[base + i].api = api;
    188         phte[base + i].rpn = pfn;
    189         phte[base + i].r = 0;
    190         phte[base + i].c = 0;
    191         phte[base + i].pp = 2; // FIXME
    192 }
    193 
    194 
    195 static void pht_real_insert(const __address vaddr, const pfn_t pfn)
    196 {
    197         __u32 page = (vaddr >> 12) & 0xffff;
    198         __u32 api = (vaddr >> 22) & 0x3f;
    199        
    200         __u32 vsid;
    201         asm volatile (
    202                 "mfsrin %0, %1\n"
    203                 : "=r" (vsid)
    204                 : "r" (vaddr)
    205         );
    206        
    207         __u32 sdr1;
    208         asm volatile (
    209                 "mfsdr1 %0\n"
    210                 : "=r" (sdr1)
    211         );
    212         phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
    213        
    214         /* Primary hash (xor) */
    215         __u32 h = 0;
    216         __u32 hash = vsid ^ page;
    217         __u32 base = (hash & 0x3ff) << 3;
    218         __u32 i;
    219         bool found = false;
    220        
    221         /* Find unused or colliding
    222            PTE in PTEG */
    223         for (i = 0; i < 8; i++) {
    224                 if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) {
    225                         found = true;
    226                         break;
    227                 }
    228         }
    229        
    230         if (!found) {
    231                 /* Secondary hash (not) */
    232                 __u32 base2 = (~hash & 0x3ff) << 3;
    233                
    234                 /* Find unused or colliding
    235                    PTE in PTEG */
    236                 for (i = 0; i < 8; i++) {
    237                         if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) {
    238                                 found = true;
    239                                 base = base2;
    240                                 h = 1;
    241                                 break;
    242                         }
    243                 }
    244                
    245                 if (!found) {
    246                         // TODO: A/C precedence groups
    247                         i = page % 8;
    248                 }
    249         }
    250        
    251         phte_physical[base + i].v = 1;
    252         phte_physical[base + i].vsid = vsid;
    253         phte_physical[base + i].h = h;
    254         phte_physical[base + i].api = api;
    255         phte_physical[base + i].rpn = pfn;
    256         phte_physical[base + i].r = 0;
    257         phte_physical[base + i].c = 0;
    258         phte_physical[base + i].pp = 2; // FIXME
    259 }
    260 
    261 
    262 /** Process Instruction/Data Storage Interrupt
    263  *
    264  * @param n Interrupt vector number.
    265  * @param istate Interrupted register context.
    266  *
    267  */
    268 void pht_refill(int n, istate_t *istate)
    269 {
    270         __address badvaddr;
    271         pte_t *pte;
    272         int pfrc;
    273         as_t *as;
    274         bool lock;
    275        
    276         if (AS == NULL) {
    277                 as = AS_KERNEL;
    278                 lock = false;
    279         } else {
    280                 as = AS;
    281                 lock = true;
    282         }
    283        
    284         if (n == VECTOR_DATA_STORAGE) {
    285                 asm volatile (
    286                         "mfdar %0\n"
    287                         : "=r" (badvaddr)
    288                 );
    289         } else
    290                 badvaddr = istate->pc;
    291                
    292         page_table_lock(as, lock);
    293        
    294         pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc);
    295         if (!pte) {
    296                 switch (pfrc) {
    297                         case AS_PF_FAULT:
    298                                 goto fail;
    299                                 break;
    300                         case AS_PF_DEFER:
    301                                 /*
    302                                  * The page fault came during copy_from_uspace()
    303                                  * or copy_to_uspace().
    304                                  */
    305                                 page_table_unlock(as, lock);
    306                                 return;
    307                         default:
    308                                 panic("Unexpected pfrc (%d)\n", pfrc);
    309                 }
    310         }
    311        
    312         pte->a = 1; /* Record access to PTE */
    313         pht_insert(badvaddr, pte->pfn);
    314        
    315         page_table_unlock(as, lock);
    316         return;
    317        
    318 fail:
    319         page_table_unlock(as, lock);
    320         pht_refill_fail(badvaddr, istate);
    321 }
    322 
    323 
    324 /** Process Instruction/Data Storage Interrupt in Real Mode
    325  *
    326  * @param n Interrupt vector number.
    327  * @param istate Interrupted register context.
    328  *
    329  */
    330 bool pht_real_refill(int n, istate_t *istate)
    331 {
    332         __address badvaddr;
    333        
    334         if (n == VECTOR_DATA_STORAGE) {
    335                 asm volatile (
    336                         "mfdar %0\n"
    337                         : "=r" (badvaddr)
    338                 );
    339         } else
    340                 badvaddr = istate->pc;
    341        
    342         __u32 physmem;
    343         asm volatile (
    344                 "mfsprg3 %0\n"
    345                 : "=r" (physmem)
    346         );
    347        
    348         if ((badvaddr >= PA2KA(0)) && (badvaddr <= PA2KA(physmem))) {
    349                 pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
    350                 return true;
    351         }
    352        
    353         return false;
    354 }
    355 
    356 
    357 void pht_init(void)
    358 {
    359         // FIXME
    360        
    361         __u32 sdr1;
    362         asm volatile (
    363                 "mfsdr1 %0\n"
    364                 : "=r" (sdr1)
    365         );
    366         phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    367        
    368         memsetb((__address) phte, 65536, 0);
    369 }
    370 
    37140
    37241void page_arch_init(void)
  • arch/ppc32/src/mm/tlb.c

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32mm       
     29/** @addtogroup ppc32mm
    3030 * @{
    3131 */
     
    3434
    3535#include <mm/tlb.h>
    36 
    37 
    38 /** Initialize Page Hash Table.
    39  *
    40  * Setup the Page Hash Table with no entries.
    41  *
    42  */
     36#include <arch/mm/tlb.h>
     37#include <arch/interrupt.h>
     38#include <mm/as.h>
     39#include <arch.h>
     40#include <print.h>
     41#include <symtab.h>
     42
     43
     44/** Try to find PTE for faulting address
     45 *
     46 * Try to find PTE for faulting address.
     47 * The as->lock must be held on entry to this function
     48 * if lock is true.
     49 *
     50 * @param as       Address space.
     51 * @param lock     Lock/unlock the address space.
     52 * @param badvaddr Faulting virtual address.
     53 * @param access   Access mode that caused the fault.
     54 * @param istate   Pointer to interrupted state.
     55 * @param pfrc     Pointer to variable where as_page_fault() return code will be stored.
     56 * @return         PTE on success, NULL otherwise.
     57 *
     58 */
     59static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, istate_t *istate, int *pfrc)
     60{
     61        /*
     62         * Check if the mapping exists in page tables.
     63         */     
     64        pte_t *pte = page_mapping_find(as, badvaddr);
     65        if ((pte) && (pte->p)) {
     66                /*
     67                 * Mapping found in page tables.
     68                 * Immediately succeed.
     69                 */
     70                return pte;
     71        } else {
     72                int rc;
     73       
     74                /*
     75                 * Mapping not found in page tables.
     76                 * Resort to higher-level page fault handler.
     77                 */
     78                page_table_unlock(as, lock);
     79                switch (rc = as_page_fault(badvaddr, access, istate)) {
     80                        case AS_PF_OK:
     81                                /*
     82                                 * The higher-level page fault handler succeeded,
     83                                 * The mapping ought to be in place.
     84                                 */
     85                                page_table_lock(as, lock);
     86                                pte = page_mapping_find(as, badvaddr);
     87                                ASSERT((pte) && (pte->p));
     88                                return pte;
     89                        case AS_PF_DEFER:
     90                                page_table_lock(as, lock);
     91                                *pfrc = rc;
     92                                return NULL;
     93                        case AS_PF_FAULT:
     94                                page_table_lock(as, lock);
     95                                printf("Page fault.\n");
     96                                *pfrc = rc;
     97                                return NULL;
     98                        default:
     99                                panic("unexpected rc (%d)\n", rc);
     100                }       
     101        }
     102}
     103
     104
     105static void pht_refill_fail(__address badvaddr, istate_t *istate)
     106{
     107        char *symbol = "";
     108        char *sym2 = "";
     109
     110        char *s = get_symtab_entry(istate->pc);
     111        if (s)
     112                symbol = s;
     113        s = get_symtab_entry(istate->lr);
     114        if (s)
     115                sym2 = s;
     116        panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
     117}
     118
     119
     120static void pht_insert(const __address vaddr, const pfn_t pfn)
     121{
     122        __u32 page = (vaddr >> 12) & 0xffff;
     123        __u32 api = (vaddr >> 22) & 0x3f;
     124       
     125        __u32 vsid;
     126        asm volatile (
     127                "mfsrin %0, %1\n"
     128                : "=r" (vsid)
     129                : "r" (vaddr)
     130        );
     131       
     132        __u32 sdr1;
     133        asm volatile (
     134                "mfsdr1 %0\n"
     135                : "=r" (sdr1)
     136        );
     137        phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
     138       
     139        /* Primary hash (xor) */
     140        __u32 h = 0;
     141        __u32 hash = vsid ^ page;
     142        __u32 base = (hash & 0x3ff) << 3;
     143        __u32 i;
     144        bool found = false;
     145       
     146        /* Find unused or colliding
     147           PTE in PTEG */
     148        for (i = 0; i < 8; i++) {
     149                if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) {
     150                        found = true;
     151                        break;
     152                }
     153        }
     154       
     155        if (!found) {
     156                /* Secondary hash (not) */
     157                __u32 base2 = (~hash & 0x3ff) << 3;
     158               
     159                /* Find unused or colliding
     160                   PTE in PTEG */
     161                for (i = 0; i < 8; i++) {
     162                        if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {
     163                                found = true;
     164                                base = base2;
     165                                h = 1;
     166                                break;
     167                        }
     168                }
     169               
     170                if (!found) {
     171                        // TODO: A/C precedence groups
     172                        i = page % 8;
     173                }
     174        }
     175       
     176        phte[base + i].v = 1;
     177        phte[base + i].vsid = vsid;
     178        phte[base + i].h = h;
     179        phte[base + i].api = api;
     180        phte[base + i].rpn = pfn;
     181        phte[base + i].r = 0;
     182        phte[base + i].c = 0;
     183        phte[base + i].pp = 2; // FIXME
     184}
     185
     186
     187static void pht_real_insert(const __address vaddr, const pfn_t pfn)
     188{
     189        __u32 page = (vaddr >> 12) & 0xffff;
     190        __u32 api = (vaddr >> 22) & 0x3f;
     191       
     192        __u32 vsid;
     193        asm volatile (
     194                "mfsrin %0, %1\n"
     195                : "=r" (vsid)
     196                : "r" (vaddr)
     197        );
     198       
     199        __u32 sdr1;
     200        asm volatile (
     201                "mfsdr1 %0\n"
     202                : "=r" (sdr1)
     203        );
     204        phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
     205       
     206        /* Primary hash (xor) */
     207        __u32 h = 0;
     208        __u32 hash = vsid ^ page;
     209        __u32 base = (hash & 0x3ff) << 3;
     210        __u32 i;
     211        bool found = false;
     212       
     213        /* Find unused or colliding
     214           PTE in PTEG */
     215        for (i = 0; i < 8; i++) {
     216                if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) {
     217                        found = true;
     218                        break;
     219                }
     220        }
     221       
     222        if (!found) {
     223                /* Secondary hash (not) */
     224                __u32 base2 = (~hash & 0x3ff) << 3;
     225               
     226                /* Find unused or colliding
     227                   PTE in PTEG */
     228                for (i = 0; i < 8; i++) {
     229                        if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) {
     230                                found = true;
     231                                base = base2;
     232                                h = 1;
     233                                break;
     234                        }
     235                }
     236               
     237                if (!found) {
     238                        // TODO: A/C precedence groups
     239                        i = page % 8;
     240                }
     241        }
     242       
     243        phte_physical[base + i].v = 1;
     244        phte_physical[base + i].vsid = vsid;
     245        phte_physical[base + i].h = h;
     246        phte_physical[base + i].api = api;
     247        phte_physical[base + i].rpn = pfn;
     248        phte_physical[base + i].r = 0;
     249        phte_physical[base + i].c = 0;
     250        phte_physical[base + i].pp = 2; // FIXME
     251}
     252
     253
     254/** Process Instruction/Data Storage Interrupt
     255 *
     256 * @param n Interrupt vector number.
     257 * @param istate Interrupted register context.
     258 *
     259 */
     260void pht_refill(int n, istate_t *istate)
     261{
     262        __address badvaddr;
     263        pte_t *pte;
     264        int pfrc;
     265        as_t *as;
     266        bool lock;
     267       
     268        if (AS == NULL) {
     269                as = AS_KERNEL;
     270                lock = false;
     271        } else {
     272                as = AS;
     273                lock = true;
     274        }
     275       
     276        if (n == VECTOR_DATA_STORAGE) {
     277                asm volatile (
     278                        "mfdar %0\n"
     279                        : "=r" (badvaddr)
     280                );
     281        } else
     282                badvaddr = istate->pc;
     283               
     284        page_table_lock(as, lock);
     285       
     286        pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc);
     287        if (!pte) {
     288                switch (pfrc) {
     289                        case AS_PF_FAULT:
     290                                goto fail;
     291                                break;
     292                        case AS_PF_DEFER:
     293                                /*
     294                                 * The page fault came during copy_from_uspace()
     295                                 * or copy_to_uspace().
     296                                 */
     297                                page_table_unlock(as, lock);
     298                                return;
     299                        default:
     300                                panic("Unexpected pfrc (%d)\n", pfrc);
     301                }
     302        }
     303       
     304        pte->a = 1; /* Record access to PTE */
     305        pht_insert(badvaddr, pte->pfn);
     306       
     307        page_table_unlock(as, lock);
     308        return;
     309       
     310fail:
     311        page_table_unlock(as, lock);
     312        pht_refill_fail(badvaddr, istate);
     313}
     314
     315
     316/** Process Instruction/Data Storage Interrupt in Real Mode
     317 *
     318 * @param n Interrupt vector number.
     319 * @param istate Interrupted register context.
     320 *
     321 */
     322bool pht_real_refill(int n, istate_t *istate)
     323{
     324        __address badvaddr;
     325       
     326        if (n == VECTOR_DATA_STORAGE) {
     327                asm volatile (
     328                        "mfdar %0\n"
     329                        : "=r" (badvaddr)
     330                );
     331        } else
     332                badvaddr = istate->pc;
     333       
     334        __u32 physmem;
     335        asm volatile (
     336                "mfsprg3 %0\n"
     337                : "=r" (physmem)
     338        );
     339       
     340        if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
     341                pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
     342                return true;
     343        }
     344       
     345        return false;
     346}
     347
     348
    43349void tlb_arch_init(void)
    44350{
     
    56362
    57363
    58 /** Invalidate all entries in TLB that belong to specified address space.
    59  *
    60  * @param asid This parameter is ignored as the architecture doesn't support it.
    61  */
    62364void tlb_invalidate_asid(asid_t asid)
    63365{
     366        // TODO
    64367        tlb_invalidate_all();
    65368}
    66369
    67 /** Invalidate TLB entries for specified page range belonging to specified address space.
    68  *
    69  * @param asid This parameter is ignored as the architecture doesn't support it.
    70  * @param page Address of the first page whose entry is to be invalidated.
    71  * @param cnt Number of entries to invalidate.
    72  */
     370
    73371void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt)
    74372{
     373        // TODO
    75374        tlb_invalidate_all();
    76375}
    77376
    78377
    79 
    80 /** Print contents of Page Hash Table. */
    81378void tlb_print(void)
    82379{
    83 }
    84 
    85  /** @}
    86  */
    87 
     380        // TODO
     381}
     382
     383/** @}
     384 */
  • arch/ppc32/src/proc/scheduler.c

    r8e3bf3e2 r10e0cee  
    2727 */
    2828
    29  /** @addtogroup ppc32proc
     29/** @addtogroup ppc32proc
    3030 * @{
    3131 */
     
    4747void before_thread_runs_arch(void)
    4848{
    49         pht_init();
    5049        tlb_invalidate_all();
    5150        asm volatile (
     
    6059}
    6160
    62  /** @}
     61/** @}
    6362 */
    64 
Note: See TracChangeset for help on using the changeset viewer.