Subversion Repositories HelenOS-historic

Rev

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

Rev 1374 Rev 1378
Line 47... Line 47...
47
 *
47
 *
48
 * Try to find PTE for faulting address.
48
 * Try to find PTE for faulting address.
49
 * The AS->lock must be held on entry to this function.
49
 * The AS->lock must be held on entry to this function.
50
 *
50
 *
51
 * @param badvaddr Faulting virtual address.
51
 * @param badvaddr Faulting virtual address.
52
 * @param istate Pointer to interrupted state.
52
 * @param istate   Pointer to interrupted state.
53
 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
53
 * @param pfrc     Pointer to variable where as_page_fault() return code will be stored.
54
 * @return         PTE on success, NULL otherwise.
54
 * @return         PTE on success, NULL otherwise.
55
 *
55
 *
56
 */
56
 */
57
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
57
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
58
{
58
{
Line 112... Line 112...
112
    if (s)
112
    if (s)
113
        sym2 = s;
113
        sym2 = s;
114
    panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
114
    panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
115
}
115
}
116
 
116
 
-
 
117
 
117
static void pht_insert(const __address vaddr, const pfn_t pfn)
118
static void pht_insert(const __address vaddr, const pfn_t pfn)
118
{
119
{
119
    __u32 page = (vaddr >> 12) & 0xffff;
120
    __u32 page = (vaddr >> 12) & 0xffff;
120
    __u32 api = (vaddr >> 22) & 0x3f;
121
    __u32 api = (vaddr >> 22) & 0x3f;
121
    __u32 vsid;
122
    __u32 vsid;
Line 128... Line 129...
128
   
129
   
129
    /* Primary hash (xor) */
130
    /* Primary hash (xor) */
130
    __u32 hash = ((vsid ^ page) & 0x3ff) << 3;
131
    __u32 hash = ((vsid ^ page) & 0x3ff) << 3;
131
   
132
   
132
    __u32 i;
133
    __u32 i;
-
 
134
    bool found = false;
133
    /* Find unused PTE in PTEG */
135
    /* Find unused PTE in PTEG */
134
    for (i = 0; i < 8; i++) {
136
    for (i = 0; i < 8; i++) {
135
        if (!phte[hash + i].v)
137
        if (!phte[hash + i].v) {
-
 
138
            found = true;
136
            break;
139
            break;
-
 
140
        }
137
    }
141
    }
138
   
142
   
-
 
143
    if (!found) {
139
    // TODO: Check access/change bits, secondary hash
144
        /* Secondary hash (not) */
-
 
145
        hash = ~hash;
-
 
146
       
-
 
147
        /* Find unused PTE in PTEG */
-
 
148
        for (i = 0; i < 8; i++) {
-
 
149
            if (!phte[hash + i].v) {
-
 
150
                found = true;
-
 
151
                break;
-
 
152
            }
-
 
153
        }
140
   
154
       
141
    if (i == 8)
155
        if (!found) {
-
 
156
            // TODO: A/C precedence groups
142
        i = page % 8;
157
            i = page % 8;
-
 
158
        }
-
 
159
    }
143
   
160
   
144
    phte[hash + i].v = 1;
161
    phte[hash + i].v = 1;
145
    phte[hash + i].vsid = vsid;
162
    phte[hash + i].vsid = vsid;
146
    phte[hash + i].h = 0;
163
    phte[hash + i].h = 0;
147
    phte[hash + i].api = api;
164
    phte[hash + i].api = api;
Line 181... Line 198...
181
    page_table_lock(AS, true);
198
    page_table_lock(AS, true);
182
   
199
   
183
    pte = find_mapping_and_check(badvaddr, istate, &pfcr);
200
    pte = find_mapping_and_check(badvaddr, istate, &pfcr);
184
    if (!pte) {
201
    if (!pte) {
185
        switch (pfcr) {
202
        switch (pfcr) {
186
        case AS_PF_FAULT:
203
            case AS_PF_FAULT:
187
            goto fail;
204
                goto fail;
188
            break;
205
                break;
189
        case AS_PF_DEFER:
206
            case AS_PF_DEFER:
190
            /*
207
                /*
191
             * The page fault came during copy_from_uspace()
208
                 * The page fault came during copy_from_uspace()
192
             * or copy_to_uspace().
209
                 * or copy_to_uspace().
193
             */
210
                 */
194
            page_table_unlock(AS, true);
211
                page_table_unlock(AS, true);
195
            return;
212
                return;
196
        default:
213
            default:
197
            panic("Unexpected pfrc (%d)\n", pfcr);
214
                panic("Unexpected pfrc (%d)\n", pfcr);
198
            break;
-
 
199
        }
215
        }
200
    }
216
    }
201
   
217
   
202
    pte->a = 1; /* Record access to PTE */
218
    pte->a = 1; /* Record access to PTE */
203
    pht_insert(badvaddr, pte->pfn);
219
    pht_insert(badvaddr, pte->pfn);
Line 212... Line 228...
212
 
228
 
213
 
229
 
214
void pht_init(void)
230
void pht_init(void)
215
{
231
{
216
    memsetb((__address) phte, 1 << PHT_BITS, 0);
232
    memsetb((__address) phte, 1 << PHT_BITS, 0);
217
   
-
 
218
    /* Insert global kernel mapping */
-
 
219
   
-
 
220
    __address cur;
-
 
221
    for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
-
 
222
        pte_t *pte = page_mapping_find(AS_KERNEL, PA2KA(cur));
-
 
223
        if ((pte) && (pte->p) && (pte->g))
-
 
224
            pht_insert(PA2KA(cur), pte->pfn);
-
 
225
    }
-
 
226
}
233
}
227
 
234
 
228
 
235
 
229
void page_arch_init(void)
236
void page_arch_init(void)
230
{
237
{
Line 254... Line 261...
254
        asm volatile (
261
        asm volatile (
255
            "mtsdr1 %0\n"
262
            "mtsdr1 %0\n"
256
            :
263
            :
257
            : "r" ((__address) physical_phte)
264
            : "r" ((__address) physical_phte)
258
        );
265
        );
259
       
-
 
260
        /* Invalidate block address translation registers,
-
 
261
           thus remove the temporary mapping */
-
 
262
//      invalidate_bat();
-
 
263
    }
266
    }
264
}
267
}