Subversion Repositories HelenOS

Rev

Rev 389 | Rev 394 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 389 Rev 391
Line 27... Line 27...
27
 */
27
 */
28
 
28
 
29
#include <arch/mm/tlb.h>
29
#include <arch/mm/tlb.h>
30
#include <arch/mm/asid.h>
30
#include <arch/mm/asid.h>
31
#include <mm/tlb.h>
31
#include <mm/tlb.h>
-
 
32
#include <mm/page.h>
-
 
33
#include <mm/vm.h>
32
#include <arch/cp0.h>
34
#include <arch/cp0.h>
33
#include <panic.h>
35
#include <panic.h>
34
#include <arch.h>
36
#include <arch.h>
35
#include <symtab.h>
37
#include <symtab.h>
-
 
38
#include <synch/spinlock.h>
-
 
39
#include <print.h>
36
 
40
 
-
 
41
static void tlb_refill_fail(struct exception_regdump *pstate);
-
 
42
static void tlb_invalid_fail(struct exception_regdump *pstate);
-
 
43
static 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
 */
37
void tlb_init_arch(void)
50
void tlb_init_arch(void)
38
{
51
{
39
    int i;
52
    int i;
40
 
53
 
41
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
54
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
Line 45... Line 58...
45
 
58
 
46
    /*
59
    /*
47
     * Invalidate all entries.
60
     * Invalidate all entries.
48
     */
61
     */
49
    for (i = 0; i < TLB_SIZE; i++) {
62
    for (i = 0; i < TLB_SIZE; i++) {
50
        cp0_index_write(0);
63
        cp0_index_write(i);
51
        tlbwi();
64
        tlbwi();
52
    }
65
    }
53
   
66
   
54
    /*
67
    /*
55
     * The kernel is going to make use of some wired
68
     * 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).
57
     */
70
     */
58
    cp0_wired_write(TLB_WIRED);
71
    cp0_wired_write(TLB_WIRED);
59
}
72
}
60
 
73
 
-
 
74
/** Process TLB Refill Exception
-
 
75
 *
-
 
76
 * Process TLB Refill Exception.
-
 
77
 *
-
 
78
 * @param pstate Interrupted register context.
-
 
79
 */
61
void tlb_refill(struct exception_regdump *pstate)
80
void tlb_refill(struct exception_regdump *pstate)
62
{
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
   
-
 
128
fail:
-
 
129
    spinlock_unlock(&VM->lock);
-
 
130
    tlb_refill_fail(pstate);
-
 
131
}
-
 
132
 
-
 
133
void tlb_invalid(struct exception_regdump *pstate)
-
 
134
{
-
 
135
    tlb_invalid_fail(pstate);
-
 
136
}
-
 
137
 
-
 
138
void tlb_modified(struct exception_regdump *pstate)
-
 
139
{
-
 
140
    tlb_modified_fail(pstate);
-
 
141
}
-
 
142
 
-
 
143
void tlb_refill_fail(struct exception_regdump *pstate)
-
 
144
{
63
    char *symbol = "";
145
    char *symbol = "";
64
    char *sym2 = "";
146
    char *sym2 = "";
65
 
147
 
66
    char *s = get_symtab_entry(pstate->epc);
148
    char *s = get_symtab_entry(pstate->epc);
67
    if (s)
149
    if (s)
68
        symbol = s;
150
        symbol = s;
69
    s = get_symtab_entry(pstate->ra);
151
    s = get_symtab_entry(pstate->ra);
70
    if (s)
152
    if (s)
71
        sym2 = s;
153
        sym2 = s;
72
    panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(),
154
    panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2);
73
          pstate->epc, symbol, sym2);
-
 
74
}
155
}
75
 
156
 
-
 
157
 
76
void tlb_invalid(struct exception_regdump *pstate)
158
void tlb_invalid_fail(struct exception_regdump *pstate)
77
{
159
{
78
    char *symbol = "";
160
    char *symbol = "";
79
 
161
 
80
    char *s = get_symtab_entry(pstate->epc);
162
    char *s = get_symtab_entry(pstate->epc);
81
    if (s)
163
    if (s)
82
        symbol = s;
164
        symbol = s;
83
    panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(),
165
    panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(),
84
          pstate->epc, symbol);
166
          pstate->epc, symbol);
85
}
167
}
86
 
168
 
87
void tlb_modified(struct exception_regdump *pstate)
169
void tlb_modified_fail(struct exception_regdump *pstate)
88
{
170
{
89
    char *symbol = "";
171
    char *symbol = "";
90
 
172
 
91
    char *s = get_symtab_entry(pstate->epc);
173
    char *s = get_symtab_entry(pstate->epc);
92
    if (s)
174
    if (s)
Line 100... Line 182...
100
{
182
{
101
    pri_t pri;
183
    pri_t pri;
102
   
184
   
103
    pri = cpu_priority_high();
185
    pri = cpu_priority_high();
104
   
186
   
105
//  asid_bitmap_reset();
-
 
106
   
-
 
107
    // TODO
187
    // TODO
108
   
188
   
109
    cpu_priority_restore(pri);
189
    cpu_priority_restore(pri);
110
}
190
}