Subversion Repositories HelenOS

Rev

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

Rev 3836 Rev 3837
Line 40... Line 40...
40
#include <arch.h>
40
#include <arch.h>
41
#include <print.h>
41
#include <print.h>
42
#include <symtab.h>
42
#include <symtab.h>
43
 
43
 
44
 
44
 
-
 
45
static unsigned int seed = 10;
-
 
46
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
-
 
47
 
-
 
48
 
45
/** Try to find PTE for faulting address
49
/** Try to find PTE for faulting address
46
 *
50
 *
47
 * Try to find PTE for faulting address.
51
 * Try to find PTE for faulting address.
48
 * The as->lock must be held on entry to this function
52
 * The as->lock must be held on entry to this function
49
 * if lock is true.
53
 * if lock is true.
Line 123... Line 127...
123
    panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
127
    panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
124
        istate->pc, symbol, sym2);
128
        istate->pc, symbol, sym2);
125
}
129
}
126
 
130
 
127
 
131
 
-
 
132
/** Pseudorandom generator
-
 
133
 *
-
 
134
 * A pretty standard linear congruential pseudorandom
-
 
135
 * number generator (m = 2^32).
-
 
136
 *
-
 
137
 */
-
 
138
#define RANDI(seed) \
-
 
139
    ({ \
-
 
140
        (seed) = 1103515245 * (seed) + 12345; \
-
 
141
        (seed); \
-
 
142
    })
-
 
143
 
-
 
144
 
128
static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
145
static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
129
{
146
{
130
    uint32_t page = (vaddr >> 12) & 0xffff;
147
    uint32_t page = (vaddr >> 12) & 0xffff;
131
    uint32_t api = (vaddr >> 22) & 0x3f;
148
    uint32_t api = (vaddr >> 22) & 0x3f;
132
   
149
   
Line 178... Line 195...
178
                break;
195
                break;
179
            }
196
            }
180
        }
197
        }
181
       
198
       
182
        if (!found)
199
        if (!found)
183
            i = page % 8;
200
            i = RANDI(seed) % 8;
184
    }
201
    }
185
   
202
   
186
   
-
 
187
   
-
 
188
    phte[base + i].v = 1;
203
    phte[base + i].v = 1;
189
    phte[base + i].vsid = vsid;
204
    phte[base + i].vsid = vsid;
190
    phte[base + i].h = h;
205
    phte[base + i].h = h;
191
    phte[base + i].api = api;
206
    phte[base + i].api = api;
192
    phte[base + i].rpn = pte->pfn;
207
    phte[base + i].rpn = pte->pfn;
Line 195... Line 210...
195
    phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
210
    phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
196
    phte[base + i].pp = 2; // FIXME
211
    phte[base + i].pp = 2; // FIXME
197
}
212
}
198
 
213
 
199
 
214
 
200
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
-
 
201
{
-
 
202
    uint32_t page = (vaddr >> 12) & 0xffff;
-
 
203
    uint32_t api = (vaddr >> 22) & 0x3f;
-
 
204
   
-
 
205
    uint32_t vsid;
-
 
206
    asm volatile (
-
 
207
        "mfsrin %0, %1\n"
-
 
208
        : "=r" (vsid)
-
 
209
        : "r" (vaddr)
-
 
210
    );
-
 
211
   
-
 
212
    uint32_t sdr1;
-
 
213
    asm volatile (
-
 
214
        "mfsdr1 %0\n"
-
 
215
        : "=r" (sdr1)
-
 
216
    );
-
 
217
    phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
-
 
218
   
-
 
219
    /* Primary hash (xor) */
-
 
220
    uint32_t h = 0;
-
 
221
    uint32_t hash = vsid ^ page;
-
 
222
    uint32_t base = (hash & 0x3ff) << 3;
-
 
223
    uint32_t i;
-
 
224
    bool found = false;
-
 
225
   
-
 
226
    /* Find unused or colliding PTE in PTEG */
-
 
227
    for (i = 0; i < 8; i++) {
-
 
228
        if ((!phte_physical[base + i].v) ||
-
 
229
            ((phte_physical[base + i].vsid == vsid)
-
 
230
            && (phte_physical[base + i].api == api)
-
 
231
            && (phte_physical[base + i].h == 0))) {
-
 
232
            found = true;
-
 
233
            break;
-
 
234
        }
-
 
235
    }
-
 
236
   
-
 
237
    if (!found) {
-
 
238
        /* Secondary hash (not) */
-
 
239
        uint32_t base2 = (~hash & 0x3ff) << 3;
-
 
240
       
-
 
241
        /* Find unused or colliding PTE in PTEG */
-
 
242
        for (i = 0; i < 8; i++) {
-
 
243
            if ((!phte_physical[base2 + i].v) ||
-
 
244
                ((phte_physical[base2 + i].vsid == vsid)
-
 
245
                && (phte_physical[base2 + i].api == api)
-
 
246
                && (phte_physical[base2 + i].h == 1))) {
-
 
247
                found = true;
-
 
248
                base = base2;
-
 
249
                h = 1;
-
 
250
                break;
-
 
251
            }
-
 
252
        }
-
 
253
       
-
 
254
        if (!found) {
-
 
255
            i = page % 8;
-
 
256
            base = base2;
-
 
257
            h = 1;
-
 
258
        }
-
 
259
    }
-
 
260
   
-
 
261
    phte_physical[base + i].v = 1;
-
 
262
    phte_physical[base + i].vsid = vsid;
-
 
263
    phte_physical[base + i].h = h;
-
 
264
    phte_physical[base + i].api = api;
-
 
265
    phte_physical[base + i].rpn = pfn;
-
 
266
    phte_physical[base + i].r = 0;
-
 
267
    phte_physical[base + i].c = 0;
-
 
268
    phte_physical[base + i].wimg = 0;
-
 
269
    phte_physical[base + i].pp = 2; // FIXME
-
 
270
}
-
 
271
 
-
 
272
 
-
 
273
/** Process Instruction/Data Storage Interrupt
215
/** Process Instruction/Data Storage Interrupt
274
 *
216
 *
275
 * @param n     Interrupt vector number.
217
 * @param n     Interrupt vector number.
276
 * @param istate    Interrupted register context.
218
 * @param istate    Interrupted register context.
277
 *
219
 *
Line 334... Line 276...
334
 *
276
 *
335
 * @param n     Interrupt vector number.
277
 * @param n     Interrupt vector number.
336
 * @param istate    Interrupted register context.
278
 * @param istate    Interrupted register context.
337
 *
279
 *
338
 */
280
 */
339
bool pht_real_refill(int n, istate_t *istate)
281
bool pht_refill_real(int n, istate_t *istate)
340
{
282
{
341
    uintptr_t badvaddr;
283
    uintptr_t badvaddr;
342
   
284
   
343
    if (n == VECTOR_DATA_STORAGE)
285
    if (n == VECTOR_DATA_STORAGE)
344
        badvaddr = istate->dar;
286
        badvaddr = istate->dar;
Line 349... Line 291...
349
    asm volatile (
291
    asm volatile (
350
        "mfsprg3 %0\n"
292
        "mfsprg3 %0\n"
351
        : "=r" (physmem)
293
        : "=r" (physmem)
352
    );
294
    );
353
   
295
   
354
    if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
296
    if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
-
 
297
        return false;
-
 
298
   
-
 
299
    uint32_t page = (badvaddr >> 12) & 0xffff;
355
        pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
300
    uint32_t api = (badvaddr >> 22) & 0x3f;
-
 
301
   
-
 
302
    uint32_t vsid;
-
 
303
    asm volatile (
-
 
304
        "mfsrin %0, %1\n"
-
 
305
        : "=r" (vsid)
-
 
306
        : "r" (badvaddr)
-
 
307
    );
-
 
308
   
-
 
309
    uint32_t sdr1;
-
 
310
    asm volatile (
-
 
311
        "mfsdr1 %0\n"
-
 
312
        : "=r" (sdr1)
-
 
313
    );
-
 
314
    phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
-
 
315
   
-
 
316
    /* Primary hash (xor) */
-
 
317
    uint32_t h = 0;
-
 
318
    uint32_t hash = vsid ^ page;
-
 
319
    uint32_t base = (hash & 0x3ff) << 3;
-
 
320
    uint32_t i;
-
 
321
    bool found = false;
-
 
322
   
-
 
323
    /* Find unused or colliding PTE in PTEG */
-
 
324
    for (i = 0; i < 8; i++) {
-
 
325
        if ((!phte_real[base + i].v) ||
-
 
326
            ((phte_real[base + i].vsid == vsid)
-
 
327
            && (phte_real[base + i].api == api)
-
 
328
            && (phte_real[base + i].h == 0))) {
356
        return true;
329
            found = true;
-
 
330
            break;
-
 
331
        }
357
    }
332
    }
358
   
333
   
-
 
334
    if (!found) {
-
 
335
        /* Secondary hash (not) */
-
 
336
        uint32_t base2 = (~hash & 0x3ff) << 3;
-
 
337
       
-
 
338
        /* Find unused or colliding PTE in PTEG */
-
 
339
        for (i = 0; i < 8; i++) {
-
 
340
            if ((!phte_real[base2 + i].v) ||
-
 
341
                ((phte_real[base2 + i].vsid == vsid)
-
 
342
                && (phte_real[base2 + i].api == api)
-
 
343
                && (phte_real[base2 + i].h == 1))) {
-
 
344
                found = true;
-
 
345
                base = base2;
-
 
346
                h = 1;
-
 
347
                break;
-
 
348
            }
-
 
349
        }
-
 
350
       
-
 
351
        if (!found) {
-
 
352
            /* Use secondary hash to avoid collisions
-
 
353
               with usual PHT refill handler. */
-
 
354
            i = RANDI(seed_real) % 8;
-
 
355
            base = base2;
-
 
356
            h = 1;
-
 
357
        }
-
 
358
    }
-
 
359
   
-
 
360
    phte_real[base + i].v = 1;
-
 
361
    phte_real[base + i].vsid = vsid;
-
 
362
    phte_real[base + i].h = h;
-
 
363
    phte_real[base + i].api = api;
-
 
364
    phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
-
 
365
    phte_real[base + i].r = 0;
-
 
366
    phte_real[base + i].c = 0;
-
 
367
    phte_real[base + i].wimg = 0;
-
 
368
    phte_real[base + i].pp = 2; // FIXME
-
 
369
   
359
    return false;
370
    return true;
360
}
371
}
361
 
372
 
362
 
373
 
363
void tlb_arch_init(void)
374
void tlb_arch_init(void)
364
{
375
{
Line 436... Line 447...
436
        asm volatile (
447
        asm volatile (
437
            "mfsrin %0, %1\n"
448
            "mfsrin %0, %1\n"
438
            : "=r" (vsid)
449
            : "=r" (vsid)
439
            : "r" (sr << 28)
450
            : "r" (sr << 28)
440
        );
451
        );
441
        printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr,
452
        printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
442
            sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
453
            sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
443
            ((vsid >> 30) & 1) ? " supervisor" : "",
454
            ((vsid >> 30) & 1) ? " supervisor" : "",
444
            ((vsid >> 29) & 1) ? " user" : "");
455
            ((vsid >> 29) & 1) ? " user" : "");
445
    }
456
    }
446
   
457