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;
+}