Changeset 35f3b8c in mainline for arch/ppc32/src


Ignore:
Timestamp:
2006-05-18T23:24:40Z (19 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c0bc189
Parents:
8424198
Message:

ppc32 work
update framebuffer
get rid of the BAT memory mapping (not finished yet)

Location:
arch/ppc32/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • arch/ppc32/src/asm.S

    r8424198 r35f3b8c  
    3434.global iret
    3535.global iret_syscall
     36.global invalidate_bat
    3637.global memsetb
    3738.global memcpy
     
    194195        rfi
    195196       
     197invalidate_bat:
     198       
     199        # invalidate block address translation registers
     200       
     201        li r14, 0
     202       
     203        mtspr ibat0u, r14
     204        mtspr ibat0l, r14
     205       
     206        mtspr ibat1u, r14
     207        mtspr ibat1l, r14
     208       
     209        mtspr ibat2u, r14
     210        mtspr ibat2l, r14
     211       
     212        mtspr ibat3u, r14
     213        mtspr ibat3l, r14
     214       
     215        mtspr dbat0u, r14
     216        mtspr dbat0l, r14
     217       
     218        mtspr dbat1u, r14
     219        mtspr dbat1l, r14
     220       
     221        mtspr dbat2u, r14
     222        mtspr dbat2l, r14
     223       
     224        mtspr dbat3u, r14
     225        mtspr dbat3l, r14
     226       
     227        blr
     228       
    196229memsetb:
    197230        rlwimi r5, r5, 8, 16, 23
  • arch/ppc32/src/mm/page.c

    r8424198 r35f3b8c  
    3030#include <genarch/mm/page_pt.h>
    3131#include <arch/mm/frame.h>
     32#include <arch/asm.h>
    3233#include <mm/frame.h>
    3334#include <mm/page.h>
     35#include <mm/as.h>
     36#include <arch.h>
    3437#include <arch/types.h>
     38#include <arch/exception.h>
     39#include <config.h>
     40#include <print.h>
     41#include <symtab.h>
     42
     43static phte_t *phte;
     44
     45
     46/** Try to find PTE for faulting address
     47 *
     48 * Try to find PTE for faulting address.
     49 * The AS->lock must be held on entry to this function.
     50 *
     51 * @param badvaddr Faulting virtual address.
     52 * @param istate Pointer to interrupted state.
     53 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
     54 * @return         PTE on success, NULL otherwise.
     55 *
     56 */
     57static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
     58{
     59        /*
     60         * Check if the mapping exists in page tables.
     61         */     
     62        pte_t *pte = page_mapping_find(AS, badvaddr);
     63        if ((pte) && (pte->p)) {
     64                /*
     65                 * Mapping found in page tables.
     66                 * Immediately succeed.
     67                 */
     68                return pte;
     69        } else {
     70                int rc;
     71       
     72                /*
     73                 * Mapping not found in page tables.
     74                 * Resort to higher-level page fault handler.
     75                 */
     76                page_table_unlock(AS, true);
     77                switch (rc = as_page_fault(badvaddr, istate)) {
     78                        case AS_PF_OK:
     79                                /*
     80                                 * The higher-level page fault handler succeeded,
     81                                 * The mapping ought to be in place.
     82                                 */
     83                                page_table_lock(AS, true);
     84                                pte = page_mapping_find(AS, badvaddr);
     85                                ASSERT((pte) && (pte->p));
     86                                return pte;
     87                        case AS_PF_DEFER:
     88                                page_table_lock(AS, true);
     89                                *pfcr = rc;
     90                                return NULL;
     91                        case AS_PF_FAULT:
     92                                page_table_lock(AS, true);
     93                                printf("Page fault.\n");
     94                                *pfcr = rc;
     95                                return NULL;
     96                        default:
     97                                panic("unexpected rc (%d)\n", rc);
     98                }       
     99        }
     100}
     101
     102
     103static void pht_refill_fail(__address badvaddr, istate_t *istate)
     104{
     105        char *symbol = "";
     106        char *sym2 = "";
     107
     108        char *s = get_symtab_entry(istate->pc);
     109        if (s)
     110                symbol = s;
     111        s = get_symtab_entry(istate->lr);
     112        if (s)
     113                sym2 = s;
     114        panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
     115}
     116
     117static void pht_insert(const __address vaddr, const pfn_t pfn)
     118{
     119        __u32 page = (vaddr >> 12) & 0xffff;
     120        __u32 api = (vaddr >> 22) & 0x3f;
     121        __u32 vsid;
     122       
     123        asm volatile (
     124                "mfsrin %0, %1\n"
     125                : "=r" (vsid)
     126                : "r" (vaddr)
     127        );
     128       
     129        /* Primary hash (xor) */
     130        __u32 hash = ((vsid ^ page) & 0x3ff) << 3;
     131       
     132        __u32 i;
     133        /* Find unused PTE in PTEG */
     134        for (i = 0; i < 8; i++) {
     135                if (!phte[hash + i].v)
     136                        break;
     137        }
     138       
     139        // TODO: Check access/change bits, secondary hash
     140       
     141        if (i == 8)
     142                i = page % 8;
     143       
     144        phte[hash + i].v = 1;
     145        phte[hash + i].vsid = vsid;
     146        phte[hash + i].h = 0;
     147        phte[hash + i].api = api;
     148        phte[hash + i].rpn = pfn;
     149        phte[hash + i].r = 0;
     150        phte[hash + i].c = 0;
     151        phte[hash + i].pp = 2; // FIXME
     152}
     153
     154
     155/** Process Instruction/Data Storage Interrupt
     156 *
     157 * @param data   True if Data Storage Interrupt.
     158 * @param istate Interrupted register context.
     159 *
     160 */
     161void pht_refill(bool data, istate_t *istate)
     162{
     163        asid_t asid;
     164        __address badvaddr;
     165        pte_t *pte;
     166       
     167        int pfcr;
     168       
     169        if (data) {
     170                asm volatile (
     171                        "mfdar %0\n"
     172                        : "=r" (badvaddr)
     173                );
     174        } else
     175                badvaddr = istate->pc;
     176               
     177        spinlock_lock(&AS->lock);
     178        asid = AS->asid;
     179        spinlock_unlock(&AS->lock);
     180       
     181        page_table_lock(AS, true);
     182       
     183        pte = find_mapping_and_check(badvaddr, istate, &pfcr);
     184        if (!pte) {
     185                switch (pfcr) {
     186                case AS_PF_FAULT:
     187                        goto fail;
     188                        break;
     189                case AS_PF_DEFER:
     190                        /*
     191                         * The page fault came during copy_from_uspace()
     192                         * or copy_to_uspace().
     193                         */
     194                        page_table_unlock(AS, true);
     195                        return;
     196                default:
     197                        panic("Unexpected pfrc (%d)\n", pfcr);
     198                        break;
     199                }
     200        }
     201       
     202        pte->a = 1; /* Record access to PTE */
     203        pht_insert(badvaddr, pte->pfn);
     204       
     205        page_table_unlock(AS, true);
     206        return;
     207       
     208fail:
     209        page_table_unlock(AS, true);
     210        pht_refill_fail(badvaddr, istate);
     211}
     212
     213
     214void pht_init(void)
     215{
     216        memsetb((__address) phte, 1 << PHT_BITS, 0);
     217       
     218        /* Insert global kernel mapping */
     219       
     220        __address cur;
     221        for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
     222                pte_t *pte = page_mapping_find(AS_KERNEL, PA2KA(cur));
     223                if ((pte) && (pte->p) && (pte->g))
     224                        pht_insert(PA2KA(cur), pte->pfn);
     225        }
     226}
     227
    35228
    36229void page_arch_init(void)
    37230{
    38         page_mapping_operations = &pt_mapping_operations;
    39 }
     231        if (config.cpu_active == 1) {
     232                page_mapping_operations = &pt_mapping_operations;
     233               
     234                /*
     235                 * PA2KA(identity) mapping for all frames until last_frame.
     236                 */
     237                __address cur;
     238                int flags;
     239               
     240                for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
     241                        flags = PAGE_CACHEABLE;
     242                        if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
     243                                flags |= PAGE_GLOBAL;
     244                        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
     245                }
     246               
     247                /* Allocate page hash table */
     248                phte_t *physical_phte = (phte_t *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC));
     249                phte = (phte_t *) PA2KA((__address) physical_phte);
     250               
     251                ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0);
     252                pht_init();
     253               
     254                asm volatile (
     255                        "mtsdr1 %0\n"
     256                        :
     257                        : "r" ((__address) physical_phte)
     258                );
     259               
     260                /* Invalidate block address translation registers,
     261                   thus remove the temporary mapping */
     262//              invalidate_bat();
     263        }
     264}
  • arch/ppc32/src/mm/tlb.c

    r8424198 r35f3b8c  
    2727 */
    2828
    29 #include <arch/mm/tlb.h>
    30 #include <arch/types.h>
    3129#include <mm/tlb.h>
    32 #include <mm/frame.h>
    33 #include <mm/page.h>
    34 #include <mm/as.h>
    35 #include <arch.h>
    36 #include <print.h>
    37 #include <symtab.h>
    38 
    39 
    40 static phte_t *phte;
    4130
    4231
     
    4837void tlb_arch_init(void)
    4938{
    50         phte_t *physical_phte = (phte_t *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC));
    51         phte =(phte_t *) PA2KA((__address) physical_phte);
    52        
    53         ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0);
    54        
    55         memsetb((__address) phte, 1 << PHT_BITS, 0);
    56        
    5739        asm volatile (
    58                 "mtsdr1 %0\n"
    59                 :
    60                 : "r" ((__address) physical_phte)
     40                "tlbia\n"
    6141        );
    62 }
    63 
    64 
    65 /** Try to find PTE for faulting address
    66  *
    67  * Try to find PTE for faulting address.
    68  * The AS->lock must be held on entry to this function.
    69  *
    70  * @param badvaddr Faulting virtual address.
    71  * @param istate Pointer to interrupted state.
    72  * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
    73  * @return         PTE on success, NULL otherwise.
    74  *
    75  */
    76 static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
    77 {
    78         /*
    79          * Check if the mapping exists in page tables.
    80          */     
    81         pte_t *pte = page_mapping_find(AS, badvaddr);
    82         if ((pte) && (pte->p)) {
    83                 /*
    84                  * Mapping found in page tables.
    85                  * Immediately succeed.
    86                  */
    87                 return pte;
    88         } else {
    89                 int rc;
    90        
    91                 /*
    92                  * Mapping not found in page tables.
    93                  * Resort to higher-level page fault handler.
    94                  */
    95                 page_table_unlock(AS, true);
    96                 switch (rc = as_page_fault(badvaddr, istate)) {
    97                 case AS_PF_OK:
    98                         /*
    99                          * The higher-level page fault handler succeeded,
    100                          * The mapping ought to be in place.
    101                          */
    102                         page_table_lock(AS, true);
    103                         pte = page_mapping_find(AS, badvaddr);
    104                         ASSERT((pte) && (pte->p));
    105                         return pte;
    106                         break;
    107                 case AS_PF_DEFER:
    108                         page_table_lock(AS, true);
    109                         *pfcr = rc;
    110                         return NULL;
    111                         break;
    112                 case AS_PF_FAULT:
    113                         page_table_lock(AS, true);
    114                         printf("Page fault.\n");
    115                         *pfcr = rc;
    116                         return NULL;
    117                         break;
    118                 default:
    119                         panic("unexpected rc (%d)\n", rc);
    120                         break;
    121                 }       
    122         }
    123 }
    124 
    125 
    126 static void pht_refill_fail(__address badvaddr, istate_t *istate)
    127 {
    128         char *symbol = "";
    129         char *sym2 = "";
    130 
    131         char *s = get_symtab_entry(istate->pc);
    132         if (s)
    133                 symbol = s;
    134         s = get_symtab_entry(istate->lr);
    135         if (s)
    136                 sym2 = s;
    137         panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
    138 }
    139 
    140 
    141 /** Process Instruction/Data Storage Interrupt
    142  *
    143  * @param data   True if Data Storage Interrupt.
    144  * @param istate Interrupted register context.
    145  *
    146  */
    147 void pht_refill(bool data, istate_t *istate)
    148 {
    149         asid_t asid;
    150         __address badvaddr;
    151         pte_t *pte;
    152         __u32 page;
    153         __u32 api;
    154         __u32 vsid;
    155         __u32 hash;
    156         __u32 i;
    157         int pfcr;
    158        
    159         if (data) {
    160                 asm volatile (
    161                         "mfdar %0\n"
    162                         : "=r" (badvaddr)
    163                 );
    164         } else
    165                 badvaddr = istate->pc;
    166                
    167         spinlock_lock(&AS->lock);
    168         asid = AS->asid;
    169         spinlock_unlock(&AS->lock);
    170        
    171         page_table_lock(AS, true);
    172        
    173         pte = find_mapping_and_check(badvaddr, istate, &pfcr);
    174         if (!pte) {
    175                 switch (pfcr) {
    176                 case AS_PF_FAULT:
    177                         goto fail;
    178                         break;
    179                 case AS_PF_DEFER:
    180                         /*
    181                          * The page fault came during copy_from_uspace()
    182                          * or copy_to_uspace().
    183                          */
    184                         page_table_unlock(AS, true);
    185                         return;
    186                 default:
    187                         panic("Unexpected pfrc (%d)\n", pfcr);
    188                         break;
    189                 }
    190         }
    191 
    192         /* Record access to PTE */
    193         pte->a = 1;
    194        
    195         page = (badvaddr >> 12) & 0xffff;
    196         api = (badvaddr >> 22) & 0x3f;
    197         asm volatile (
    198                 "mfsrin %0, %1\n"
    199                 : "=r" (vsid)
    200                 : "r" (badvaddr)
    201         );
    202        
    203         /* Primary hash (xor) */
    204         hash = ((vsid ^ page) & 0x3ff) << 3;
    205        
    206         /* Find invalid PTE in PTEG */
    207         for (i = 0; i < 8; i++) {
    208                 if (!phte[hash + i].v)
    209                         break;
    210         }
    211        
    212         // TODO: Check access/change bits, secondary hash
    213        
    214         if (i == 8)
    215                 i = page % 8;
    216        
    217         phte[hash + i].v = 1;
    218         phte[hash + i].vsid = vsid;
    219         phte[hash + i].h = 0;
    220         phte[hash + i].api = api;
    221         phte[hash + i].rpn = pte->pfn;
    222         phte[hash + i].r = 0;
    223         phte[hash + i].c = 0;
    224         phte[hash + i].pp = 2; // FIXME
    225        
    226         page_table_unlock(AS, true);
    227         return;
    228        
    229 fail:
    230         page_table_unlock(AS, true);
    231         pht_refill_fail(badvaddr, istate);
    23242}
    23343
     
    23545void tlb_invalidate_all(void)
    23646{
    237         ipl_t ipl;
    238 
    239         ipl = interrupts_disable();
    240         memsetb((__address) phte, 1 << PHT_BITS, 0);
    241         interrupts_restore(ipl);
    24247}
    24348
  • arch/ppc32/src/ppc32.c

    r8424198 r35f3b8c  
    2929#include <arch.h>
    3030#include <arch/boot/boot.h>
    31 #include <arch/console.h>
    3231#include <arch/drivers/cuda.h>
    3332#include <arch/mm/memory_init.h>
    3433#include <arch/interrupt.h>
     34#include <genarch/fb/fb.h>
    3535#include <userspace.h>
    3636#include <proc/uarg.h>
     
    6868                /* Merge all zones to 1 big zone */
    6969                zone_merge_all();
    70                
    71                 ppc32_console_register();
    7270        }
    7371}
  • arch/ppc32/src/proc/scheduler.c

    r8424198 r35f3b8c  
    4141void before_thread_runs_arch(void)
    4242{
    43         tlb_invalidate_all();
     43        pht_init();
    4444        asm volatile (
    4545                "mtsprg0 %0\n"
Note: See TracChangeset for help on using the changeset viewer.