summaryrefslogtreecommitdiffstats
path: root/bsps/powerpc/shared/exceptions/ppc_exc_alignment.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/powerpc/shared/exceptions/ppc_exc_alignment.c')
-rw-r--r--bsps/powerpc/shared/exceptions/ppc_exc_alignment.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/bsps/powerpc/shared/exceptions/ppc_exc_alignment.c b/bsps/powerpc/shared/exceptions/ppc_exc_alignment.c
new file mode 100644
index 0000000000..732ff96b18
--- /dev/null
+++ b/bsps/powerpc/shared/exceptions/ppc_exc_alignment.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp/vectors.h>
+
+int ppc_exc_alignment_handler(BSP_Exception_frame *frame, unsigned excNum)
+{
+ unsigned opcode = *(unsigned *) frame->EXC_SRR0;
+
+ /* Do we have a dcbz instruction? */
+ if ((opcode & 0xffe007ff) == 0x7c0007ec) {
+ unsigned clsz = rtems_cache_get_data_line_size();
+ unsigned a = (opcode >> 16) & 0x1f;
+ unsigned b = (opcode >> 11) & 0x1f;
+ PPC_GPR_TYPE *regs = &frame->GPR0;
+ unsigned *current = (unsigned *)
+ (((a == 0 ? 0 : (unsigned) regs[a]) + (unsigned) regs[b]) & (clsz - 1));
+ unsigned *end = current + clsz / sizeof(*current);
+
+ while (current != end) {
+ *current = 0;
+ ++current;
+ }
+
+ frame->EXC_SRR0 += 4;
+
+ return 0;
+ } else {
+ return -1;
+ }
+}