Subversion Repositories HelenOS-historic

Rev

Rev 1758 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1758 Rev 1780
Line 54... Line 54...
54
 * @param istate   Pointer to interrupted state.
54
 * @param istate   Pointer to interrupted state.
55
 * @param pfrc     Pointer to variable where as_page_fault() return code will be stored.
55
 * @param pfrc     Pointer to variable where as_page_fault() return code will be stored.
56
 * @return         PTE on success, NULL otherwise.
56
 * @return         PTE on success, NULL otherwise.
57
 *
57
 *
58
 */
58
 */
59
static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, istate_t *istate, int *pfrc)
59
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, istate_t *istate, int *pfrc)
60
{
60
{
61
    /*
61
    /*
62
     * Check if the mapping exists in page tables.
62
     * Check if the mapping exists in page tables.
63
     */
63
     */
64
    pte_t *pte = page_mapping_find(as, badvaddr);
64
    pte_t *pte = page_mapping_find(as, badvaddr);
Line 101... Line 101...
101
        }  
101
        }  
102
    }
102
    }
103
}
103
}
104
 
104
 
105
 
105
 
106
static void pht_refill_fail(__address badvaddr, istate_t *istate)
106
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
107
{
107
{
108
    char *symbol = "";
108
    char *symbol = "";
109
    char *sym2 = "";
109
    char *sym2 = "";
110
 
110
 
111
    char *s = get_symtab_entry(istate->pc);
111
    char *s = get_symtab_entry(istate->pc);
Line 116... Line 116...
116
        sym2 = s;
116
        sym2 = s;
117
    panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
117
    panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
118
}
118
}
119
 
119
 
120
 
120
 
121
static void pht_insert(const __address vaddr, const pfn_t pfn)
121
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn)
122
{
122
{
123
    __u32 page = (vaddr >> 12) & 0xffff;
123
    uint32_t page = (vaddr >> 12) & 0xffff;
124
    __u32 api = (vaddr >> 22) & 0x3f;
124
    uint32_t api = (vaddr >> 22) & 0x3f;
125
   
125
   
126
    __u32 vsid;
126
    uint32_t vsid;
127
    asm volatile (
127
    asm volatile (
128
        "mfsrin %0, %1\n"
128
        "mfsrin %0, %1\n"
129
        : "=r" (vsid)
129
        : "=r" (vsid)
130
        : "r" (vaddr)
130
        : "r" (vaddr)
131
    );
131
    );
132
   
132
   
133
    __u32 sdr1;
133
    uint32_t sdr1;
134
    asm volatile (
134
    asm volatile (
135
        "mfsdr1 %0\n"
135
        "mfsdr1 %0\n"
136
        : "=r" (sdr1)
136
        : "=r" (sdr1)
137
    );
137
    );
138
    phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
138
    phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
139
   
139
   
140
    /* Primary hash (xor) */
140
    /* Primary hash (xor) */
141
    __u32 h = 0;
141
    uint32_t h = 0;
142
    __u32 hash = vsid ^ page;
142
    uint32_t hash = vsid ^ page;
143
    __u32 base = (hash & 0x3ff) << 3;
143
    uint32_t base = (hash & 0x3ff) << 3;
144
    __u32 i;
144
    uint32_t i;
145
    bool found = false;
145
    bool found = false;
146
   
146
   
147
    /* Find unused or colliding
147
    /* Find unused or colliding
148
       PTE in PTEG */
148
       PTE in PTEG */
149
    for (i = 0; i < 8; i++) {
149
    for (i = 0; i < 8; i++) {
Line 153... Line 153...
153
        }
153
        }
154
    }
154
    }
155
   
155
   
156
    if (!found) {
156
    if (!found) {
157
        /* Secondary hash (not) */
157
        /* Secondary hash (not) */
158
        __u32 base2 = (~hash & 0x3ff) << 3;
158
        uint32_t base2 = (~hash & 0x3ff) << 3;
159
       
159
       
160
        /* Find unused or colliding
160
        /* Find unused or colliding
161
           PTE in PTEG */
161
           PTE in PTEG */
162
        for (i = 0; i < 8; i++) {
162
        for (i = 0; i < 8; i++) {
163
            if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {
163
            if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) {
Line 183... Line 183...
183
    phte[base + i].c = 0;
183
    phte[base + i].c = 0;
184
    phte[base + i].pp = 2; // FIXME
184
    phte[base + i].pp = 2; // FIXME
185
}
185
}
186
 
186
 
187
 
187
 
188
static void pht_real_insert(const __address vaddr, const pfn_t pfn)
188
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
189
{
189
{
190
    __u32 page = (vaddr >> 12) & 0xffff;
190
    uint32_t page = (vaddr >> 12) & 0xffff;
191
    __u32 api = (vaddr >> 22) & 0x3f;
191
    uint32_t api = (vaddr >> 22) & 0x3f;
192
   
192
   
193
    __u32 vsid;
193
    uint32_t vsid;
194
    asm volatile (
194
    asm volatile (
195
        "mfsrin %0, %1\n"
195
        "mfsrin %0, %1\n"
196
        : "=r" (vsid)
196
        : "=r" (vsid)
197
        : "r" (vaddr)
197
        : "r" (vaddr)
198
    );
198
    );
199
   
199
   
200
    __u32 sdr1;
200
    uint32_t sdr1;
201
    asm volatile (
201
    asm volatile (
202
        "mfsdr1 %0\n"
202
        "mfsdr1 %0\n"
203
        : "=r" (sdr1)
203
        : "=r" (sdr1)
204
    );
204
    );
205
    phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
205
    phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
206
   
206
   
207
    /* Primary hash (xor) */
207
    /* Primary hash (xor) */
208
    __u32 h = 0;
208
    uint32_t h = 0;
209
    __u32 hash = vsid ^ page;
209
    uint32_t hash = vsid ^ page;
210
    __u32 base = (hash & 0x3ff) << 3;
210
    uint32_t base = (hash & 0x3ff) << 3;
211
    __u32 i;
211
    uint32_t i;
212
    bool found = false;
212
    bool found = false;
213
   
213
   
214
    /* Find unused or colliding
214
    /* Find unused or colliding
215
       PTE in PTEG */
215
       PTE in PTEG */
216
    for (i = 0; i < 8; i++) {
216
    for (i = 0; i < 8; i++) {
Line 220... Line 220...
220
        }
220
        }
221
    }
221
    }
222
   
222
   
223
    if (!found) {
223
    if (!found) {
224
        /* Secondary hash (not) */
224
        /* Secondary hash (not) */
225
        __u32 base2 = (~hash & 0x3ff) << 3;
225
        uint32_t base2 = (~hash & 0x3ff) << 3;
226
       
226
       
227
        /* Find unused or colliding
227
        /* Find unused or colliding
228
           PTE in PTEG */
228
           PTE in PTEG */
229
        for (i = 0; i < 8; i++) {
229
        for (i = 0; i < 8; i++) {
230
            if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) {
230
            if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) {
Line 258... Line 258...
258
 * @param istate Interrupted register context.
258
 * @param istate Interrupted register context.
259
 *
259
 *
260
 */
260
 */
261
void pht_refill(int n, istate_t *istate)
261
void pht_refill(int n, istate_t *istate)
262
{
262
{
263
    __address badvaddr;
263
    uintptr_t badvaddr;
264
    pte_t *pte;
264
    pte_t *pte;
265
    int pfrc;
265
    int pfrc;
266
    as_t *as;
266
    as_t *as;
267
    bool lock;
267
    bool lock;
268
   
268
   
Line 320... Line 320...
320
 * @param istate Interrupted register context.
320
 * @param istate Interrupted register context.
321
 *
321
 *
322
 */
322
 */
323
bool pht_real_refill(int n, istate_t *istate)
323
bool pht_real_refill(int n, istate_t *istate)
324
{
324
{
325
    __address badvaddr;
325
    uintptr_t badvaddr;
326
   
326
   
327
    if (n == VECTOR_DATA_STORAGE) {
327
    if (n == VECTOR_DATA_STORAGE) {
328
        asm volatile (
328
        asm volatile (
329
            "mfdar %0\n"
329
            "mfdar %0\n"
330
            : "=r" (badvaddr)
330
            : "=r" (badvaddr)
331
        );
331
        );
332
    } else
332
    } else
333
        badvaddr = istate->pc;
333
        badvaddr = istate->pc;
334
   
334
   
335
    __u32 physmem;
335
    uint32_t physmem;
336
    asm volatile (
336
    asm volatile (
337
        "mfsprg3 %0\n"
337
        "mfsprg3 %0\n"
338
        : "=r" (physmem)
338
        : "=r" (physmem)
339
    );
339
    );
340
   
340
   
Line 362... Line 362...
362
}
362
}
363
 
363
 
364
 
364
 
365
void tlb_invalidate_asid(asid_t asid)
365
void tlb_invalidate_asid(asid_t asid)
366
{
366
{
367
    __u32 sdr1;
367
    uint32_t sdr1;
368
    asm volatile (
368
    asm volatile (
369
        "mfsdr1 %0\n"
369
        "mfsdr1 %0\n"
370
        : "=r" (sdr1)
370
        : "=r" (sdr1)
371
    );
371
    );
372
    phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
372
    phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
373
   
373
   
374
    __u32 i;
374
    uint32_t i;
375
    for (i = 0; i < 8192; i++) {
375
    for (i = 0; i < 8192; i++) {
376
        if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && (phte[i].vsid < ((asid << 4) + 16)))
376
        if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && (phte[i].vsid < ((asid << 4) + 16)))
377
            phte[i].v = 0;
377
            phte[i].v = 0;
378
    }
378
    }
379
    tlb_invalidate_all();
379
    tlb_invalidate_all();
380
}
380
}
381
 
381
 
382
 
382
 
383
void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt)
383
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
384
{
384
{
385
    // TODO
385
    // TODO
386
    tlb_invalidate_all();
386
    tlb_invalidate_all();
387
}
387
}
388
 
388
 
Line 393... Line 393...
393
        "mfspr %1," #lreg "\n" \
393
        "mfspr %1," #lreg "\n" \
394
        : "=r" (upper), "=r" (lower) \
394
        : "=r" (upper), "=r" (lower) \
395
    ); \
395
    ); \
396
    mask = (upper & 0x1ffc) >> 2; \
396
    mask = (upper & 0x1ffc) >> 2; \
397
    if (upper & 3) { \
397
    if (upper & 3) { \
398
        __u32 tmp = mask; \
398
        uint32_t tmp = mask; \
399
        length = 128; \
399
        length = 128; \
400
        while (tmp) { \
400
        while (tmp) { \
401
            if ((tmp & 1) == 0) { \
401
            if ((tmp & 1) == 0) { \
402
                printf("ibat[0]: error in mask\n"); \
402
                printf("ibat[0]: error in mask\n"); \
403
                break; \
403
                break; \
Line 410... Line 410...
410
    printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, lower & 0xffff0000, length, mask, ((upper >> 1) & 1) ? " supervisor" : "", (upper & 1) ? " user" : "");
410
    printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, lower & 0xffff0000, length, mask, ((upper >> 1) & 1) ? " supervisor" : "", (upper & 1) ? " user" : "");
411
 
411
 
412
 
412
 
413
void tlb_print(void)
413
void tlb_print(void)
414
{
414
{
415
    __u32 sr;
415
    uint32_t sr;
416
   
416
   
417
    for (sr = 0; sr < 16; sr++) {
417
    for (sr = 0; sr < 16; sr++) {
418
        __u32 vsid;
418
        uint32_t vsid;
419
        asm volatile (
419
        asm volatile (
420
            "mfsrin %0, %1\n"
420
            "mfsrin %0, %1\n"
421
            : "=r" (vsid)
421
            : "=r" (vsid)
422
            : "r" (sr << 28)
422
            : "r" (sr << 28)
423
        );
423
        );
424
        printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, ((vsid >> 30) & 1) ? " supervisor" : "", ((vsid >> 29) & 1) ? " user" : "");
424
        printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, ((vsid >> 30) & 1) ? " supervisor" : "", ((vsid >> 29) & 1) ? " user" : "");
425
    }
425
    }
426
   
426
   
427
    __u32 upper;
427
    uint32_t upper;
428
    __u32 lower;
428
    uint32_t lower;
429
    __u32 mask;
429
    uint32_t mask;
430
    __u32 length;
430
    uint32_t length;
431
   
431
   
432
    PRINT_BAT("ibat[0]", 528, 529);
432
    PRINT_BAT("ibat[0]", 528, 529);
433
    PRINT_BAT("ibat[1]", 530, 531);
433
    PRINT_BAT("ibat[1]", 530, 531);
434
    PRINT_BAT("ibat[2]", 532, 533);
434
    PRINT_BAT("ibat[2]", 532, 533);
435
    PRINT_BAT("ibat[3]", 534, 535);
435
    PRINT_BAT("ibat[3]", 534, 535);