OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [arch/] [arm/] [v6/] [exception.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Memory exception handling in process context.
3
 *
4
 * Copyright (C) 2007, 2008 Bahadir Balban
5
 */
6
#include <l4/generic/scheduler.h>
7
#include <l4/generic/thread.h>
8
#include <l4/api/thread.h>
9
#include <l4/generic/space.h>
10
#include <l4/generic/tcb.h>
11
#include <l4/generic/platform.h>
12
#include <l4/lib/printk.h>
13
#include <l4/api/ipc.h>
14
#include <l4/api/kip.h>
15
#include <l4/api/errno.h>
16
#include INC_ARCH(exception.h)
17
#include INC_GLUE(memlayout.h)
18
#include INC_GLUE(memory.h)
19
#include INC_GLUE(mapping.h)
20
#include INC_GLUE(message.h)
21
#include INC_GLUE(ipc.h)
22
#include INC_SUBARCH(mm.h)
23
 
24
int check_abort_type(u32 faulted_pc, u32 fsr, u32 far, u32 spsr)
25
{
26
        int ret = 0;
27
 
28
        /*
29
         * On ARMv5, prefetch aborts dont have different
30
         * status values. We validate them here and return.
31
         */
32
        if (is_prefetch_abort(fsr)) {
33
                dbg_abort("Prefetch abort @ ", faulted_pc);
34
 
35
                /* Happened in any mode other than user */
36
                if (!is_user_mode(spsr)) {
37
                        dprintk("Unhandled kernel prefetch "
38
                                "abort at address ", far);
39
                        return -EABORT;
40
                }
41
                return 0;
42
        }
43
 
44
        switch (fsr & FSR_FS_MASK) {
45
        /* Aborts that are expected on page faults: */
46
        case DABT_PERM_PAGE:
47
                dbg_abort("Page permission fault @ ", far);
48
                ret = 0;
49
                break;
50
        case DABT_XLATE_PAGE:
51
                dbg_abort("Page translation fault @ ", far);
52
                ret = 0;
53
                break;
54
        case DABT_XLATE_SECT:
55
                dbg_abort("Section translation fault @ ", far);
56
                ret = 0;
57
                break;
58
 
59
        /* Aborts that can't be handled by a pager yet: */
60
        case DABT_TERMINAL:
61
                dprintk("Terminal fault dabt @ ", far);
62
                ret = -EABORT;
63
                break;
64
        case DABT_VECTOR:
65
                dprintk("Vector abort (obsolete!) @ ", far);
66
                ret = -EABORT;
67
                break;
68
        case DABT_ALIGN:
69
                dprintk("Alignment fault dabt @ ", far);
70
                ret = -EABORT;
71
                break;
72
        case DABT_EXT_XLATE_LEVEL1:
73
                dprintk("External LVL1 translation fault @ ", far);
74
                ret = -EABORT;
75
                break;
76
        case DABT_EXT_XLATE_LEVEL2:
77
                dprintk("External LVL2 translation fault @ ", far);
78
                ret = -EABORT;
79
                break;
80
        case DABT_DOMAIN_SECT:
81
                dprintk("Section domain fault dabt @ ", far);
82
                ret = -EABORT;
83
                break;
84
        case DABT_DOMAIN_PAGE:
85
                dprintk("Page domain fault dabt @ ", far);
86
                ret = -EABORT;
87
                break;
88
        case DABT_PERM_SECT:
89
                dprintk("Section permission fault dabt @ ", far);
90
                ret = -EABORT;
91
                break;
92
        case DABT_EXT_LFETCH_SECT:
93
                dprintk("External section linefetch "
94
                        "fault dabt @ ", far);
95
                ret = -EABORT;
96
                break;
97
        case DABT_EXT_LFETCH_PAGE:
98
                dprintk("Page perm fault dabt @ ", far);
99
                ret = -EABORT;
100
                break;
101
        case DABT_EXT_NON_LFETCH_SECT:
102
                dprintk("External section non-linefetch "
103
                        "fault dabt @ ", far);
104
                ret = -EABORT;
105
                break;
106
        case DABT_EXT_NON_LFETCH_PAGE:
107
                dprintk("External page non-linefetch "
108
                        "fault dabt @ ", far);
109
                ret = -EABORT;
110
                break;
111
        default:
112
                dprintk("FATAL: Unrecognised/Unknown "
113
                        "data abort @ ", far);
114
                dprintk("FATAL: FSR code: ", fsr);
115
                ret = -EABORT;
116
        }
117
 
118
        /*
119
         * Check validity of data abort's source.
120
         *
121
         * FIXME: Why not use spsr to do this?
122
         */
123
        if (is_kernel_address(faulted_pc)) {
124
                dprintk("Unhandled kernel data "
125
                        "abort at address ",
126
                        faulted_pc);
127
                ret = -EABORT;
128
        }
129
 
130
        return ret;
131
}
132
 
133
#if 0
134
void data_abort_handler(u32 faulted_pc, u32 fsr, u32 far)
135
{
136
        set_abort_type(fsr, ARM_DABT);
137
 
138
        dbg_abort("Data abort @ PC: ", faulted_pc);
139
 
140
        //printk("Data abort: %d, PC: 0x%x\n",
141
        //current->tid, faulted_pc);
142
 
143
        /* Check for more details */
144
        if (check_aborts(faulted_pc, fsr, far) < 0) {
145
                printascii("This abort can't be handled by "
146
                           "any pager.\n");
147
                goto error;
148
        }
149
 
150
        /* This notifies the pager */
151
        fault_ipc_to_pager(faulted_pc, fsr, far, L4_IPC_TAG_PFAULT);
152
 
153
        if (current->flags & TASK_SUSPENDING) {
154
                BUG_ON(current->nlocks);
155
                sched_suspend_sync();
156
        } else if (current->flags & TASK_EXITING) {
157
                BUG_ON(current->nlocks);
158
                sched_exit_sync();
159
        }
160
 
161
        return;
162
 
163
error:
164
        disable_irqs();
165
        dprintk("Unhandled data abort @ PC address: ", faulted_pc);
166
        dprintk("FAR:", far);
167
        dprintk("FSR:", fsr);
168
        printascii("Kernel panic.\n");
169
        printascii("Halting system...\n");
170
        while (1)
171
                ;
172
}
173
 
174
void prefetch_abort_handler(u32 faulted_pc, u32 fsr, u32 far, u32 spsr)
175
{
176
        set_abort_type(fsr, ARM_PABT);
177
 
178
        if (check_aborts(faulted_pc, fsr, far) < 0) {
179
                printascii("This abort can't be handled by any pager.\n");
180
                goto error;
181
        }
182
 
183
        /* Did the abort occur in kernel mode? */
184
        if ((spsr & ARM_MODE_MASK) == ARM_MODE_SVC)
185
                goto error;
186
 
187
        fault_ipc_to_pager(faulted_pc, fsr, far, L4_IPC_TAG_PFAULT);
188
 
189
        if (current->flags & TASK_SUSPENDING) {
190
                BUG_ON(current->nlocks);
191
                sched_suspend_sync();
192
        } else if (current->flags & TASK_EXITING) {
193
                BUG_ON(current->nlocks);
194
                sched_exit_sync();
195
        }
196
 
197
        return;
198
 
199
error:
200
        disable_irqs();
201
        dprintk("Unhandled prefetch abort @ address: ", faulted_pc);
202
        dprintk("FAR:", far);
203
        dprintk("FSR:", fsr);
204
        dprintk("Aborted PSR:", spsr);
205
        printascii("Kernel panic.\n");
206
        printascii("Halting system...\n");
207
        while (1)
208
                ;
209
}
210
 
211
void undef_handler(u32 undef_addr, u32 spsr, u32 lr)
212
{
213
        dbg_abort("Undefined instruction @ PC: ", undef_addr);
214
 
215
        //printk("Undefined instruction: tid: %d, PC: 0x%x, Mode: %s\n",
216
        //       current->tid, undef_addr,
217
        //       (spsr & ARM_MODE_MASK) == ARM_MODE_SVC ? "SVC" : "User");
218
 
219
        if ((spsr & ARM_MODE_MASK) == ARM_MODE_SVC) {
220
                printk("Panic: Undef in Kernel\n");
221
                goto error;
222
        }
223
 
224
        fault_ipc_to_pager(undef_addr, 0, undef_addr, L4_IPC_TAG_UNDEF_FAULT);
225
 
226
        if (current->flags & TASK_SUSPENDING) {
227
                BUG_ON(current->nlocks);
228
                sched_suspend_sync();
229
        } else if (current->flags & TASK_EXITING) {
230
                BUG_ON(current->nlocks);
231
                sched_exit_sync();
232
        }
233
 
234
        return;
235
 
236
error:
237
        disable_irqs();
238
        dprintk("SPSR:", spsr);
239
        dprintk("LR:", lr);
240
        printascii("Kernel panic.\n");
241
        printascii("Halting system...\n");
242
        while(1)
243
                ;
244
}
245
#endif
246
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.