[PATCH 15/21] mips: libgloss: Update to new custom exception handler example and use soft-float

Aleksandar Rikalo arikalo@gmail.com
Thu Oct 31 05:49:31 GMT 2024


From: Matthew Fortune <matthew.fortune@imgtec.com>

libgloss/
	* mips/examples/custom_excpt/Makefile (CFLAGS): Add
	-msoft-float.
	(LDFLAGS): Likewise.
	* mips/examples/custom_excpt/README.txt: Update description.
	* mips/examples/custom_excpt/custom_excpt.c: Rewrite.
	* mips/examples/fault_recovery/Makefile (CFLAGS): Add
	-msoft-float.
	(LDFLAGS): Likewise.
	* mips/examples/isr_vector_space/Makefile (CFLAGS): Add
	-msoft-float.
	(LDFLAGS): Likewise.

Signed-off-by: Matthew Fortune <matthew.fortune@imgtec.com>
Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
---
 libgloss/mips/examples/custom_excpt/Makefile  |   4 +-
 .../mips/examples/custom_excpt/README.txt     |   5 +-
 .../mips/examples/custom_excpt/custom_excpt.c | 125 +++++++++---------
 .../mips/examples/fault_recovery/Makefile     |   4 +-
 .../mips/examples/isr_vector_space/Makefile   |   4 +-
 5 files changed, 71 insertions(+), 71 deletions(-)

diff --git a/libgloss/mips/examples/custom_excpt/Makefile b/libgloss/mips/examples/custom_excpt/Makefile
index 0b76d09e2..03c3fa9af 100644
--- a/libgloss/mips/examples/custom_excpt/Makefile
+++ b/libgloss/mips/examples/custom_excpt/Makefile
@@ -29,8 +29,8 @@
 
 include ${MIPS_ELF_ROOT}/share/mips/rules/mipshal.mk
 
-CFLAGS += -g -O1
-LDFLAGS += -g
+CFLAGS += -msoft-float -g -O1
+LDFLAGS += -msoft-float -g
 
 OBJS = custom_excpt.o
 APP = custom_excpt.elf
diff --git a/libgloss/mips/examples/custom_excpt/README.txt b/libgloss/mips/examples/custom_excpt/README.txt
index 8df200334..1828be85b 100644
--- a/libgloss/mips/examples/custom_excpt/README.txt
+++ b/libgloss/mips/examples/custom_excpt/README.txt
@@ -1,5 +1,6 @@
-Demonstration of exception handling by emulating r0 style accesses for memory
-with _mips_handle_exception.
+Demonstration of exception handling by using the TRAP instruction to cause
+an action to be taken in an exception handler via use of
+_mips_handle_exception.
 
 Set environment variable MIPS_ELF_ROOT
 	This should be set to the root of the installation directory for the
diff --git a/libgloss/mips/examples/custom_excpt/custom_excpt.c b/libgloss/mips/examples/custom_excpt/custom_excpt.c
index 93580ffac..713156623 100644
--- a/libgloss/mips/examples/custom_excpt/custom_excpt.c
+++ b/libgloss/mips/examples/custom_excpt/custom_excpt.c
@@ -31,79 +31,78 @@
 #include <unistd.h>
 #include <mips/hal.h>
 #include <mips/cpu.h>
+
+/* Store a secret from register t0 */
+#define TRAPCODE1 14
+/* Retrieve a secret into register t0 */
+#define TRAPCODE2 15
+
+/* Count the traps we saw in the exception handler */
+volatile int num_traps = 0;
+
 int
-main ()
+main (void)
 {
-  /* Some pointer setup to access memory address 0*/
-  int b = -1;
-  int *a = 0;
-  /* Write to 0, triggering a TLB store error */
-  *a = 0;
-  /* Read from 0, triggering a TLB load error */
-  b = *a;
-  /* Return value should be 0 */
-  return b;
+  volatile register int secret __asm("$t0") = 0x1234;
+
+  /* Store a secret */
+  asm volatile ("teq $zero, $zero, %1\n"
+		::"r" (secret), "i" (TRAPCODE1));
+  secret = 0;
+  /* Retrieve the secret */
+  asm volatile ("teq $zero, $zero, %1\n"
+		:"=r" (secret): "i" (TRAPCODE2));
+
+  if (num_traps != 2)
+    {
+      printf ("2 traps expected to have been done. Failed.\n");
+      return 2;
+    }
+  else if (secret != 0x1234)
+    {
+      printf ("Expected secret to be 0x1234 but got 0x%x\n", secret);
+    }
+
+  printf ("Succeeded!\n");
+  return 0;
 }
 
-/*
- * This exception handler emulates register zero style handling but for memory,
- * i.e. writes to page zero are ignored and reads return a zero for select
- * instructions.
- */
 void
 _mips_handle_exception (struct gpctx *ctx, int exception)
 {
-  /*
-   * This example is designed to work only on MIPS32 and does not handle the
-   * case where a memory operation occurs in a branch delay slot.
-   */
-  if ((mips32_get_c0 (C0_CAUSE) & CR_BD) == 0
-      && (ctx->epc & 0x1) == 0)
-    {
-      unsigned int fault_instruction = 0;
-      switch (exception)
-	{
-	case EXC_TLBS:
-	  fault_instruction = *((unsigned int *) (ctx->epc));
-	  if ((fault_instruction >> 26) == 0x2b)
-	    {
-	      /* Store instruction, ensure it went to zero. */
-	      unsigned int store_reg = (fault_instruction >> 21) & 0x1f;
-	      int16_t offset = fault_instruction & 0xffff;
-	      unsigned int destination = ctx->r[C_CTX_REGNO(store_reg)] + offset;
-
-	      if (destination < 4096)
-		{
-		  write (1, "Handled write to zero page\n", 27);
-		  ctx->epc += 4;
-		  return;
-		}
-	    }
-	  break;
-
-	case EXC_TLBL:
-	  fault_instruction = *((unsigned int *) (ctx->epc));
-	  if ((fault_instruction >> 26) == 0x23)
-	    {
-	      /* Load instruction, ensure it went to zero. */
-	      unsigned int load_reg = (fault_instruction >> 21) & 0x1f;
-	      int16_t offset = fault_instruction & 0xffff;
-	      unsigned int destination = ctx->r[C_CTX_REGNO(load_reg)] + offset;
-	      if (destination < 4096)
-		{
-		  write (1, "Handled read from zero page\n", 28);
-		  ctx->epc += 4;
-		  unsigned int rt = (fault_instruction >> 16) & 0x1f;
-		  ctx->r[rt] = 0;
-		  return;
-		}
-	    }
-	  break;
+  /* The secret data we stash */
+  static int secret_store = 0;
 
+  if ((mips32_get_c0 (C0_CAUSE) & CR_BD) == 0
+      && (exception == EXC_TRAP))
+  {
+#ifdef __mips_micromips
+    unsigned int trap_insn = ((*(unsigned short *)ctx->epc & ~1) << 16
+			      | *(unsigned short *)((ctx->epc & ~1) + 2));
+    switch ((trap_insn >> 12) & 0xf)
+#else
+    unsigned int trap_insn = *(unsigned int *)ctx->epc;
+    switch ((trap_insn >> 6) & 0x3ff)
+#endif
+      {
+	case TRAPCODE1:
+	  secret_store = ctx->r[C_CTX_REGNO (12)];
+	  /* Trash the value */
+	  ctx->r[C_CTX_REGNO (12)] = 0;
+	  write(1, "Trap 1 done!\n", 13);
+	  num_traps += 1;
+	  ctx->epc += 4;
+	  return;
+	case TRAPCODE2:
+	  ctx->r[C_CTX_REGNO (12)] = secret_store;
+	  write(1, "Trap 2 done!\n", 13);
+	  num_traps += 1;
+	  ctx->epc += 4;
+	  return;
 	default:
 	  break;
-	}
-    }
+      }
+  }
 
   /* All other exceptions are passed to the default exception handler.  */
   __exception_handle (ctx, exception);
diff --git a/libgloss/mips/examples/fault_recovery/Makefile b/libgloss/mips/examples/fault_recovery/Makefile
index f857e4a62..572ea6438 100644
--- a/libgloss/mips/examples/fault_recovery/Makefile
+++ b/libgloss/mips/examples/fault_recovery/Makefile
@@ -29,8 +29,8 @@
 
 include ${MIPS_ELF_ROOT}/share/mips/rules/mipshal.mk
 
-CFLAGS += -g -O1
-LDFLAGS += -g
+CFLAGS += -msoft-float -g -O1
+LDFLAGS += -msoft-float -g
 
 OBJS = fault_recovery.o
 APP = fault_recovery.elf
diff --git a/libgloss/mips/examples/isr_vector_space/Makefile b/libgloss/mips/examples/isr_vector_space/Makefile
index bc037d3ac..80a9c47cf 100644
--- a/libgloss/mips/examples/isr_vector_space/Makefile
+++ b/libgloss/mips/examples/isr_vector_space/Makefile
@@ -30,8 +30,8 @@
 ISR_VEC_SPACE = 64
 include ${MIPS_ELF_ROOT}/share/mips/rules/mipshal.mk
 
-CFLAGS += -g -O1 -DISR_VEC_SPACE=$(ISR_VEC_SPACE)
-LDFLAGS += -g
+CFLAGS += -msoft-float -g -O1 -DISR_VEC_SPACE=$(ISR_VEC_SPACE)
+LDFLAGS += -msoft-float -g
 
 OBJS = isr_vector_space.o excpt_isr.o
 APP = isr_vector_space.elf
-- 
2.25.1



More information about the Newlib mailing list