|
@@ -334,9 +334,64 @@ save_full_context_ex:
|
|
|
|
|
|
/* Low-level exception handlers */
|
|
/* Low-level exception handlers */
|
|
handle_critical:
|
|
handle_critical:
|
|
|
|
+ /*
|
|
|
|
+ * AT32AP700x errata:
|
|
|
|
+ *
|
|
|
|
+ * After a Java stack overflow or underflow trap, any CPU
|
|
|
|
+ * memory access may cause erratic behavior. This will happen
|
|
|
|
+ * when the four least significant bits of the JOSP system
|
|
|
|
+ * register contains any value between 9 and 15 (inclusive).
|
|
|
|
+ *
|
|
|
|
+ * Possible workarounds:
|
|
|
|
+ * - Don't use the Java Extension Module
|
|
|
|
+ * - Ensure that the stack overflow and underflow trap
|
|
|
|
+ * handlers do not do any memory access or trigger any
|
|
|
|
+ * exceptions before the overflow/underflow condition is
|
|
|
|
+ * cleared (by incrementing or decrementing the JOSP)
|
|
|
|
+ * - Make sure that JOSP does not contain any problematic
|
|
|
|
+ * value before doing any exception or interrupt
|
|
|
|
+ * processing.
|
|
|
|
+ * - Set up a critical exception handler which writes a
|
|
|
|
+ * known-to-be-safe value, e.g. 4, to JOSP before doing
|
|
|
|
+ * any further processing.
|
|
|
|
+ *
|
|
|
|
+ * We'll use the last workaround for now since we cannot
|
|
|
|
+ * guarantee that user space processes don't use Java mode.
|
|
|
|
+ * Non-well-behaving userland will be terminated with extreme
|
|
|
|
+ * prejudice.
|
|
|
|
+ */
|
|
|
|
+#ifdef CONFIG_CPU_AT32AP700X
|
|
|
|
+ /*
|
|
|
|
+ * There's a chance we can't touch memory, so temporarily
|
|
|
|
+ * borrow PTBR to save the stack pointer while we fix things
|
|
|
|
+ * up...
|
|
|
|
+ */
|
|
|
|
+ mtsr SYSREG_PTBR, sp
|
|
|
|
+ mov sp, 4
|
|
|
|
+ mtsr SYSREG_JOSP, sp
|
|
|
|
+ mfsr sp, SYSREG_PTBR
|
|
|
|
+ sub pc, -2
|
|
|
|
+
|
|
|
|
+ /* Push most of pt_regs on stack. We'll do the rest later */
|
|
sub sp, 4
|
|
sub sp, 4
|
|
- stmts --sp, r0-lr
|
|
|
|
- rcall save_full_context_ex
|
|
|
|
|
|
+ pushm r0-r12
|
|
|
|
+
|
|
|
|
+ /* PTBR mirrors current_thread_info()->task->active_mm->pgd */
|
|
|
|
+ get_thread_info r0
|
|
|
|
+ ld.w r1, r0[TI_task]
|
|
|
|
+ ld.w r2, r1[TSK_active_mm]
|
|
|
|
+ ld.w r3, r2[MM_pgd]
|
|
|
|
+ mtsr SYSREG_PTBR, r3
|
|
|
|
+#else
|
|
|
|
+ sub sp, 4
|
|
|
|
+ pushm r0-r12
|
|
|
|
+#endif
|
|
|
|
+ sub r0, sp, -(14 * 4)
|
|
|
|
+ mov r1, lr
|
|
|
|
+ mfsr r2, SYSREG_RAR_EX
|
|
|
|
+ mfsr r3, SYSREG_RSR_EX
|
|
|
|
+ pushm r0-r3
|
|
|
|
+
|
|
mfsr r12, SYSREG_ECR
|
|
mfsr r12, SYSREG_ECR
|
|
mov r11, sp
|
|
mov r11, sp
|
|
rcall do_critical_exception
|
|
rcall do_critical_exception
|