Subversion Repositories HelenOS-historic

Rev

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

Rev 227 Rev 313
Line 37... Line 37...
37
void exception(void)
37
void exception(void)
38
{
38
{
39
    int excno;
39
    int excno;
40
    __u32 epc;
40
    __u32 epc;
41
    __u32 epc_shift = 0;
41
    __u32 epc_shift = 0;
42
    pri_t pri;
-
 
43
 
42
 
44
    ASSERT(CPU != NULL);
43
    ASSERT(CPU != NULL);
45
 
44
 
46
    /*
45
    /*
47
     * NOTE ON OPERATION ORDERING
46
     * NOTE ON OPERATION ORDERING
48
     *
47
     *
49
     * On entry, cpu_priority_high() must be called before exception bit is cleared.
48
     * On entry, cpu_priority_high() must be called before exception bit is cleared.
50
     * On exit, exception bit must be set before cpu_priority_restore() is called.
49
     * On exit, exception bit must be set before cpu_priority_restore() is called.
51
     */
50
     */
52
 
51
 
53
    pri = cpu_priority_high();
52
    cpu_priority_high();
54
    epc = cp0_epc_read();
53
    epc = cp0_epc_read();
55
    cp0_status_write(cp0_status_read() & ~ cp0_status_exl_exception_bit);
54
    cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
-
 
55
                        cp0_status_um_bit));
56
 
56
 
57
    if (THREAD) {
57
    if (THREAD) {
58
        THREAD->saved_pri = pri;
-
 
59
        THREAD->saved_epc = epc;
58
        THREAD->saved_epc = epc;
60
    }
59
    }
61
    /* decode exception number and process the exception */
60
    /* decode exception number and process the exception */
62
    switch (excno = (cp0_cause_read() >> 2) & 0x1f) {
61
    switch (excno = (cp0_cause_read() >> 2) & 0x1f) {
63
        case EXC_Int:
62
        case EXC_Int:
Line 113... Line 112...
113
            break;
112
            break;
114
        default:
113
        default:
115
            panic("unhandled exception %d\n", excno);
114
            panic("unhandled exception %d\n", excno);
116
    }
115
    }
117
   
116
   
118
    if (THREAD) {
117
    if (THREAD)
119
        pri = THREAD->saved_pri;
-
 
120
        epc = THREAD->saved_epc;
118
        epc = THREAD->saved_epc;
121
    }
119
   
122
 
-
 
-
 
120
    /* Raise EXL bit before epc_write, so that we support
123
    cp0_epc_write(epc + epc_shift);
121
     * properly nested exceptions
-
 
122
     */
124
    cp0_status_write(cp0_status_read() | cp0_status_exl_exception_bit);
123
    cp0_status_write(cp0_status_read() | cp0_status_exl_exception_bit);
125
    cpu_priority_restore(pri);
124
    cp0_epc_write(epc + epc_shift);
126
}
125
}