Subversion Repositories HelenOS-historic

Rev

Rev 396 | Rev 399 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 396 Rev 397
1
/*
1
/*
2
 * Copyright (C) 2003-2004 Jakub Jermar
2
 * Copyright (C) 2003-2004 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
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
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.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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>
32
#include <mm/page.h>
33
#include <mm/vm.h>
33
#include <mm/vm.h>
34
#include <arch/cp0.h>
34
#include <arch/cp0.h>
35
#include <panic.h>
35
#include <panic.h>
36
#include <arch.h>
36
#include <arch.h>
37
#include <symtab.h>
37
#include <symtab.h>
38
#include <synch/spinlock.h>
38
#include <synch/spinlock.h>
39
#include <print.h>
39
#include <print.h>
40
#include <debug.h>
40
#include <debug.h>
41
 
41
 
42
static void tlb_refill_fail(struct exception_regdump *pstate);
42
static void tlb_refill_fail(struct exception_regdump *pstate);
43
static void tlb_invalid_fail(struct exception_regdump *pstate);
43
static void tlb_invalid_fail(struct exception_regdump *pstate);
44
static void tlb_modified_fail(struct exception_regdump *pstate);
44
static void tlb_modified_fail(struct exception_regdump *pstate);
45
 
45
 
46
static pte_t *find_mapping_and_check(__address badvaddr);
46
static pte_t *find_mapping_and_check(__address badvaddr);
47
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn);
47
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn);
48
 
48
 
49
/** Initialize TLB
49
/** Initialize TLB
50
 *
50
 *
51
 * Initialize TLB.
51
 * Initialize TLB.
52
 * Invalidate all entries and mark wired entries.
52
 * Invalidate all entries and mark wired entries.
53
 */
53
 */
54
void tlb_init_arch(void)
54
void tlb_init_arch(void)
55
{
55
{
56
    int i;
56
    int i;
57
 
57
 
58
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
58
    cp0_pagemask_write(TLB_PAGE_MASK_16K);
59
    cp0_entry_hi_write(0);
59
    cp0_entry_hi_write(0);
60
    cp0_entry_lo0_write(0);
60
    cp0_entry_lo0_write(0);
61
    cp0_entry_lo1_write(0);
61
    cp0_entry_lo1_write(0);
62
 
62
 
63
    /*
63
    /*
64
     * Invalidate all entries.
64
     * Invalidate all entries.
65
     */
65
     */
66
    for (i = 0; i < TLB_SIZE; i++) {
66
    for (i = 0; i < TLB_SIZE; i++) {
67
        cp0_index_write(i);
67
        cp0_index_write(i);
68
        tlbwi();
68
        tlbwi();
69
    }
69
    }
70
   
70
   
71
    /*
71
    /*
72
     * The kernel is going to make use of some wired
72
     * The kernel is going to make use of some wired
73
     * entries (e.g. mapping kernel stacks in kseg3).
73
     * entries (e.g. mapping kernel stacks in kseg3).
74
     */
74
     */
75
    cp0_wired_write(TLB_WIRED);
75
    cp0_wired_write(TLB_WIRED);
76
}
76
}
77
 
77
 
78
/** Process TLB Refill Exception
78
/** Process TLB Refill Exception
79
 *
79
 *
80
 * Process TLB Refill Exception.
80
 * Process TLB Refill Exception.
81
 *
81
 *
82
 * @param pstate Interrupted register context.
82
 * @param pstate Interrupted register context.
83
 */
83
 */
84
void tlb_refill(struct exception_regdump *pstate)
84
void tlb_refill(struct exception_regdump *pstate)
85
{
85
{
86
    entry_lo_t lo;
86
    entry_lo_t lo;
87
    __address badvaddr;
87
    __address badvaddr;
88
    pte_t *pte;
88
    pte_t *pte;
-
 
89
 
-
 
90
// debug    
-
 
91
    entry_hi_t hi;
89
   
92
 
90
    badvaddr = cp0_badvaddr_read();
93
    badvaddr = cp0_badvaddr_read();
-
 
94
 
-
 
95
// debug
-
 
96
    hi.value = cp0_entry_hi_read();
-
 
97
    printf("TLB Refill: hi.vnp2=%X\n", hi.vpn2);
91
   
98
   
92
    spinlock_lock(&VM->lock);      
99
    spinlock_lock(&VM->lock);      
93
    pte = find_mapping_and_check(badvaddr);
100
    pte = find_mapping_and_check(badvaddr);
94
    if (!pte)
101
    if (!pte)
95
        goto fail;
102
        goto fail;
96
 
103
 
97
    /*
104
    /*
98
     * Record access to PTE.
105
     * Record access to PTE.
99
     */
106
     */
100
    pte->a = 1;
107
    pte->a = 1;
101
 
108
 
102
    prepare_entry_lo(&lo, pte->g, pte->v, pte->d, pte->c, pte->pfn);
109
    prepare_entry_lo(&lo, pte->g, pte->v, pte->d, pte->c, pte->pfn);
103
 
110
 
104
    /*
111
    /*
105
     * New entry is to be inserted into TLB
112
     * New entry is to be inserted into TLB
106
     */
113
     */
107
    if ((badvaddr/PAGE_SIZE) % 2 == 0) {
114
    if ((badvaddr/PAGE_SIZE) % 2 == 0) {
108
        cp0_entry_lo0_write(lo.value);
115
        cp0_entry_lo0_write(lo.value);
109
        cp0_entry_lo1_write(0);
116
        cp0_entry_lo1_write(0);
110
    }
117
    }
111
    else {
118
    else {
112
        cp0_entry_lo0_write(0);
119
        cp0_entry_lo0_write(0);
113
        cp0_entry_lo1_write(lo.value);
120
        cp0_entry_lo1_write(lo.value);
114
    }
121
    }
115
    tlbwr();
122
    tlbwr();
116
 
123
 
117
    spinlock_unlock(&VM->lock);
124
    spinlock_unlock(&VM->lock);
118
    return;
125
    return;
119
   
126
   
120
fail:
127
fail:
121
    spinlock_unlock(&VM->lock);
128
    spinlock_unlock(&VM->lock);
122
    tlb_refill_fail(pstate);
129
    tlb_refill_fail(pstate);
123
}
130
}
124
 
131
 
125
/** Process TLB Invalid Exception
132
/** Process TLB Invalid Exception
126
 *
133
 *
127
 * Process TLB Invalid Exception.
134
 * Process TLB Invalid Exception.
128
 *
135
 *
129
 * @param pstate Interrupted register context.
136
 * @param pstate Interrupted register context.
130
 */
137
 */
131
void tlb_invalid(struct exception_regdump *pstate)
138
void tlb_invalid(struct exception_regdump *pstate)
132
{
139
{
133
    tlb_index_t index;
140
    tlb_index_t index;
134
    __address badvaddr;
141
    __address badvaddr;
135
    entry_lo_t lo;
142
    entry_lo_t lo;
136
    pte_t *pte;
143
    pte_t *pte;
137
 
144
 
138
    badvaddr = cp0_badvaddr_read();
145
    badvaddr = cp0_badvaddr_read();
139
 
146
 
140
    /*
147
    /*
141
     * Locate the faulting entry in TLB.
148
     * Locate the faulting entry in TLB.
142
     */
149
     */
143
    tlbp();
150
    tlbp();
144
    index.value = cp0_index_read();
151
    index.value = cp0_index_read();
145
   
152
   
146
    spinlock_lock(&VM->lock);  
153
    spinlock_lock(&VM->lock);  
147
   
154
   
148
    /*
155
    /*
149
     * Fail if the entry is not in TLB.
156
     * Fail if the entry is not in TLB.
150
     */
157
     */
151
    if (index.p) {
158
    if (index.p) {
152
        printf("TLB entry not found.\n");
159
        printf("TLB entry not found.\n");
153
        goto fail;
160
        goto fail;
154
    }
161
    }
155
 
162
 
156
    pte = find_mapping_and_check(badvaddr);
163
    pte = find_mapping_and_check(badvaddr);
157
    if (!pte)
164
    if (!pte)
158
        goto fail;
165
        goto fail;
159
 
166
 
160
    /*
167
    /*
161
     * Read the faulting TLB entry.
168
     * Read the faulting TLB entry.
162
     */
169
     */
163
    tlbr();
170
    tlbr();
164
 
171
 
165
    /*
172
    /*
166
     * Record access to PTE.
173
     * Record access to PTE.
167
     */
174
     */
168
    pte->a = 1;
175
    pte->a = 1;
169
 
176
 
170
    prepare_entry_lo(&lo, pte->g, pte->v, pte->d, pte->c, pte->pfn);
177
    prepare_entry_lo(&lo, pte->g, pte->v, pte->d, pte->c, pte->pfn);
171
 
178
 
172
    /*
179
    /*
173
     * The entry is to be updated in TLB.
180
     * The entry is to be updated in TLB.
174
     */
181
     */
175
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
182
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
176
        cp0_entry_lo0_write(lo.value);
183
        cp0_entry_lo0_write(lo.value);
177
    else
184
    else
178
        cp0_entry_lo1_write(lo.value);
185
        cp0_entry_lo1_write(lo.value);
179
    tlbwi();
186
    tlbwi();
180
 
187
 
181
    spinlock_unlock(&VM->lock);
188
    spinlock_unlock(&VM->lock);
182
    return;
189
    return;
183
   
190
   
184
fail:
191
fail:
185
    spinlock_unlock(&VM->lock);
192
    spinlock_unlock(&VM->lock);
186
    tlb_invalid_fail(pstate);
193
    tlb_invalid_fail(pstate);
187
}
194
}
188
 
195
 
189
/** Process TLB Modified Exception
196
/** Process TLB Modified Exception
190
 *
197
 *
191
 * Process TLB Modified Exception.
198
 * Process TLB Modified Exception.
192
 *
199
 *
193
 * @param pstate Interrupted register context.
200
 * @param pstate Interrupted register context.
194
 */
201
 */
195
void tlb_modified(struct exception_regdump *pstate)
202
void tlb_modified(struct exception_regdump *pstate)
196
{
203
{
197
    tlb_index_t index;
204
    tlb_index_t index;
198
    __address badvaddr;
205
    __address badvaddr;
199
    entry_lo_t lo;
206
    entry_lo_t lo;
200
    pte_t *pte;
207
    pte_t *pte;
201
 
208
 
202
    badvaddr = cp0_badvaddr_read();
209
    badvaddr = cp0_badvaddr_read();
203
 
210
 
204
    /*
211
    /*
205
     * Locate the faulting entry in TLB.
212
     * Locate the faulting entry in TLB.
206
     */
213
     */
207
    tlbp();
214
    tlbp();
208
    index.value = cp0_index_read();
215
    index.value = cp0_index_read();
209
   
216
   
210
    spinlock_lock(&VM->lock);  
217
    spinlock_lock(&VM->lock);  
211
   
218
   
212
    /*
219
    /*
213
     * Fail if the entry is not in TLB.
220
     * Fail if the entry is not in TLB.
214
     */
221
     */
215
    if (index.p) {
222
    if (index.p) {
216
        printf("TLB entry not found.\n");
223
        printf("TLB entry not found.\n");
217
        goto fail;
224
        goto fail;
218
    }
225
    }
219
 
226
 
220
    pte = find_mapping_and_check(badvaddr);
227
    pte = find_mapping_and_check(badvaddr);
221
    if (!pte)
228
    if (!pte)
222
        goto fail;
229
        goto fail;
223
 
230
 
224
    /*
231
    /*
225
     * Fail if the page is not writable.
232
     * Fail if the page is not writable.
226
     */
233
     */
227
    if (!pte->w)
234
    if (!pte->w)
228
        goto fail;
235
        goto fail;
229
 
236
 
230
    /*
237
    /*
231
     * Read the faulting TLB entry.
238
     * Read the faulting TLB entry.
232
     */
239
     */
233
    tlbr();
240
    tlbr();
234
 
241
 
235
    /*
242
    /*
236
     * Record access and write to PTE.
243
     * Record access and write to PTE.
237
     */
244
     */
238
    pte->a = 1;
245
    pte->a = 1;
239
    pte->d = 1;
246
    pte->d = 1;
240
 
247
 
241
    prepare_entry_lo(&lo, pte->g, pte->v, pte->w, pte->c, pte->pfn);
248
    prepare_entry_lo(&lo, pte->g, pte->v, pte->w, pte->c, pte->pfn);
242
 
249
 
243
    /*
250
    /*
244
     * The entry is to be updated in TLB.
251
     * The entry is to be updated in TLB.
245
     */
252
     */
246
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
253
    if ((badvaddr/PAGE_SIZE) % 2 == 0)
247
        cp0_entry_lo0_write(lo.value);
254
        cp0_entry_lo0_write(lo.value);
248
    else
255
    else
249
        cp0_entry_lo1_write(lo.value);
256
        cp0_entry_lo1_write(lo.value);
250
    tlbwi();
257
    tlbwi();
251
 
258
 
252
    spinlock_unlock(&VM->lock);
259
    spinlock_unlock(&VM->lock);
253
    return;
260
    return;
254
   
261
   
255
fail:
262
fail:
256
    spinlock_unlock(&VM->lock);
263
    spinlock_unlock(&VM->lock);
257
    tlb_modified_fail(pstate);
264
    tlb_modified_fail(pstate);
258
}
265
}
259
 
266
 
260
void tlb_refill_fail(struct exception_regdump *pstate)
267
void tlb_refill_fail(struct exception_regdump *pstate)
261
{
268
{
262
    char *symbol = "";
269
    char *symbol = "";
263
    char *sym2 = "";
270
    char *sym2 = "";
264
 
271
 
265
    char *s = get_symtab_entry(pstate->epc);
272
    char *s = get_symtab_entry(pstate->epc);
266
    if (s)
273
    if (s)
267
        symbol = s;
274
        symbol = s;
268
    s = get_symtab_entry(pstate->ra);
275
    s = get_symtab_entry(pstate->ra);
269
    if (s)
276
    if (s)
270
        sym2 = s;
277
        sym2 = s;
271
    panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2);
278
    panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2);
272
}
279
}
273
 
280
 
274
 
281
 
275
void tlb_invalid_fail(struct exception_regdump *pstate)
282
void tlb_invalid_fail(struct exception_regdump *pstate)
276
{
283
{
277
    char *symbol = "";
284
    char *symbol = "";
278
 
285
 
279
    char *s = get_symtab_entry(pstate->epc);
286
    char *s = get_symtab_entry(pstate->epc);
280
    if (s)
287
    if (s)
281
        symbol = s;
288
        symbol = s;
282
    panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
289
    panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
283
}
290
}
284
 
291
 
285
void tlb_modified_fail(struct exception_regdump *pstate)
292
void tlb_modified_fail(struct exception_regdump *pstate)
286
{
293
{
287
    char *symbol = "";
294
    char *symbol = "";
288
 
295
 
289
    char *s = get_symtab_entry(pstate->epc);
296
    char *s = get_symtab_entry(pstate->epc);
290
    if (s)
297
    if (s)
291
        symbol = s;
298
        symbol = s;
292
    panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
299
    panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol);
293
}
300
}
294
 
301
 
295
/** Invalidate TLB entries with specified ASID
302
/** Invalidate TLB entries with specified ASID
296
 *
303
 *
297
 * Invalidate TLB entries with specified ASID.
304
 * Invalidate TLB entries with specified ASID.
298
 *
305
 *
299
 * @param asid ASID.
306
 * @param asid ASID.
300
 */
307
 */
301
void tlb_invalidate(asid_t asid)
308
void tlb_invalidate(asid_t asid)
302
{
309
{
303
    entry_hi_t hi;
310
    entry_hi_t hi;
304
    pri_t pri;
311
    pri_t pri;
305
    int i; 
312
    int i; 
306
   
313
   
307
    ASSERT(asid != ASID_INVALID);
314
    ASSERT(asid != ASID_INVALID);
308
 
315
 
309
    pri = cpu_priority_high();
316
    pri = cpu_priority_high();
310
   
317
   
311
    for (i = 0; i < TLB_SIZE; i++) {
318
    for (i = 0; i < TLB_SIZE; i++) {
312
        cp0_index_write(i);
319
        cp0_index_write(i);
313
        tlbr();
320
        tlbr();
314
       
321
       
315
        hi.value = cp0_entry_hi_read();
322
        hi.value = cp0_entry_hi_read();
316
        if (hi.asid == asid) {
323
        if (hi.asid == asid) {
317
            cp0_pagemask_write(TLB_PAGE_MASK_16K);
324
            cp0_pagemask_write(TLB_PAGE_MASK_16K);
318
            cp0_entry_hi_write(0);
325
            cp0_entry_hi_write(0);
319
            cp0_entry_lo0_write(0);
326
            cp0_entry_lo0_write(0);
320
            cp0_entry_lo1_write(0);
327
            cp0_entry_lo1_write(0);
321
            tlbwi();
328
            tlbwi();
322
        }
329
        }
323
    }
330
    }
324
   
331
   
325
    cpu_priority_restore(pri);
332
    cpu_priority_restore(pri);
326
}
333
}
327
 
334
 
328
/** Try to find PTE for faulting address
335
/** Try to find PTE for faulting address
329
 *
336
 *
330
 * Try to find PTE for faulting address.
337
 * Try to find PTE for faulting address.
331
 * The VM->lock must be held on entry to this function.
338
 * The VM->lock must be held on entry to this function.
332
 *
339
 *
333
 * @param badvaddr Faulting virtual address.
340
 * @param badvaddr Faulting virtual address.
334
 *
341
 *
335
 * @return PTE on success, NULL otherwise.
342
 * @return PTE on success, NULL otherwise.
336
 */
343
 */
337
pte_t *find_mapping_and_check(__address badvaddr)
344
pte_t *find_mapping_and_check(__address badvaddr)
338
{
345
{
339
    entry_hi_t hi;
346
    entry_hi_t hi;
340
    pte_t *pte;
347
    pte_t *pte;
341
 
348
 
342
    hi.value = cp0_entry_hi_read();
349
    hi.value = cp0_entry_hi_read();
343
 
350
 
344
    /*
351
    /*
345
     * Handler cannot succeed if the ASIDs don't match.
352
     * Handler cannot succeed if the ASIDs don't match.
346
     */
353
     */
347
    if (hi.asid != VM->asid) {
354
    if (hi.asid != VM->asid) {
348
        printf("EntryHi.asid=%d, VM->asid=%d\n", hi.asid, VM->asid);
355
        printf("EntryHi.asid=%d, VM->asid=%d\n", hi.asid, VM->asid);
349
        return NULL;
356
        return NULL;
350
    }
357
    }
351
   
358
   
352
    /*
359
    /*
353
     * Handler cannot succeed if badvaddr has no mapping.
360
     * Handler cannot succeed if badvaddr has no mapping.
354
     */
361
     */
355
    pte = find_mapping(badvaddr, 0);
362
    pte = find_mapping(badvaddr, 0);
356
    if (!pte) {
363
    if (!pte) {
357
        printf("No such mapping.\n");
364
        printf("No such mapping.\n");
358
        return NULL;
365
        return NULL;
359
    }
366
    }
360
 
367
 
361
    /*
368
    /*
362
     * Handler cannot succeed if the mapping is marked as invalid.
369
     * Handler cannot succeed if the mapping is marked as invalid.
363
     */
370
     */
364
    if (!pte->v) {
371
    if (!pte->v) {
365
        printf("Invalid mapping.\n");
372
        printf("Invalid mapping.\n");
366
        return NULL;
373
        return NULL;
367
    }
374
    }
368
 
375
 
369
    return pte;
376
    return pte;
370
}
377
}
371
 
378
 
372
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
379
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
373
{
380
{
374
    lo->g = g;
381
    lo->g = g;
375
    lo->v = v;
382
    lo->v = v;
376
    lo->d = d;
383
    lo->d = d;
377
    lo->c = c;
384
    lo->c = c;
378
    lo->pfn = pfn;
385
    lo->pfn = pfn;
379
    lo->zero = 0;
386
    lo->zero = 0;
380
}
387
}
381
 
388