Subversion Repositories HelenOS-historic

Rev

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

Rev 313 Rev 317
Line 32... Line 32...
32
#include <arch/cp0.h>
32
#include <arch/cp0.h>
33
#include <arch/types.h>
33
#include <arch/types.h>
34
#include <arch.h>
34
#include <arch.h>
35
#include <debug.h>
35
#include <debug.h>
36
 
36
 
37
void exception(void)
37
void exception(struct exception_regdump *pstate)
38
{
38
{
39
    int excno;
39
    int excno;
40
    __u32 epc;
-
 
41
    __u32 epc_shift = 0;
40
    __u32 epc_shift = 0;
42
 
41
 
43
    ASSERT(CPU != NULL);
42
    ASSERT(CPU != NULL);
44
 
43
 
45
    /*
44
    /*
46
     * NOTE ON OPERATION ORDERING
45
     * NOTE ON OPERATION ORDERING
47
     *
46
     *
48
     * On entry, cpu_priority_high() must be called before exception bit is cleared.
47
     * On entry, cpu_priority_high() must be called before
49
     * On exit, exception bit must be set before cpu_priority_restore() is called.
48
     * exception bit is cleared.
50
     */
49
     */
51
 
50
 
52
    cpu_priority_high();
51
    cpu_priority_high();
53
    epc = cp0_epc_read();
-
 
54
    cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
52
    cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
55
                        cp0_status_um_bit));
53
                        cp0_status_um_bit));
56
 
54
 
57
    if (THREAD) {
-
 
58
        THREAD->saved_epc = epc;
-
 
59
    }
-
 
60
    /* decode exception number and process the exception */
55
    /* decode exception number and process the exception */
61
    switch (excno = (cp0_cause_read() >> 2) & 0x1f) {
56
    switch (excno = (cp0_cause_read() >> 2) & 0x1f) {
62
        case EXC_Int:
57
        case EXC_Int:
63
            interrupt();
58
            interrupt();
64
            break;
59
            break;
65
        case EXC_TLBL:
60
        case EXC_TLBL:
66
        case EXC_TLBS:
61
        case EXC_TLBS:
67
            tlb_invalid();
62
            tlb_invalid(pstate);
68
            break;
63
            break;
69
        case EXC_Mod:
64
        case EXC_Mod:
70
            panic("unhandled TLB Modification Exception\n");
65
            panic("unhandled TLB Modification Exception\n");
71
            break;
66
            break;
72
        case EXC_AdEL:
67
        case EXC_AdEL:
Line 112... Line 107...
112
            break;
107
            break;
113
        default:
108
        default:
114
            panic("unhandled exception %d\n", excno);
109
            panic("unhandled exception %d\n", excno);
115
    }
110
    }
116
   
111
   
117
    if (THREAD)
-
 
118
        epc = THREAD->saved_epc;
-
 
119
   
-
 
120
    /* Raise EXL bit before epc_write, so that we support
-
 
121
     * properly nested exceptions
-
 
122
     */
-
 
123
    cp0_status_write(cp0_status_read() | cp0_status_exl_exception_bit);
-
 
124
    cp0_epc_write(epc + epc_shift);
112
    pstate->epc += epc_shift;
125
}
113
}