Changeset 1084a784 in mainline


Ignore:
Timestamp:
2005-10-04T22:09:41Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
342de62
Parents:
8e3f47b3
Message:

mips32 memory management work.
TLB Refill Exception implemented (passed basic testing).
Remove bit g from struct entry_hi.
Add generic find_mapping().
Add asid to vm_t type, define asid_t to hide architecture specific differences.
Implement ASID allocation for mips32, dummy for other architectures.
Add THE→vm (a.k.a. VM).
Add vm_install_arch().
Move pte_t definition to arch/types.h on each architecture.
Fix PTL manipulating functions on mips32 to shift pfn by 12 instead of by 14.
Fix tlb_init_arch() to initialize all entries.

Other.
Remove unnecessary header files from arch.h
Add missing headers here and there.
Remove two unnecessary ld flags from mips32 makefile.

Files:
5 added
35 edited

Legend:

Unmodified
Added
Removed
  • arch/amd64/include/mm/page.h

    r8e3f47b3 r1084a784  
    7575#ifndef __ASM__
    7676
    77 typedef struct page_specifier pte_t;
    78 
    7977struct page_specifier {
    8078        unsigned present : 1;
  • arch/amd64/include/mm/vm.h

    r8e3f47b3 r1084a784  
    4141#define UDATA_ADDRESS_ARCH      0x21000000
    4242
     43#define vm_install_arch(vm)
     44
    4345#endif
  • arch/amd64/include/types.h

    r8e3f47b3 r1084a784  
    4646typedef __u64 __native;
    4747
     48typedef struct page_specifier pte_t;
     49
    4850#endif
  • arch/amd64/src/cpu/cpu.c

    r8e3f47b3 r1084a784  
    3535#include <print.h>
    3636#include <typedefs.h>
     37#include <fpu_context.h>
    3738
    3839/*
  • arch/amd64/src/interrupt.c

    r8e3f47b3 r1084a784  
    4040#include <arch/asm.h>
    4141#include <proc/scheduler.h>
     42#include <proc/thread.h>
    4243
    4344
  • arch/ia32/include/mm/page.h

    r8e3f47b3 r1084a784  
    9191} __attribute__ ((packed));
    9292
    93 typedef struct page_specifier pte_t;
    94 
    9593static inline int get_pt_flags(pte_t *pt, index_t i)
    9694{
  • arch/ia32/include/mm/vm.h

    r8e3f47b3 r1084a784  
    4141#define UDATA_ADDRESS_ARCH      0x21000000
    4242
     43#define vm_install_arch(vm)
     44
    4345#endif
  • arch/ia32/include/types.h

    r8e3f47b3 r1084a784  
    4545typedef __u32 __native;
    4646
     47typedef struct page_specifier pte_t;
     48
    4749#endif
  • arch/ia32/src/cpu/cpu.c

    r8e3f47b3 r1084a784  
    3535#include <print.h>
    3636#include <typedefs.h>
     37#include <fpu_context.h>
    3738
    3839#include <arch/smp/apic.h>
  • arch/ia32/src/interrupt.c

    r8e3f47b3 r1084a784  
    3838#include <arch.h>
    3939#include <symtab.h>
     40#include <proc/thread.h>
    4041
    4142/*
  • arch/ia64/include/mm/page.h

    r8e3f47b3 r1084a784  
    7171#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)
    7272
    73 typedef __u64 pte_t;
    74 
    7573#endif
  • arch/ia64/include/mm/vm.h

    r8e3f47b3 r1084a784  
    4141#define UDATA_ADDRESS_ARCH      0x0000000001001000
    4242
     43#define vm_install_arch(vm)
     44
    4345#endif
  • arch/ia64/include/types.h

    r8e3f47b3 r1084a784  
    4545typedef __u64 __native;
    4646
     47typedef __u64 pte_t;
     48
    4749#endif
  • arch/mips32/Makefile.inc

    r8e3f47b3 r1084a784  
    1111
    1212DEFS=-DARCH=$(ARCH) -DMACHINE=${MACHINE} -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS}
    13 CFLAGS=$(DEFS) -mno-abicalls -G 0 -nostdlib -fno-builtin -O2  -fno-zero-initialized-in-bss 
    14 LFLAGS=-M -N
     13CFLAGS=$(DEFS) -mno-abicalls -G 0 -nostdlib -fno-builtin -O2  -fno-zero-initialized-in-bss
     14LFLAGS=
    1515BFD_ARCH=mips
    1616
     
    8787        src/arch/cache.c \
    8888        src/arch/cpu/cpu.c \
     89        src/arch/mm/asid.c \
    8990        src/arch/mm/frame.c \
    9091        src/arch/mm/page.c \
    9192        src/arch/mm/tlb.c \
     93        src/arch/mm/vm.c \
    9294        src/arch/fpu_context.c \
    9395        src/arch/fmath.c \
  • arch/mips32/include/cp0.h

    r8e3f47b3 r1084a784  
    3131
    3232#include <arch/types.h>
     33#include <arch/mm/tlb.h>
    3334
    3435#define cp0_status_ie_enabled_bit       (1<<0)
  • arch/mips32/include/mm/asid.h

    r8e3f47b3 r1084a784  
    11/*
    2  * Copyright (C) 2005 Matrin Decky
     2 * Copyright (C) 2005 Martin Decky
    33 * All rights reserved.
    44 *
     
    3030#define __mips32_ASID_H__
    3131
    32 extern void asid_bitmap_reset(void);
     32#include <arch/types.h>
     33
     34typedef __u8 asid_t;
     35
     36extern asid_t asid_get(void);
     37extern void asid_put(asid_t asid);
    3338
    3439#endif
  • arch/mips32/include/mm/page.h

    r8e3f47b3 r1084a784  
    5757#define PTL1_INDEX_ARCH(vaddr)  0
    5858#define PTL2_INDEX_ARCH(vaddr)  0
    59 #define PTL3_INDEX_ARCH(vaddr)  (((vaddr)>>14)&0xfff)
     59#define PTL3_INDEX_ARCH(vaddr)  (((vaddr)>>12)&0xfff)
    6060
    6161#define GET_PTL0_ADDRESS_ARCH()                 (PTL0)
    6262#define SET_PTL0_ADDRESS_ARCH(ptl0)             (PTL0 = (pte_t *)(ptl0))
    6363
    64 #define GET_PTL1_ADDRESS_ARCH(ptl0, i)          (((pte_t *)(ptl0))[(i)].pfn<<14)
     64#define GET_PTL1_ADDRESS_ARCH(ptl0, i)          (((pte_t *)(ptl0))[(i)].pfn<<12)
    6565#define GET_PTL2_ADDRESS_ARCH(ptl1, i)          (ptl1)
    6666#define GET_PTL3_ADDRESS_ARCH(ptl2, i)          (ptl2)
    67 #define GET_FRAME_ADDRESS_ARCH(ptl3, i)         (((pte_t *)(ptl3))[(i)].pfn<<14)
     67#define GET_FRAME_ADDRESS_ARCH(ptl3, i)         (((pte_t *)(ptl3))[(i)].pfn<<12)
    6868
    69 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)       (((pte_t *)(ptl0))[(i)].pfn = (a)>>14)
     69#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)       (((pte_t *)(ptl0))[(i)].pfn = (a)>>12)
    7070#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
    7171#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
    72 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)      (((pte_t *)(ptl3))[(i)].pfn = (a)>>14)
     72#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)      (((pte_t *)(ptl3))[(i)].pfn = (a)>>12)
    7373
    7474#define GET_PTL1_FLAGS_ARCH(ptl0, i)            get_pt_flags((pte_t *)(ptl0), (index_t)(i))
  • arch/mips32/include/mm/tlb.h

    r8e3f47b3 r1084a784  
    5353struct entry_hi {
    5454        unsigned asid : 8;
    55         unsigned : 4;
    56         unsigned g : 1;
     55        unsigned : 5;
    5756        unsigned vpn2 : 19;
    5857} __attribute__ ((packed));
     
    7170} __attribute__ ((packed));
    7271
    73 typedef struct entry_lo pte_t;
    7472
    7573/** Read Indexed TLB Entry
  • arch/mips32/include/mm/vm.h

    r8e3f47b3 r1084a784  
    3131
    3232#include <arch/types.h>
     33#include <typedefs.h>
    3334
    3435#define KERNEL_ADDRESS_SPACE_START_ARCH         (__address) 0x80000000
     
    4142#define UDATA_ADDRESS_ARCH      0x01001000
    4243
     44extern void vm_install_arch(vm_t *vm);
     45
    4346#endif
  • arch/mips32/include/types.h

    r8e3f47b3 r1084a784  
    5050typedef __u32 __native;
    5151
     52typedef struct entry_lo pte_t;
     53
    5254#endif
  • arch/mips32/src/exception.c

    r8e3f47b3 r1084a784  
    3434#include <arch.h>
    3535#include <debug.h>
     36#include <proc/thread.h>
    3637
    3738void exception(struct exception_regdump *pstate)
  • arch/mips32/src/mips32.c

    r8e3f47b3 r1084a784  
    3838#include <arch/interrupt.h>
    3939#include <arch/drivers/arc.h>
    40 
     40#include <proc/thread.h>
    4141#include <print.h>
    4242
  • arch/mips32/src/mm/asid.c

    r8e3f47b3 r1084a784  
    2727 */
    2828
     29#include <arch/mm/asid.h>
     30#include <synch/spinlock.h>
    2931#include <arch.h>
    30 #include <memstr.h>
     32#include <debug.h>
    3133
    32 /**< Array of threads that have currently some ASID assigned,
    33      NULL means no thread have ASID with number of that index assigned */
    34 struct thread * asids[256];
    35 int last_asid; /**< The number of last assigned ASID */
    36 int asid_bitmap[32]; /**< Bitmap of ASIDs currently in TLB */
     34#define ASIDS   256
    3735
     36static spinlock_t asid_usage_lock;
     37static count_t asid_usage[ASIDS];       /**< Usage tracking array for ASIDs */
    3838
    39 /** Cleanup asid_bitmap
     39/** Get ASID
    4040 *
     41 * Get the least used ASID.
     42 *
     43 * @return ASID
    4144 */
    42 void asid_bitmap_reset(void)
     45asid_t asid_get(void)
    4346{
    44         memsetb(asid_bitmap, sizeof(asid_bitmap), 0);
     47        pri_t pri;
     48        int i, j;
     49        count_t min;
     50       
     51        min = (unsigned) -1;
     52       
     53        pri = cpu_priority_high();
     54        spinlock_lock(&asid_usage_lock);
     55       
     56        for (i=0, j = 0; (i<ASIDS); i++) {
     57                if (asid_usage[i] < min) {
     58                        j = i;
     59                        min = asid_usage[i];
     60                        if (!min)
     61                                break;
     62                }
     63        }
     64
     65        asid_usage[i]++;
     66
     67        spinlock_unlock(&asid_usage_lock);
     68        cpu_priority_restore(pri);
     69
     70        return i;
    4571}
    4672
     73/** Release ASID
     74 *
     75 * Release ASID by decrementing its usage count.
     76 *
     77 * @param asid ASID.
     78 */
     79void asid_put(asid_t asid)
     80{
     81        pri_t pri;
    4782
    48 /** Initialize manipulating with ASIDs
    49  *
    50  */
    51 void init_asids(void)
    52 {
    53         memsetb(asids, sizeof(asids), 0);
    54         asid_bitmap_reset();
    55         last_asid = 0;
     83        pri = cpu_priority_high();
     84        spinlock_lock(&asid_usage_lock);
     85
     86        ASSERT(asid_usage[asid] > 0);
     87        asid_usage[asid]--;
     88
     89        spinlock_unlock(&asid_usage_lock);
     90        cpu_priority_restore(pri);
    5691}
  • arch/mips32/src/mm/tlb.c

    r8e3f47b3 r1084a784  
    3030#include <arch/mm/asid.h>
    3131#include <mm/tlb.h>
     32#include <mm/page.h>
     33#include <mm/vm.h>
    3234#include <arch/cp0.h>
    3335#include <panic.h>
    3436#include <arch.h>
    3537#include <symtab.h>
     38#include <synch/spinlock.h>
     39#include <print.h>
    3640
     41static void tlb_refill_fail(struct exception_regdump *pstate);
     42static void tlb_invalid_fail(struct exception_regdump *pstate);
     43static void tlb_modified_fail(struct exception_regdump *pstate);
     44
     45/** Initialize TLB
     46 *
     47 * Initialize TLB.
     48 * Invalidate all entries and mark wired entries.
     49 */
    3750void tlb_init_arch(void)
    3851{
     
    4861         */
    4962        for (i = 0; i < TLB_SIZE; i++) {
    50                 cp0_index_write(0);
     63                cp0_index_write(i);
    5164                tlbwi();
    5265        }
     
    5467        /*
    5568         * The kernel is going to make use of some wired
    56          * entries (e.g. mapping kernel stacks).
     69         * entries (e.g. mapping kernel stacks in kseg3).
    5770         */
    5871        cp0_wired_write(TLB_WIRED);
    5972}
    6073
     74/** Process TLB Refill Exception
     75 *
     76 * Process TLB Refill Exception.
     77 *
     78 * @param pstate Interrupted register context.
     79 */
    6180void tlb_refill(struct exception_regdump *pstate)
     81{
     82        struct entry_hi hi;
     83        __address badvaddr;
     84        pte_t *pte;
     85       
     86        *((__u32 *) &hi) = cp0_entry_hi_read();
     87        badvaddr = cp0_badvaddr_read();
     88       
     89        spinlock_lock(&VM->lock);
     90
     91        /*
     92         * Refill cannot succeed if the ASIDs don't match.
     93         */
     94        if (hi.asid != VM->asid)
     95                goto fail;
     96
     97        /*
     98         * Refill cannot succeed if badvaddr is not
     99         * associated with any mapping.
     100         */
     101        pte = find_mapping(badvaddr, 0);
     102        if (!pte)
     103                goto fail;
     104               
     105        /*
     106         * Refill cannot succeed if the mapping is marked as invalid.
     107         */
     108        if (!pte->v)
     109                goto fail;
     110
     111        /*
     112         * New entry is to be inserted into TLB
     113         */
     114        cp0_pagemask_write(TLB_PAGE_MASK_16K);
     115        if ((badvaddr/PAGE_SIZE) % 2 == 0) {
     116                cp0_entry_lo0_write(*((__u32 *) pte));
     117                cp0_entry_lo1_write(0);
     118        }
     119        else {
     120                cp0_entry_lo0_write(0);
     121                cp0_entry_lo1_write(*((__u32 *) pte));
     122        }
     123        tlbwr();
     124
     125        spinlock_unlock(&VM->lock);
     126        return;
     127       
     128fail:
     129        spinlock_unlock(&VM->lock);
     130        tlb_refill_fail(pstate);
     131}
     132
     133void tlb_invalid(struct exception_regdump *pstate)
     134{
     135        tlb_invalid_fail(pstate);
     136}
     137
     138void tlb_modified(struct exception_regdump *pstate)
     139{
     140        tlb_modified_fail(pstate);
     141}
     142
     143void tlb_refill_fail(struct exception_regdump *pstate)
    62144{
    63145        char *symbol = "";
     
    70152        if (s)
    71153                sym2 = s;
    72         panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(),
    73               pstate->epc, symbol, sym2);
     154        panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2);
    74155}
    75156
    76 void tlb_invalid(struct exception_regdump *pstate)
     157
     158void tlb_invalid_fail(struct exception_regdump *pstate)
    77159{
    78160        char *symbol = "";
     
    85167}
    86168
    87 void tlb_modified(struct exception_regdump *pstate)
     169void tlb_modified_fail(struct exception_regdump *pstate)
    88170{
    89171        char *symbol = "";
     
    103185        pri = cpu_priority_high();
    104186       
    105 //      asid_bitmap_reset();
    106        
    107187        // TODO
    108188       
  • arch/ppc32/include/mm/page.h

    r8e3f47b3 r1084a784  
    6969extern void page_arch_init(void);
    7070
    71 typedef __u32 pte_t;
    72 
    7371#endif
  • arch/ppc32/include/mm/vm.h

    r8e3f47b3 r1084a784  
    4141#define UDATA_ADDRESS_ARCH      0x21000000
    4242
     43#define vm_install_arch(vm)
     44
    4345#endif
  • arch/ppc32/include/types.h

    r8e3f47b3 r1084a784  
    4545typedef __u32 __native;
    4646
     47typedef __u32 pte_t;
     48
    4749#endif
  • include/arch.h

    r8e3f47b3 r1084a784  
    3737#include <arch/asm.h>
    3838
    39 #include <proc/thread.h>
    40 #include <proc/task.h>
    41 
    4239#define CPU                     THE->cpu
    4340#define THREAD                  THE->thread
    4441#define TASK                    THE->task
     42#define VM                      THE->vm
    4543#define PREEMPTION_DISABLED     THE->preemption_disabled
    4644
     
    5957        task_t *task;                   /* current task */
    6058        cpu_t *cpu;                     /* executing cpu */
     59        vm_t *vm;                       /* current vm */
    6160};
    6261
  • include/mm/page.h

    r8e3f47b3 r1084a784  
    109109extern void page_init(void);
    110110extern void map_page_to_frame(__address page, __address frame, int flags, __address root);
     111extern pte_t *find_mapping(__address page, __address root);
    111112extern void map_structure(__address s, size_t size);
    112113
  • include/mm/vm.h

    r8e3f47b3 r1084a784  
    3232#include <arch/mm/page.h>
    3333#include <arch/mm/vm.h>
     34#include <arch/mm/asid.h>
    3435#include <arch/types.h>
    3536#include <typedefs.h>
     
    7576        link_t vm_area_head;
    7677        pte_t *ptl0;
     78        asid_t asid;
    7779};
    7880
  • src/main/kinit.c

    r8e3f47b3 r1084a784  
    5454#include <test.h>
    5555#endif /* __TEST__ */
     56
     57#include <mm/frame.h>
    5658
    5759void kinit(void *arg)
  • src/mm/page.c

    r8e3f47b3 r1084a784  
    3434#include <arch/asm.h>
    3535#include <memstr.h>
    36 
    3736
    3837void page_init(void)
     
    110109        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
    111110}
     111
     112/** Find mapping for virtual page
     113 *
     114 * Find mapping for virtual page.
     115 *
     116 * @param page Virtual page.
     117 * @param root PTL0 address if non-zero.
     118 *
     119 * @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
     120 */
     121pte_t *find_mapping(__address page, __address root)
     122{
     123        pte_t *ptl0, *ptl1, *ptl2, *ptl3;
     124
     125        ptl0 = (pte_t *) PA2KA(root ? root : (__address) GET_PTL0_ADDRESS());
     126
     127        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
     128                return NULL;
     129
     130        ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
     131
     132        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
     133                return NULL;
     134
     135        ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
     136
     137        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
     138                return NULL;
     139
     140        ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
     141
     142        return &ptl3[PTL3_INDEX(page)];
     143}
  • src/mm/vm.c

    r8e3f47b3 r1084a784  
    3333#include <mm/heap.h>
    3434#include <arch/mm/page.h>
     35#include <arch/mm/asid.h>
     36#include <arch/mm/vm.h>
    3537#include <arch/types.h>
    3638#include <typedefs.h>
     
    5658                spinlock_initialize(&m->lock);
    5759                list_initialize(&m->vm_area_head);
     60
     61                m->asid = asid_get();
    5862
    5963                /*
     
    200204
    201205        cpu_priority_restore(pri);
    202 }
     206
     207        vm_install_arch(m);
     208       
     209        VM = m;
     210}
  • src/proc/the.c

    r8e3f47b3 r1084a784  
    4444        the->thread = NULL;
    4545        the->task = NULL;
     46        the->vm = NULL;
    4647}
    4748
  • src/time/clock.c

    r8e3f47b3 r1084a784  
    4040#include <list.h>
    4141#include <arch/atomic.h>
     42#include <proc/thread.h>
    4243
    4344/** Clock routine
Note: See TracChangeset for help on using the changeset viewer.