public inbox for newlib-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin] Add support for Semihosting v2 support for AArch64 in libgloss.
@ 2017-07-05 12:42 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2017-07-05 12:42 UTC (permalink / raw)
  To: newlib-cvs

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=ddb6f8a02ad404796ff3cb901cb34c2d6d317c4a

commit ddb6f8a02ad404796ff3cb901cb34c2d6d317c4a
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Wed Jul 5 13:04:59 2017 +0100

    Add support for Semihosting v2 support for AArch64 in libgloss.
    
    Semihosting v2 changes are documented here:
    https://developer.arm.com/docs/100863/latest/
    
    The biggest change is the addition of an extensions mechanism
    to add more extensions in the future.
    
    Signed-off-by: Tamar Christina <tamar.christina@arm.com>

Diff:
---
 libgloss/aarch64/_exit.c    |   8 ++-
 libgloss/aarch64/_kill.c    |   8 ++-
 libgloss/aarch64/svc.h      |  78 ++++++++++++++++---------
 libgloss/aarch64/syscalls.c | 139 ++++++++++++++++++++++++++++++++++++++------
 4 files changed, 186 insertions(+), 47 deletions(-)

diff --git a/libgloss/aarch64/_exit.c b/libgloss/aarch64/_exit.c
index a4f9d9e..1a6b015 100644
--- a/libgloss/aarch64/_exit.c
+++ b/libgloss/aarch64/_exit.c
@@ -36,6 +36,12 @@ _exit (int status)
       param_block_t block[2];
       block[0] = ADP_Stopped_ApplicationExit;
       block[1] = status;
-      do_AngelSVC (AngelSVC_Reason_ReportException, block);
+
+#if SEMIHOST_V2
+      if (_has_ext_exit_extended ())
+	 do_AngelSVC (AngelSVC_Reason_ReportExceptionExtended, block);
+      else
+#endif
+	 do_AngelSVC (AngelSVC_Reason_ReportException, block);
     }
 }
diff --git a/libgloss/aarch64/_kill.c b/libgloss/aarch64/_kill.c
index af33f07..1d42371 100644
--- a/libgloss/aarch64/_kill.c
+++ b/libgloss/aarch64/_kill.c
@@ -45,5 +45,11 @@ _kill (int pid, int sig)
 
   block[0] = ADP_Stopped_RunTimeError;
   block[1] = sig;
-  return do_AngelSVC (AngelSVC_Reason_ReportException, block);
+
+#if SEMIHOST_V2
+  if (_has_ext_exit_extended ())
+    return do_AngelSVC (AngelSVC_Reason_ReportExceptionExtended, block);
+  else
+#endif
+    return do_AngelSVC (AngelSVC_Reason_ReportException, block);
 }
diff --git a/libgloss/aarch64/svc.h b/libgloss/aarch64/svc.h
index fe249f0..60bd00f 100644
--- a/libgloss/aarch64/svc.h
+++ b/libgloss/aarch64/svc.h
@@ -23,37 +23,59 @@
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
 
+#include <_ansi.h>
+
 /* Now the SWI numbers and reason codes for RDI (Angel) monitors.  */
-#define AngelSVC			0xF000
-#define AngelSVCInsn			"hlt"
-#define AngelSVCAsm			hlt
+#define AngelSVC				0xF000
+#define AngelSVCInsn				"hlt"
+#define AngelSVCAsm				hlt
 
 /* The reason codes:  */
-#define AngelSVC_Reason_Open		0x01
-#define AngelSVC_Reason_Close		0x02
-#define AngelSVC_Reason_WriteC		0x03
-#define AngelSVC_Reason_Write0		0x04
-#define AngelSVC_Reason_Write		0x05
-#define AngelSVC_Reason_Read		0x06
-#define AngelSVC_Reason_ReadC		0x07
-#define AngelSVC_Reason_IsTTY		0x09
-#define AngelSVC_Reason_Seek		0x0A
-#define AngelSVC_Reason_FLen		0x0C
-#define AngelSVC_Reason_TmpNam		0x0D
-#define AngelSVC_Reason_Remove		0x0E
-#define AngelSVC_Reason_Rename		0x0F
-#define AngelSVC_Reason_Clock		0x10
-#define AngelSVC_Reason_Time		0x11
-#define AngelSVC_Reason_System		0x12
-#define AngelSVC_Reason_Errno		0x13
-#define AngelSVC_Reason_GetCmdLine	0x15
-#define AngelSVC_Reason_HeapInfo	0x16
-#define AngelSVC_Reason_EnterSVC	0x17
-#define AngelSVC_Reason_ReportException 0x18
-#define AngelSVC_Reason_SyncCacheRange	0x19
-#define AngelSVC_Reason_Elapsed         0x30
-#define ADP_Stopped_ApplicationExit	((2 << 16) + 38)
-#define ADP_Stopped_RunTimeError	((2 << 16) + 35)
+#define AngelSVC_Reason_Open			0x01
+#define AngelSVC_Reason_Close			0x02
+#define AngelSVC_Reason_WriteC			0x03
+#define AngelSVC_Reason_Write0			0x04
+#define AngelSVC_Reason_Write			0x05
+#define AngelSVC_Reason_Read			0x06
+#define AngelSVC_Reason_ReadC			0x07
+#define AngelSVC_Reason_IsError			0x08
+#define AngelSVC_Reason_IsTTY			0x09
+#define AngelSVC_Reason_Seek			0x0A
+#define AngelSVC_Reason_FLen			0x0C
+#define AngelSVC_Reason_TmpNam			0x0D
+#define AngelSVC_Reason_Remove			0x0E
+#define AngelSVC_Reason_Rename			0x0F
+#define AngelSVC_Reason_Clock			0x10
+#define AngelSVC_Reason_Time			0x11
+#define AngelSVC_Reason_System			0x12
+#define AngelSVC_Reason_Errno			0x13
+#define AngelSVC_Reason_GetCmdLine		0x15
+#define AngelSVC_Reason_HeapInfo		0x16
+#define AngelSVC_Reason_EnterSVC		0x17
+#define AngelSVC_Reason_ReportException 	0x18
+#define AngelSVC_Reason_SyncCacheRange		0x19
+#define AngelSVC_Reason_ReportExceptionExtended 0x20
+#define AngelSVC_Reason_Elapsed			0x30
+#define AngelSVC_Reason_TickFreq		0x31
+#define ADP_Stopped_ApplicationExit		((2 << 16) + 38)
+#define ADP_Stopped_RunTimeError		((2 << 16) + 35)
+
+/* Semihosting feature magic numbers.  */
+#define NUM_SHFB_MAGIC			4
+#define SHFB_MAGIC_0			0x53
+#define SHFB_MAGIC_1			0x48
+#define SHFB_MAGIC_2			0x46
+#define SHFB_MAGIC_3			0x42
+
+/* Semihosting extensions.  */
+#define SH_EXT_EXIT_EXTENDED_BITNUM	0x0
+#define SH_EXT_STDOUT_STDERR_BITNUM	0x1
+
+#if !defined (__ASSEMBLER__)
+extern int _get_semihosting_exts _PARAMS ((char*, int, int));
+extern int _has_ext_exit_extended _PARAMS ((void));
+extern int _has_ext_stdout_stderr _PARAMS ((void));
+#endif
 
 #if defined(ARM_RDI_MONITOR) && !defined(__ASSEMBLER__)
 
diff --git a/libgloss/aarch64/syscalls.c b/libgloss/aarch64/syscalls.c
index 058cef5..af206a1 100644
--- a/libgloss/aarch64/syscalls.c
+++ b/libgloss/aarch64/syscalls.c
@@ -76,6 +76,9 @@ static int checkerror _PARAMS ((int));
 static int error _PARAMS ((int));
 static int get_errno _PARAMS ((void));
 
+/* Semihosting utilities.  */
+static void initialise_semihosting_exts _PARAMS ((void));
+
 /* Struct used to keep track of the file position, just so we
    can implement fseek(fh,x,SEEK_CUR).  */
 struct fdent
@@ -130,6 +133,9 @@ static int monitor_stdin;
 static int monitor_stdout;
 static int monitor_stderr;
 
+static int supports_ext_exit_extended = -1;
+static int supports_ext_stdout_stderr = -1;
+
 /* Return a pointer to the structure associated with
    the user file descriptor fd. */
 static struct fdent *
@@ -188,32 +194,131 @@ initialise_monitor_handles (void)
   block[1] = 0;			/* mode "r" */
   monitor_stdin = do_AngelSVC (AngelSVC_Reason_Open, block);
 
-  block[0] = POINTER_TO_PARAM_BLOCK_T (":tt");
-  block[2] = 3;			/* length of filename */
-  block[1] = 4;			/* mode "w" */
-  monitor_stdout = do_AngelSVC (AngelSVC_Reason_Open, block);
+  for (i = 0; i < MAX_OPEN_FILES; i++)
+    openfiles[i].handle = -1;;
 
-  block[0] = POINTER_TO_PARAM_BLOCK_T (":tt");
-  block[2] = 3;			/* length of filename */
-  block[1] = 8;			/* mode "a" */
-  monitor_stderr = do_AngelSVC (AngelSVC_Reason_Open, block);
+  if (_has_ext_stdout_stderr ())
+  {
+    block[0] = POINTER_TO_PARAM_BLOCK_T (":tt");
+    block[2] = 3;			/* length of filename */
+    block[1] = 4;			/* mode "w" */
+    monitor_stdout = do_AngelSVC (AngelSVC_Reason_Open, block);
+
+    block[0] = POINTER_TO_PARAM_BLOCK_T (":tt");
+    block[2] = 3;			/* length of filename */
+    block[1] = 8;			/* mode "a" */
+    monitor_stderr = do_AngelSVC (AngelSVC_Reason_Open, block);
+  }
 
   /* If we failed to open stderr, redirect to stdout. */
   if (monitor_stderr == -1)
     monitor_stderr = monitor_stdout;
 
-  for (i = 0; i < MAX_OPEN_FILES; i++)
-    openfiles[i].handle = -1;
-
   openfiles[0].handle = monitor_stdin;
   openfiles[0].flags = _FREAD;
   openfiles[0].pos = 0;
-  openfiles[1].handle = monitor_stdout;
-  openfiles[0].flags = _FWRITE;
-  openfiles[1].pos = 0;
-  openfiles[2].handle = monitor_stderr;
-  openfiles[0].flags = _FWRITE;
-  openfiles[2].pos = 0;
+
+  if (_has_ext_stdout_stderr ())
+  {
+    openfiles[1].handle = monitor_stdout;
+    openfiles[0].flags = _FWRITE;
+    openfiles[1].pos = 0;
+    openfiles[2].handle = monitor_stderr;
+    openfiles[0].flags = _FWRITE;
+    openfiles[2].pos = 0;
+  }
+}
+
+int
+_has_ext_exit_extended (void)
+{
+  if (supports_ext_exit_extended < 0)
+  {
+    initialise_semihosting_exts ();
+  }
+
+  return supports_ext_exit_extended;
+}
+
+int
+_has_ext_stdout_stderr (void)
+{
+  if (supports_ext_stdout_stderr < 0)
+  {
+    initialise_semihosting_exts ();
+  }
+
+  return supports_ext_stdout_stderr;
+}
+
+static void
+initialise_semihosting_exts (void)
+{
+  supports_ext_exit_extended = 0;
+  supports_ext_stdout_stderr = 1;
+
+#if SEMIHOST_V2
+  char features[1];
+  if (_get_semihosting_exts (features, 0, 1) > 0)
+  {
+     supports_ext_exit_extended
+       = features[0] & (1 << SH_EXT_EXIT_EXTENDED_BITNUM);
+     supports_ext_stdout_stderr
+       = features[0] & (1 << SH_EXT_STDOUT_STDERR_BITNUM);
+  }
+#endif
+}
+
+int
+_get_semihosting_exts (char* features, int offset, int num)
+{
+  int fd = _open (":semihosting-features", O_RDONLY);
+  memset (features, 0, num);
+
+  if (fd == -1)
+  {
+    return -1;
+  }
+
+  struct fdent *pfd;
+  pfd = findslot (fd);
+
+  param_block_t block[1];
+  block[0] = pfd->handle;
+
+  int len = do_AngelSVC (AngelSVC_Reason_FLen, block);
+
+  if (len < NUM_SHFB_MAGIC
+      || num > (len - NUM_SHFB_MAGIC))
+  {
+     _close (fd);
+     return -1;
+  }
+
+  char buffer[NUM_SHFB_MAGIC];
+  int n_read = _read (fd, buffer, NUM_SHFB_MAGIC);
+
+  if (n_read < NUM_SHFB_MAGIC
+      || buffer[0] != SHFB_MAGIC_0
+      || buffer[1] != SHFB_MAGIC_1
+      || buffer[2] != SHFB_MAGIC_2
+      || buffer[3] != SHFB_MAGIC_3)
+  {
+     _close (fd);
+     return -1;
+  }
+
+  if (_lseek (fd, offset, SEEK_CUR) < 0)
+  {
+     _close (fd);
+     return -1;
+  }
+
+  n_read = _read (fd, features, num);
+
+  _close (fd);
+
+  return checkerror (n_read);
 }
 
 static int


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-07-05 12:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-05 12:42 [newlib-cygwin] Add support for Semihosting v2 support for AArch64 in libgloss Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).