Subversion Repositories HelenOS

Rev

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

Rev 3597 Rev 4377
Line 24... Line 24...
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
/** @addtogroup mips32mm   
29
/** @addtogroup mips32mm
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
Line 38... Line 38...
38
#include <mm/page.h>
38
#include <mm/page.h>
39
#include <mm/as.h>
39
#include <mm/as.h>
40
#include <arch/cp0.h>
40
#include <arch/cp0.h>
41
#include <panic.h>
41
#include <panic.h>
42
#include <arch.h>
42
#include <arch.h>
43
#include <symtab.h>
-
 
44
#include <synch/spinlock.h>
43
#include <synch/mutex.h>
45
#include <print.h>
44
#include <print.h>
46
#include <debug.h>
45
#include <debug.h>
47
#include <align.h>
46
#include <align.h>
48
#include <interrupt.h>
47
#include <interrupt.h>
-
 
48
#include <symtab.h>
49
 
49
 
50
static void tlb_refill_fail(istate_t *);
50
static void tlb_refill_fail(istate_t *);
51
static void tlb_invalid_fail(istate_t *);
51
static void tlb_invalid_fail(istate_t *);
52
static void tlb_modified_fail(istate_t *);
52
static void tlb_modified_fail(istate_t *);
53
 
53
 
Line 90... Line 90...
90
    entry_hi_t hi;
90
    entry_hi_t hi;
91
    asid_t asid;
91
    asid_t asid;
92
    uintptr_t badvaddr;
92
    uintptr_t badvaddr;
93
    pte_t *pte;
93
    pte_t *pte;
94
    int pfrc;
94
    int pfrc;
95
 
95
   
96
    badvaddr = cp0_badvaddr_read();
96
    badvaddr = cp0_badvaddr_read();
97
 
97
   
98
    spinlock_lock(&AS->lock);
98
    mutex_lock(&AS->lock);
99
    asid = AS->asid;
99
    asid = AS->asid;
100
    spinlock_unlock(&AS->lock);
100
    mutex_unlock(&AS->lock);
101
 
101
   
102
    page_table_lock(AS, true);
102
    page_table_lock(AS, true);
103
 
103
   
104
    pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
104
    pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
105
    if (!pte) {
105
    if (!pte) {
106
        switch (pfrc) {
106
        switch (pfrc) {
107
        case AS_PF_FAULT:
107
        case AS_PF_FAULT:
108
            goto fail;
108
            goto fail;
Line 113... Line 113...
113
             * or copy_to_uspace().
113
             * or copy_to_uspace().
114
             */
114
             */
115
            page_table_unlock(AS, true);
115
            page_table_unlock(AS, true);
116
            return;
116
            return;
117
        default:
117
        default:
118
            panic("unexpected pfrc (%d)\n", pfrc);
118
            panic("Unexpected pfrc (%d).", pfrc);
119
        }
119
        }
120
    }
120
    }
121
 
121
 
122
    /*
122
    /*
123
     * Record access to PTE.
123
     * Record access to PTE.
Line 197... Line 197...
197
             * or copy_to_uspace().
197
             * or copy_to_uspace().
198
             */
198
             */
199
            page_table_unlock(AS, true);             
199
            page_table_unlock(AS, true);             
200
            return;
200
            return;
201
        default:
201
        default:
202
            panic("unexpected pfrc (%d)\n", pfrc);
202
            panic("Unexpected pfrc (%d).", pfrc);
203
        }
203
        }
204
    }
204
    }
205
 
205
 
206
    /*
206
    /*
207
     * Read the faulting TLB entry.
207
     * Read the faulting TLB entry.
Line 280... Line 280...
280
             * or copy_to_uspace().
280
             * or copy_to_uspace().
281
             */
281
             */
282
            page_table_unlock(AS, true);             
282
            page_table_unlock(AS, true);             
283
            return;
283
            return;
284
        default:
284
        default:
285
            panic("unexpected pfrc (%d)\n", pfrc);
285
            panic("Unexpected pfrc (%d).", pfrc);
286
        }
286
        }
287
    }
287
    }
288
 
288
 
289
    /*
289
    /*
290
     * Read the faulting TLB entry.
290
     * Read the faulting TLB entry.
Line 318... Line 318...
318
    tlb_modified_fail(istate);
318
    tlb_modified_fail(istate);
319
}
319
}
320
 
320
 
321
void tlb_refill_fail(istate_t *istate)
321
void tlb_refill_fail(istate_t *istate)
322
{
322
{
323
    char *symbol = "";
323
    char *symbol, *sym2;
324
    char *sym2 = "";
-
 
325
 
-
 
326
    char *s = get_symtab_entry(istate->epc);
-
 
327
    if (s)
-
 
328
        symbol = s;
-
 
329
    s = get_symtab_entry(istate->ra);
-
 
330
    if (s)
-
 
331
        sym2 = s;
-
 
332
 
324
 
-
 
325
    symbol = symtab_fmt_name_lookup(istate->epc);
-
 
326
    sym2 = symtab_fmt_name_lookup(istate->ra);
-
 
327
   
333
    fault_if_from_uspace(istate, "TLB Refill Exception on %p",
328
    fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
334
        cp0_badvaddr_read());
329
        cp0_badvaddr_read());
335
    panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(),
330
    panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(),
336
        istate->epc, symbol, sym2);
331
        istate->epc, symbol, sym2);
337
}
332
}
338
 
333
 
339
 
334
 
340
void tlb_invalid_fail(istate_t *istate)
335
void tlb_invalid_fail(istate_t *istate)
341
{
336
{
342
    char *symbol = "";
337
    char *symbol;
-
 
338
 
-
 
339
    symbol = symtab_fmt_name_lookup(istate->epc);
343
 
340
 
344
    char *s = get_symtab_entry(istate->epc);
-
 
345
    if (s)
-
 
346
        symbol = s;
-
 
347
    fault_if_from_uspace(istate, "TLB Invalid Exception on %p",
341
    fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
348
        cp0_badvaddr_read());
342
        cp0_badvaddr_read());
349
    panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(),
343
    panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(),
350
        istate->epc, symbol);
344
        istate->epc, symbol);
351
}
345
}
352
 
346
 
353
void tlb_modified_fail(istate_t *istate)
347
void tlb_modified_fail(istate_t *istate)
354
{
348
{
355
    char *symbol = "";
349
    char *symbol;
-
 
350
 
-
 
351
    symbol = symtab_fmt_name_lookup(istate->epc);
356
 
352
 
357
    char *s = get_symtab_entry(istate->epc);
-
 
358
    if (s)
-
 
359
        symbol = s;
-
 
360
    fault_if_from_uspace(istate, "TLB Modified Exception on %p",
353
    fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
361
        cp0_badvaddr_read());
354
        cp0_badvaddr_read());
362
    panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(),
355
    panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(),
363
        istate->epc, symbol);
356
        istate->epc, symbol);
364
}
357
}
365
 
358
 
366
/** Try to find PTE for faulting address.
359
/** Try to find PTE for faulting address.
367
 *
360
 *
Line 431... Line 424...
431
            page_table_lock(AS, true);
424
            page_table_lock(AS, true);
432
            *pfrc = AS_PF_FAULT;
425
            *pfrc = AS_PF_FAULT;
433
            return NULL;
426
            return NULL;
434
            break;
427
            break;
435
        default:
428
        default:
436
            panic("unexpected rc (%d)\n", rc);
429
            panic("Unexpected rc (%d).", rc);
437
        }
430
        }
438
       
431
       
439
    }
432
    }
440
}
433
}
441
 
434