.. | .. |
---|
154 | 154 | static void microblaze_unwind_inner(struct task_struct *task, |
---|
155 | 155 | unsigned long pc, unsigned long fp, |
---|
156 | 156 | unsigned long leaf_return, |
---|
157 | | - struct stack_trace *trace); |
---|
| 157 | + struct stack_trace *trace, |
---|
| 158 | + const char *loglvl); |
---|
158 | 159 | |
---|
159 | 160 | /** |
---|
160 | 161 | * unwind_trap - Unwind through a system trap, that stored previous state |
---|
.. | .. |
---|
162 | 163 | */ |
---|
163 | 164 | #ifdef CONFIG_MMU |
---|
164 | 165 | static inline void unwind_trap(struct task_struct *task, unsigned long pc, |
---|
165 | | - unsigned long fp, struct stack_trace *trace) |
---|
| 166 | + unsigned long fp, struct stack_trace *trace, |
---|
| 167 | + const char *loglvl) |
---|
166 | 168 | { |
---|
167 | 169 | /* To be implemented */ |
---|
168 | 170 | } |
---|
169 | 171 | #else |
---|
170 | 172 | static inline void unwind_trap(struct task_struct *task, unsigned long pc, |
---|
171 | | - unsigned long fp, struct stack_trace *trace) |
---|
| 173 | + unsigned long fp, struct stack_trace *trace, |
---|
| 174 | + const char *loglvl) |
---|
172 | 175 | { |
---|
173 | 176 | const struct pt_regs *regs = (const struct pt_regs *) fp; |
---|
174 | | - microblaze_unwind_inner(task, regs->pc, regs->r1, regs->r15, trace); |
---|
| 177 | + microblaze_unwind_inner(task, regs->pc, regs->r1, regs->r15, trace, loglvl); |
---|
175 | 178 | } |
---|
176 | 179 | #endif |
---|
177 | 180 | |
---|
.. | .. |
---|
184 | 187 | * the caller's return address. |
---|
185 | 188 | * @trace : Where to store stack backtrace (PC values). |
---|
186 | 189 | * NULL == print backtrace to kernel log |
---|
| 190 | + * @loglvl : Used for printk log level if (trace == NULL). |
---|
187 | 191 | */ |
---|
188 | 192 | static void microblaze_unwind_inner(struct task_struct *task, |
---|
189 | 193 | unsigned long pc, unsigned long fp, |
---|
190 | 194 | unsigned long leaf_return, |
---|
191 | | - struct stack_trace *trace) |
---|
| 195 | + struct stack_trace *trace, |
---|
| 196 | + const char *loglvl) |
---|
192 | 197 | { |
---|
193 | 198 | int ofs = 0; |
---|
194 | 199 | |
---|
.. | .. |
---|
214 | 219 | const struct pt_regs *regs = |
---|
215 | 220 | (const struct pt_regs *) fp; |
---|
216 | 221 | #endif |
---|
217 | | - pr_info("HW EXCEPTION\n"); |
---|
| 222 | + printk("%sHW EXCEPTION\n", loglvl); |
---|
218 | 223 | #ifndef CONFIG_MMU |
---|
219 | 224 | microblaze_unwind_inner(task, regs->r17 - 4, |
---|
220 | 225 | fp + EX_HANDLER_STACK_SIZ, |
---|
221 | | - regs->r15, trace); |
---|
| 226 | + regs->r15, trace, loglvl); |
---|
222 | 227 | #endif |
---|
223 | 228 | return; |
---|
224 | 229 | } |
---|
.. | .. |
---|
228 | 233 | if ((return_to >= handler->start_addr) |
---|
229 | 234 | && (return_to <= handler->end_addr)) { |
---|
230 | 235 | if (!trace) |
---|
231 | | - pr_info("%s\n", handler->trap_name); |
---|
232 | | - unwind_trap(task, pc, fp, trace); |
---|
| 236 | + printk("%s%s\n", loglvl, handler->trap_name); |
---|
| 237 | + unwind_trap(task, pc, fp, trace, loglvl); |
---|
233 | 238 | return; |
---|
234 | 239 | } |
---|
235 | 240 | } |
---|
.. | .. |
---|
248 | 253 | } else { |
---|
249 | 254 | /* Have we reached userland? */ |
---|
250 | 255 | if (unlikely(pc == task_pt_regs(task)->pc)) { |
---|
251 | | - pr_info("[<%p>] PID %lu [%s]\n", |
---|
252 | | - (void *) pc, |
---|
| 256 | + printk("%s[<%p>] PID %lu [%s]\n", |
---|
| 257 | + loglvl, (void *) pc, |
---|
253 | 258 | (unsigned long) task->pid, |
---|
254 | 259 | task->comm); |
---|
255 | 260 | break; |
---|
256 | 261 | } else |
---|
257 | | - print_ip_sym(pc); |
---|
| 262 | + print_ip_sym(loglvl, pc); |
---|
258 | 263 | } |
---|
259 | 264 | |
---|
260 | 265 | /* Stop when we reach anything not part of the kernel */ |
---|
.. | .. |
---|
282 | 287 | * @task : Task whose stack we are to unwind (NULL == current) |
---|
283 | 288 | * @trace : Where to store stack backtrace (PC values). |
---|
284 | 289 | * NULL == print backtrace to kernel log |
---|
| 290 | + * @loglvl : Used for printk log level if (trace == NULL). |
---|
285 | 291 | */ |
---|
286 | | -void microblaze_unwind(struct task_struct *task, struct stack_trace *trace) |
---|
| 292 | +void microblaze_unwind(struct task_struct *task, struct stack_trace *trace, |
---|
| 293 | + const char *loglvl) |
---|
287 | 294 | { |
---|
288 | 295 | if (task) { |
---|
289 | 296 | if (task == current) { |
---|
290 | 297 | const struct pt_regs *regs = task_pt_regs(task); |
---|
291 | 298 | microblaze_unwind_inner(task, regs->pc, regs->r1, |
---|
292 | | - regs->r15, trace); |
---|
| 299 | + regs->r15, trace, loglvl); |
---|
293 | 300 | } else { |
---|
294 | 301 | struct thread_info *thread_info = |
---|
295 | 302 | (struct thread_info *)(task->stack); |
---|
.. | .. |
---|
299 | 306 | microblaze_unwind_inner(task, |
---|
300 | 307 | (unsigned long) &_switch_to, |
---|
301 | 308 | cpu_context->r1, |
---|
302 | | - cpu_context->r15, trace); |
---|
| 309 | + cpu_context->r15, |
---|
| 310 | + trace, loglvl); |
---|
303 | 311 | } |
---|
304 | 312 | } else { |
---|
305 | 313 | unsigned long pc, fp; |
---|
.. | .. |
---|
314 | 322 | ); |
---|
315 | 323 | |
---|
316 | 324 | /* Since we are not a leaf function, use leaf_return = 0 */ |
---|
317 | | - microblaze_unwind_inner(current, pc, fp, 0, trace); |
---|
| 325 | + microblaze_unwind_inner(current, pc, fp, 0, trace, loglvl); |
---|
318 | 326 | } |
---|
319 | 327 | } |
---|
320 | 328 | |
---|