Subversion Repositories HelenOS-historic

Rev

Rev 389 | Rev 394 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 jermar 1
/*
319 jermar 2
 * Copyright (C) 2003-2004 Jakub Jermar
1 jermar 3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
#include <arch/mm/tlb.h>
130 decky 30
#include <arch/mm/asid.h>
1 jermar 31
#include <mm/tlb.h>
391 jermar 32
#include <mm/page.h>
33
#include <mm/vm.h>
1 jermar 34
#include <arch/cp0.h>
35
#include <panic.h>
36
#include <arch.h>
268 palkovsky 37
#include <symtab.h>
391 jermar 38
#include <synch/spinlock.h>
39
#include <print.h>
268 palkovsky 40
 
391 jermar 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
 */
389 jermar 50
void tlb_init_arch(void)
51
{
52
    int i;
53
 
54
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
55
    cp0_entry_hi_write(0);
56
    cp0_entry_lo0_write(0);
57
    cp0_entry_lo1_write(0);
58
 
59
    /*
60
     * Invalidate all entries.
61
     */
62
    for (i = 0; i < TLB_SIZE; i++) {
391 jermar 63
        cp0_index_write(i);
389 jermar 64
        tlbwi();
65
    }
66
 
67
    /*
68
     * The kernel is going to make use of some wired
391 jermar 69
     * entries (e.g. mapping kernel stacks in kseg3).
389 jermar 70
     */
71
    cp0_wired_write(TLB_WIRED);
72
}
73
 
391 jermar 74
/** Process TLB Refill Exception
75
 *
76
 * Process TLB Refill Exception.
77
 *
78
 * @param pstate Interrupted register context.
79
 */
317 palkovsky 80
void tlb_refill(struct exception_regdump *pstate)
1 jermar 81
{
391 jermar 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
{
324 palkovsky 145
    char *symbol = "";
146
    char *sym2 = "";
147
 
332 palkovsky 148
    char *s = get_symtab_entry(pstate->epc);
149
    if (s)
150
        symbol = s;
151
    s = get_symtab_entry(pstate->ra);
152
    if (s)
153
        sym2 = s;
391 jermar 154
    panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2);
1 jermar 155
}
156
 
391 jermar 157
 
158
void tlb_invalid_fail(struct exception_regdump *pstate)
1 jermar 159
{
268 palkovsky 160
    char *symbol = "";
161
 
332 palkovsky 162
    char *s = get_symtab_entry(pstate->epc);
163
    if (s)
164
        symbol = s;
389 jermar 165
    panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(),
317 palkovsky 166
          pstate->epc, symbol);
1 jermar 167
}
168
 
391 jermar 169
void tlb_modified_fail(struct exception_regdump *pstate)
389 jermar 170
{
171
    char *symbol = "";
172
 
173
    char *s = get_symtab_entry(pstate->epc);
174
    if (s)
175
        symbol = s;
176
    panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(),
177
          pstate->epc, symbol);
178
}
179
 
180
 
1 jermar 181
void tlb_invalidate(int asid)
182
{
130 decky 183
    pri_t pri;
184
 
185
    pri = cpu_priority_high();
186
 
187
    // TODO
188
 
189
    cpu_priority_restore(pri);
1 jermar 190
}