Changeset cc205f1 in mainline


Ignore:
Timestamp:
2005-10-06T12:45:22Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fd3c9e5
Parents:
bca1b47
Message:

Add mm/mapping1 test.
(Will not make it past TLB Invalid exception on mips32.)
Fixes in asid.c.
Make TLB register types union with u32 value.
Implement tlb_invalidate() for mips32.
(TLB invalidation and shootdown path will have to be revised.)

Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • Makefile.config

    rbca1b47 rcc205f1  
    4141#TEST_DIR=print/print1/
    4242#TEST_DIR=thread/thread1/
     43#TEST_DIR=mm/mapping1/
  • arch/ia32/src/mm/tlb.c

    rbca1b47 rcc205f1  
    2828
    2929#include <mm/tlb.h>
     30#include <arch/mm/asid.h>
    3031#include <arch/asm.h>
    3132
    32 void tlb_invalidate(int asid)
     33/** Invalidate all TLB entries
     34 *
     35 * Invalidate all TLB entries.
     36 *
     37 * @param asid This argument is ignored.
     38 */
     39void tlb_invalidate(asid_t asid)
    3340{
    3441        write_cr3(read_cr3());
  • arch/mips32/include/mm/asid.h

    rbca1b47 rcc205f1  
    3131
    3232#include <arch/types.h>
     33#include <typedefs.h>
     34
     35#define ASIDS           256
     36#define ASID_INVALID    0
     37#define ASID_START      1
    3338
    3439typedef __u8 asid_t;
     
    3641extern asid_t asid_get(void);
    3742extern void asid_put(asid_t asid);
     43extern bool asid_has_conflicts(asid_t asid);
    3844
    3945#endif
  • arch/mips32/include/mm/tlb.h

    rbca1b47 rcc205f1  
    4242#define PAGE_CACHEABLE_EXC_WRITE        5
    4343
    44 struct entry_lo {
    45         unsigned g : 1;         /* global bit */
    46         unsigned v : 1;         /* valid bit */
    47         unsigned d : 1;         /* dirty/write-protect bit */
    48         unsigned c : 3;         /* cache coherency attribute */
    49         unsigned pfn : 24;      /* frame number */
    50         unsigned zero: 2;       /* zero */
    51 } __attribute__ ((packed));
     44union entry_lo {
     45        struct {
     46                unsigned g : 1;         /* global bit */
     47                unsigned v : 1;         /* valid bit */
     48                unsigned d : 1;         /* dirty/write-protect bit */
     49                unsigned c : 3;         /* cache coherency attribute */
     50                unsigned pfn : 24;      /* frame number */
     51                unsigned zero: 2;       /* zero */
     52        } __attribute__ ((packed));
     53        __u32 value;
     54};
    5255
    5356struct pte {
     
    6164} __attribute__ ((packed));
    6265
    63 struct entry_hi {
    64         unsigned asid : 8;
    65         unsigned : 5;
    66         unsigned vpn2 : 19;
    67 } __attribute__ ((packed));
     66union entry_hi {
     67        struct {
     68                unsigned asid : 8;
     69                unsigned : 5;
     70                unsigned vpn2 : 19;
     71        } __attribute__ ((packed));
     72        __u32 value;
     73};
    6874
    69 struct page_mask {
    70         unsigned : 13;
    71         unsigned mask : 12;
    72         unsigned : 7;
    73 } __attribute__ ((packed));
     75union page_mask {
     76        struct {
     77                unsigned : 13;
     78                unsigned mask : 12;
     79                unsigned : 7;
     80        } __attribute__ ((packed));
     81        __u32 value;
     82};
    7483
    75 struct index {
    76         unsigned index : 4;
    77         unsigned : 27;
    78         unsigned p : 1;
    79 } __attribute__ ((packed));
     84union index {
     85        struct {
     86                unsigned index : 4;
     87                unsigned : 27;
     88                unsigned p : 1;
     89        } __attribute__ ((packed));
     90        __u32 value;
     91};
     92
     93typedef union entry_lo entry_lo_t;
     94typedef union entry_hi entry_hi_t;
     95typedef union page_mask page_mask_t;
     96typedef union index tlb_index_t;
    8097
    8198/** Probe TLB for Matching Entry
  • arch/mips32/src/mm/asid.c

    rbca1b47 rcc205f1  
    11/*
    22 * Copyright (C) 2005 Martin Decky
     3 * Copyright (C) 2005 Jakub Jermar
    34 * All rights reserved.
    45 *
     
    3132#include <arch.h>
    3233#include <debug.h>
    33 
    34 #define ASIDS   256
     34#include <typedefs.h>
    3535
    3636static spinlock_t asid_usage_lock;
     
    5454        spinlock_lock(&asid_usage_lock);
    5555       
    56         for (i=0, j = 0; (i<ASIDS); i++) {
     56        for (i = ASID_START, j = ASID_START; i < ASIDS; i++) {
    5757                if (asid_usage[i] < min) {
    5858                        j = i;
     
    6363        }
    6464
    65         asid_usage[i]++;
     65        asid_usage[j]++;
    6666
    6767        spinlock_unlock(&asid_usage_lock);
     
    8484        spinlock_lock(&asid_usage_lock);
    8585
     86        ASSERT(asid != ASID_INVALID);
     87       
    8688        ASSERT(asid_usage[asid] > 0);
    8789        asid_usage[asid]--;
     
    9092        cpu_priority_restore(pri);
    9193}
     94
     95/** Find out whether ASID is used by more address spaces
     96 *
     97 * Find out whether ASID is used by more address spaces.
     98 *
     99 * @param asid ASID in question.
     100 *
     101 * @return True if 'asid' is used by more address spaces, false otherwise.
     102 */
     103bool asid_has_conflicts(asid_t asid)
     104{
     105        bool has_conflicts = false;
     106        pri_t pri;
     107
     108        ASSERT(asid != ASID_INVALID);
     109
     110        pri = cpu_priority_high();
     111        spinlock_lock(&asid_usage_lock);
     112
     113        if (asid_usage[asid] > 1)
     114                has_conflicts = true;
     115
     116        spinlock_unlock(&asid_usage_lock);
     117        cpu_priority_restore(pri);
     118
     119        return has_conflicts;
     120}
  • arch/mips32/src/mm/tlb.c

    rbca1b47 rcc205f1  
    3838#include <synch/spinlock.h>
    3939#include <print.h>
     40#include <debug.h>
    4041
    4142static void tlb_refill_fail(struct exception_regdump *pstate);
     
    4445
    4546static pte_t *find_mapping_and_check(__address badvaddr);
    46 static void prepare_entry_lo(struct entry_lo *lo, bool g, bool v, bool d, int c, __address pfn);
     47static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn);
    4748
    4849/** Initialize TLB
     
    8384void tlb_refill(struct exception_regdump *pstate)
    8485{
    85         struct entry_lo lo;
     86        entry_lo_t lo;
    8687        __address badvaddr;
    8788        pte_t *pte;
     
    105106         */
    106107        if ((badvaddr/PAGE_SIZE) % 2 == 0) {
    107                 cp0_entry_lo0_write(*((__u32 *) &lo));
     108                cp0_entry_lo0_write(lo.value);
    108109                cp0_entry_lo1_write(0);
    109110        }
    110111        else {
    111112                cp0_entry_lo0_write(0);
    112                 cp0_entry_lo1_write(*((__u32 *) &lo));
     113                cp0_entry_lo1_write(lo.value);
    113114        }
    114115        tlbwr();
     
    130131void tlb_invalid(struct exception_regdump *pstate)
    131132{
    132         struct index index;
     133        tlb_index_t index;
    133134        __address badvaddr;
    134         struct entry_lo lo;
     135        entry_lo_t lo;
    135136        pte_t *pte;
    136137
     
    141142         */
    142143        tlbp();
    143         *((__u32 *) &index) = cp0_index_read();
     144        index.value = cp0_index_read();
    144145       
    145146        spinlock_lock(&VM->lock);       
     
    148149         * Fail if the entry is not in TLB.
    149150         */
    150         if (index.p)
    151                 goto fail;
     151        if (index.p) {
     152                printf("TLB entry not found.\n");
     153                goto fail;
     154        }
    152155
    153156        pte = find_mapping_and_check(badvaddr);
     
    171174         */
    172175        if ((badvaddr/PAGE_SIZE) % 2 == 0)
    173                 cp0_entry_lo0_write(*((__u32 *) &lo));
     176                cp0_entry_lo0_write(lo.value);
    174177        else
    175                 cp0_entry_lo1_write(*((__u32 *) &lo));
     178                cp0_entry_lo1_write(lo.value);
    176179        tlbwi();
    177180
     
    190193 * @param pstate Interrupted register context.
    191194 */
    192 
    193195void tlb_modified(struct exception_regdump *pstate)
    194196{
    195         struct index index;
     197        tlb_index_t index;
    196198        __address badvaddr;
    197         struct entry_lo lo;
     199        entry_lo_t lo;
    198200        pte_t *pte;
    199201
     
    204206         */
    205207        tlbp();
    206         *((__u32 *) &index) = cp0_index_read();
     208        index.value = cp0_index_read();
    207209       
    208210        spinlock_lock(&VM->lock);       
     
    211213         * Fail if the entry is not in TLB.
    212214         */
    213         if (index.p)
    214                 goto fail;
     215        if (index.p) {
     216                printf("TLB entry not found.\n");
     217                goto fail;
     218        }
    215219
    216220        pte = find_mapping_and_check(badvaddr);
     
    241245         */
    242246        if ((badvaddr/PAGE_SIZE) % 2 == 0)
    243                 cp0_entry_lo0_write(*((__u32 *) &lo));
     247                cp0_entry_lo0_write(lo.value);
    244248        else
    245                 cp0_entry_lo1_write(*((__u32 *) &lo));
     249                cp0_entry_lo1_write(lo.value);
    246250        tlbwi();
    247251
     
    289293}
    290294
    291 
    292 void tlb_invalidate(int asid)
    293 {
     295/** Invalidate TLB entries with specified ASID
     296 *
     297 * Invalidate TLB entries with specified ASID.
     298 *
     299 * @param asid ASID.
     300 */
     301void tlb_invalidate(asid_t asid)
     302{
     303        entry_hi_t hi;
    294304        pri_t pri;
    295        
     305        int i; 
     306       
     307        ASSERT(asid != ASID_INVALID);
     308
    296309        pri = cpu_priority_high();
    297310       
    298         // TODO
     311        for (i = 0; i < TLB_SIZE; i++) {
     312                cp0_index_write(i);
     313                tlbr();
     314               
     315                hi.value = cp0_entry_hi_read();
     316                if (hi.asid == asid) {
     317                        cp0_pagemask_write(TLB_PAGE_MASK_16K);
     318                        cp0_entry_hi_write(0);
     319                        cp0_entry_lo0_write(0);
     320                        cp0_entry_lo1_write(0);
     321                        tlbwi();
     322                }
     323        }
    299324       
    300325        cpu_priority_restore(pri);
     
    312337pte_t *find_mapping_and_check(__address badvaddr)
    313338{
    314         struct entry_hi hi;
     339        entry_hi_t hi;
    315340        pte_t *pte;
    316341
    317         *((__u32 *) &hi) = cp0_entry_hi_read();
     342        hi.value = cp0_entry_hi_read();
    318343
    319344        /*
    320345         * Handler cannot succeed if the ASIDs don't match.
    321346         */
    322         if (hi.asid != VM->asid)
     347        if (hi.asid != VM->asid) {
     348                printf("EntryHi.asid=%d, VM->asid=%d\n", hi.asid, VM->asid);
    323349                return NULL;
     350        }
    324351       
    325352        /*
     
    327354         */
    328355        pte = find_mapping(badvaddr, 0);
    329         if (!pte)
     356        if (!pte) {
     357                printf("No such mapping.\n");
    330358                return NULL;
     359        }
    331360
    332361        /*
    333362         * Handler cannot succeed if the mapping is marked as invalid.
    334363         */
    335         if (!pte->v)
     364        if (!pte->v) {
     365                printf("Invalid mapping.\n");
    336366                return NULL;
     367        }
    337368
    338369        return pte;
    339370}
    340371
    341 void prepare_entry_lo(struct entry_lo *lo, bool g, bool v, bool d, int c, __address pfn)
     372void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
    342373{
    343374        lo->g = g;
  • arch/mips32/src/mm/vm.c

    rbca1b47 rcc205f1  
    3232#include <arch/cp0.h>
    3333#include <arch.h>
    34 #include <print.h>
    3534
    3635/** Install ASID of the current VM
     
    4241void vm_install_arch(vm_t *vm)
    4342{
    44         struct entry_hi hi;
     43        entry_hi_t hi;
    4544        pri_t pri;
    4645       
    47         *((__u32 *) &hi) = cp0_entry_hi_read();
     46        hi.value = cp0_entry_hi_read();
    4847
    4948        pri = cpu_priority_high();
  • include/mm/tlb.h

    rbca1b47 rcc205f1  
    3030#define __TLB_H__
    3131
     32#include <arch/mm/asid.h>
     33
    3234extern void tlb_init(void);
    3335
     
    4446/* Export TLB interface that each architecture must implement. */
    4547extern void tlb_init_arch(void);
    46 extern void tlb_invalidate(int asid);
     48extern void tlb_invalidate(asid_t asid);
    4749extern void tlb_shootdown_ipi_send(void);
    4850
Note: See TracChangeset for help on using the changeset viewer.