Subversion Repositories HelenOS-historic

Rev

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

Rev 955 Rev 958
Line 60... Line 60...
60
        "WatchHi/WatchLo", /* 23 */
60
        "WatchHi/WatchLo", /* 23 */
61
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
61
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
62
        "Virtual Coherency - data",
62
        "Virtual Coherency - data",
63
};
63
};
64
 
64
 
65
static void print_regdump(struct exception_regdump *pstate)
65
static void print_regdump(istate_t *istate)
66
{
66
{
67
    char *pcsymbol = "";
67
    char *pcsymbol = "";
68
    char *rasymbol = "";
68
    char *rasymbol = "";
69
 
69
 
70
    char *s = get_symtab_entry(pstate->epc);
70
    char *s = get_symtab_entry(istate->epc);
71
    if (s)
71
    if (s)
72
        pcsymbol = s;
72
        pcsymbol = s;
73
    s = get_symtab_entry(pstate->ra);
73
    s = get_symtab_entry(istate->ra);
74
    if (s)
74
    if (s)
75
        rasymbol = s;
75
        rasymbol = s;
76
   
76
   
77
    printf("PC: %X(%s) RA: %X(%s), SP(%P)\n",pstate->epc,pcsymbol,
77
    printf("PC: %X(%s) RA: %X(%s), SP(%P)\n",istate->epc,pcsymbol,
78
           pstate->ra,rasymbol, pstate->sp);
78
           istate->ra,rasymbol, istate->sp);
79
}
79
}
80
 
80
 
81
static void unhandled_exception(int n, struct exception_regdump *pstate)
81
static void unhandled_exception(int n, istate_t *istate)
82
{
82
{
83
    print_regdump(pstate);
83
    print_regdump(istate);
84
    panic("unhandled exception %s\n", exctable[n]);
84
    panic("unhandled exception %s\n", exctable[n]);
85
}
85
}
86
 
86
 
87
static void breakpoint_exception(int n, struct exception_regdump *pstate)
87
static void breakpoint_exception(int n, istate_t *istate)
88
{
88
{
89
#ifdef CONFIG_DEBUG
89
#ifdef CONFIG_DEBUG
90
    debugger_bpoint(pstate);
90
    debugger_bpoint(istate);
91
#else
91
#else
92
    /* it is necessary to not re-execute BREAK instruction after
92
    /* it is necessary to not re-execute BREAK instruction after
93
       returning from Exception handler
93
       returning from Exception handler
94
       (see page 138 in R4000 Manual for more information) */
94
       (see page 138 in R4000 Manual for more information) */
95
    pstate->epc += 4;
95
    istate->epc += 4;
96
#endif
96
#endif
97
}
97
}
98
 
98
 
99
static void tlbmod_exception(int n, struct exception_regdump *pstate)
99
static void tlbmod_exception(int n, istate_t *istate)
100
{
100
{
101
    tlb_modified(pstate);
101
    tlb_modified(istate);
102
}
102
}
103
 
103
 
104
static void tlbinv_exception(int n, struct exception_regdump *pstate)
104
static void tlbinv_exception(int n, istate_t *istate)
105
{
105
{
106
    tlb_invalid(pstate);
106
    tlb_invalid(istate);
107
}
107
}
108
 
108
 
109
#ifdef CONFIG_FPU_LAZY
109
#ifdef CONFIG_FPU_LAZY
110
static void cpuns_exception(int n, struct exception_regdump *pstate)
110
static void cpuns_exception(int n, istate_t *istate)
111
{
111
{
112
    if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
112
    if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
113
        scheduler_fpu_lazy_request();
113
        scheduler_fpu_lazy_request();
114
    else
114
    else
115
        panic("unhandled Coprocessor Unusable Exception\n");
115
        panic("unhandled Coprocessor Unusable Exception\n");
116
}
116
}
117
#endif
117
#endif
118
 
118
 
119
static void interrupt_exception(int n, struct exception_regdump *pstate)
119
static void interrupt_exception(int n, istate_t *istate)
120
{
120
{
121
    __u32 cause;
121
    __u32 cause;
122
    int i;
122
    int i;
123
   
123
   
124
    /* decode interrupt number and process the interrupt */
124
    /* decode interrupt number and process the interrupt */
125
    cause = (cp0_cause_read() >> 8) &0xff;
125
    cause = (cp0_cause_read() >> 8) &0xff;
126
   
126
   
127
    for (i = 0; i < 8; i++)
127
    for (i = 0; i < 8; i++)
128
        if (cause & (1 << i))
128
        if (cause & (1 << i))
129
            exc_dispatch(i+INT_OFFSET, pstate);
129
            exc_dispatch(i+INT_OFFSET, istate);
130
}
130
}
131
 
131
 
132
#include <debug.h>
132
#include <debug.h>
133
/** Handle syscall userspace call */
133
/** Handle syscall userspace call */
134
static void syscall_exception(int n, struct exception_regdump *pstate)
134
static void syscall_exception(int n, istate_t *istate)
135
{
135
{
136
    interrupts_enable();
136
    interrupts_enable();
137
    if (pstate->a3 < SYSCALL_END)
137
    if (istate->a3 < SYSCALL_END)
138
        pstate->v0 = syscall_table[pstate->a3](pstate->a0,
138
        istate->v0 = syscall_table[istate->a3](istate->a0,
139
                               pstate->a1,
139
                               istate->a1,
140
                               pstate->a2);
140
                               istate->a2);
141
    else
141
    else
142
        panic("Undefined syscall %d", pstate->a3);
142
        panic("Undefined syscall %d", istate->a3);
-
 
143
    istate->epc += 4;
143
    interrupts_disable();
144
    interrupts_disable();
144
    pstate->epc += 4;
-
 
145
}
145
}
146
 
146
 
147
 
-
 
148
void exception(struct exception_regdump *pstate)
147
void exception(istate_t *istate)
149
{
148
{
150
    int cause;
149
    int cause;
151
    int excno;
150
    int excno;
152
 
151
 
153
    ASSERT(CPU != NULL);
152
    ASSERT(CPU != NULL);
Line 161... Line 160...
161
 
160
 
162
    interrupts_disable();
161
    interrupts_disable();
163
    cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
162
    cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
164
                        cp0_status_um_bit));
163
                        cp0_status_um_bit));
165
 
164
 
166
    /* Save pstate so that the threads can access it */
165
    /* Save istate so that the threads can access it */
167
    /* If THREAD->pstate is set, this is nested exception,
166
    /* If THREAD->istate is set, this is nested exception,
168
     * do not rewrite it
167
     * do not rewrite it
169
     */
168
     */
170
    if (THREAD && !THREAD->pstate)
169
    if (THREAD && !THREAD->istate)
171
        THREAD->pstate = pstate;
170
        THREAD->istate = istate;
172
 
171
 
173
    cause = cp0_cause_read();
172
    cause = cp0_cause_read();
174
    excno = cp0_cause_excno(cause);
173
    excno = cp0_cause_excno(cause);
175
    /* Dispatch exception */
174
    /* Dispatch exception */
176
    exc_dispatch(excno, pstate);
175
    exc_dispatch(excno, istate);
177
 
176
 
178
    /* Set to NULL, so that we can still support nested
177
    /* Set to NULL, so that we can still support nested
179
     * exceptions
178
     * exceptions
180
     * TODO: We should probably set EXL bit before this command,
179
     * TODO: We should probably set EXL bit before this command,
181
     * nesting. On the other hand, if some exception occurs between
180
     * nesting. On the other hand, if some exception occurs between
182
     * here and ERET, it won't set anything on the pstate anyway.
181
     * here and ERET, it won't set anything on the istate anyway.
183
     */
182
     */
184
    if (THREAD)
183
    if (THREAD)
185
        THREAD->pstate = NULL;
184
        THREAD->istate = NULL;
186
}
185
}
187
 
186
 
188
void exception_init(void)
187
void exception_init(void)
189
{
188
{
190
    int i;
189
    int i;