hw/drivers/semihosting: Add raw semihosting driver
These come from https://github.com/ARMmbed/mbed-os. A few changes were
nessesary to make them build in mynewt and mbed-os specific commands
were removed
diff --git a/.style_ignored_dirs b/.style_ignored_dirs
index 8ef10ca..a35fe20 100644
--- a/.style_ignored_dirs
+++ b/.style_ignored_dirs
@@ -5,6 +5,7 @@
crypto/mbedtls
crypto/tinycrypt
hw/drivers/rtt
+hw/drivers/semihosting
libc/baselibc
net/ip/lwip_base
net/lora/node/src/mac
diff --git a/hw/drivers/semihosting/include/semihosting/mbed_semihost_api.h b/hw/drivers/semihosting/include/semihosting/mbed_semihost_api.h
new file mode 100644
index 0000000..2f6e675
--- /dev/null
+++ b/hw/drivers/semihosting/include/semihosting/mbed_semihost_api.h
@@ -0,0 +1,89 @@
+
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2019 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBED_SEMIHOST_H
+#define MBED_SEMIHOST_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(__ARMCC_VERSION)
+
+#if defined(__ICCARM__)
+static inline int __semihost(int reason, const void *arg)
+{
+ return __semihosting(reason, (void *)arg);
+}
+#else
+
+#ifdef __thumb__
+# define AngelSWI 0xAB
+# define AngelSWIInsn "bkpt"
+# define AngelSWIAsm bkpt
+#else
+# define AngelSWI 0x123456
+# define AngelSWIInsn "swi"
+# define AngelSWIAsm swi
+#endif
+
+static inline int __semihost(int reason, const void *arg)
+{
+ int value;
+
+ asm volatile(
+ "mov r0, %1" "\n\t"
+ "mov r1, %2" "\n\t"
+ AngelSWIInsn " %a3" "\n\t"
+ "mov %0, r0"
+ : "=r"(value) /* output operands */
+ : "r"(reason), "r"(arg), "i"(AngelSWI) /* input operands */
+ : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" /* list of clobbered registers */
+ );
+
+ return value;
+}
+#endif
+#endif
+
+typedef uint32_t FILEHANDLE;
+
+FILEHANDLE semihost_open(const char *name, int openmode);
+int semihost_close(FILEHANDLE fh);
+int semihost_read(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode);
+int semihost_write(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode);
+int semihost_ensure(FILEHANDLE fh);
+long semihost_flen(FILEHANDLE fh);
+int semihost_seek(FILEHANDLE fh, long position);
+int semihost_istty(FILEHANDLE fh);
+
+int semihost_remove(const char *name);
+int semihost_rename(const char *old_name, const char *new_name);
+
+int semihost_exit(void);
+
+int semihost_connected(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/hw/drivers/semihosting/pkg.yml b/hw/drivers/semihosting/pkg.yml
new file mode 100644
index 0000000..a12310a
--- /dev/null
+++ b/hw/drivers/semihosting/pkg.yml
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: "hw/drivers/semihosting"
+pkg.description: "ARM semihosting implementation"
+pkg.author: "ARMmbed"
+pkg.homepage: "https://github.com/ARMmbed/mbed-os"
+pkg.keywords:
+ - ARM
+ - semihosting
+
+pkg.deps:
+ - "hw/cmsis-core"
diff --git a/hw/drivers/semihosting/src/mbed_semihost_api.c b/hw/drivers/semihosting/src/mbed_semihost_api.c
new file mode 100644
index 0000000..cd1fa1e
--- /dev/null
+++ b/hw/drivers/semihosting/src/mbed_semihost_api.c
@@ -0,0 +1,122 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <os/mynewt.h>
+#include "semihosting/mbed_semihost_api.h"
+
+#include <stdint.h>
+#include <string.h>
+
+// ARM Semihosting Commands
+#define SYS_OPEN (0x1)
+#define SYS_CLOSE (0x2)
+#define SYS_WRITE (0x5)
+#define SYS_READ (0x6)
+#define SYS_ISTTY (0x9)
+#define SYS_SEEK (0xa)
+#define SYS_ENSURE (0xb)
+#define SYS_FLEN (0xc)
+#define SYS_REMOVE (0xe)
+#define SYS_RENAME (0xf)
+#define SYS_EXIT (0x18)
+
+FILEHANDLE semihost_open(const char *name, int openmode)
+{
+ uint32_t args[3];
+ args[0] = (uint32_t)name;
+ args[1] = (uint32_t)openmode;
+ args[2] = (uint32_t)strlen(name);
+ return __semihost(SYS_OPEN, args);
+}
+
+int semihost_close(FILEHANDLE fh)
+{
+ return __semihost(SYS_CLOSE, &fh);
+}
+
+int semihost_write(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode)
+{
+ if (length == 0) {
+ return 0;
+ }
+
+ uint32_t args[3];
+ args[0] = (uint32_t)fh;
+ args[1] = (uint32_t)buffer;
+ args[2] = (uint32_t)length;
+ return __semihost(SYS_WRITE, args);
+}
+
+int semihost_read(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode)
+{
+ uint32_t args[3];
+ args[0] = (uint32_t)fh;
+ args[1] = (uint32_t)buffer;
+ args[2] = (uint32_t)length;
+ return __semihost(SYS_READ, args);
+}
+
+int semihost_istty(FILEHANDLE fh)
+{
+ return __semihost(SYS_ISTTY, &fh);
+}
+
+int semihost_seek(FILEHANDLE fh, long position)
+{
+ uint32_t args[2];
+ args[0] = (uint32_t)fh;
+ args[1] = (uint32_t)position;
+ return __semihost(SYS_SEEK, args);
+}
+
+int semihost_ensure(FILEHANDLE fh)
+{
+ return __semihost(SYS_ENSURE, &fh);
+}
+
+long semihost_flen(FILEHANDLE fh)
+{
+ return __semihost(SYS_FLEN, &fh);
+}
+
+int semihost_remove(const char *name)
+{
+ uint32_t args[2];
+ args[0] = (uint32_t)name;
+ args[1] = (uint32_t)strlen(name);
+ return __semihost(SYS_REMOVE, args);
+}
+
+int semihost_rename(const char *old_name, const char *new_name)
+{
+ uint32_t args[4];
+ args[0] = (uint32_t)old_name;
+ args[1] = (uint32_t)strlen(old_name);
+ args[0] = (uint32_t)new_name;
+ args[1] = (uint32_t)strlen(new_name);
+ return __semihost(SYS_RENAME, args);
+}
+
+int semihost_exit(void)
+{
+ uint32_t args[4];
+ return __semihost(SYS_EXIT, args);
+}
+
+int semihost_connected(void)
+{
+ return (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) ? 1 : 0;
+}