summaryrefslogtreecommitdiffstatshomepage
path: root/shared/runtime/semihosting.c
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2024-05-22 10:17:13 +0200
committerDamien George <damien@micropython.org>2024-06-06 12:55:15 +1000
commit90d50ce9189feffb63ebf9b92d4302bd5c12730b (patch)
tree7415727d6a00b1f123a6c2e3f07285ecbcdb663f /shared/runtime/semihosting.c
parentde0e13a9a82fb27a50aa632b6c22663d9d58a4a0 (diff)
downloadmicropython-90d50ce9189feffb63ebf9b92d4302bd5c12730b.tar.gz
micropython-90d50ce9189feffb63ebf9b92d4302bd5c12730b.zip
shared/runtime/semihosting: Rename ARM semihosting files.
Make room for RISC-V semihosting code, by renaming the existing `semihosting.[ch]` files into `semihosting_arm.[ch]`. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Diffstat (limited to 'shared/runtime/semihosting.c')
-rw-r--r--shared/runtime/semihosting.c132
1 files changed, 0 insertions, 132 deletions
diff --git a/shared/runtime/semihosting.c b/shared/runtime/semihosting.c
deleted file mode 100644
index 18c7f5d57a..0000000000
--- a/shared/runtime/semihosting.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Ayke van Laethem
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "semihosting.h"
-
-// Resources:
-// http://embed.rs/articles/2016/semi-hosting-rust/
-// https://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22
-// https://github.com/arduino/OpenOCD/blob/master/src/target/arm_semihosting.c
-
-#define SYS_OPEN 0x01
-#define SYS_WRITEC 0x03
-#define SYS_WRITE 0x05
-#define SYS_READC 0x07
-
-// Constants:
-#define OPEN_MODE_READ (0) // mode "r"
-#define OPEN_MODE_WRITE (4) // mode "w"
-
-#ifndef __thumb__
-#error Semihosting is only implemented for ARM microcontrollers.
-#endif
-
-static int mp_semihosting_stdout;
-
-static uint32_t mp_semihosting_call(uint32_t num, const void *arg) {
- // A semihosting call works as follows, similar to a SVCall:
- // * the call is invoked by a special breakpoint: 0xAB
- // * the command is placed in r0
- // * a pointer to the arguments is placed in r1
- // * the return value is placed in r0
- // Note that because it uses the breakpoint instruction, applications
- // will hang if they're not connected to a debugger. And they'll be
- // stuck in a breakpoint if semihosting is not specifically enabled in
- // the debugger.
- // Also note that semihosting is extremely slow (sometimes >100ms per
- // call).
- register uint32_t num_reg __asm__ ("r0") = num;
- register const void *args_reg __asm__ ("r1") = arg;
- __asm__ __volatile__ (
- "bkpt 0xAB\n" // invoke semihosting call
- : "+r" (num_reg) // call number and result
- : "r" (args_reg) // arguments
- : "memory"); // make sure args aren't optimized away
- return num_reg; // r0, which became the result
-}
-
-static int mp_semihosting_open_console(uint32_t mode) {
- struct {
- char *name;
- uint32_t mode;
- uint32_t name_len;
- } args = {
- .name = ":tt", // magic path to console
- .mode = mode, // e.g. "r", "w" (see OPEN_MODE_* constants)
- .name_len = 3, // strlen(":tt")
- };
- return mp_semihosting_call(SYS_OPEN, &args);
-}
-
-void mp_semihosting_init() {
- mp_semihosting_stdout = mp_semihosting_open_console(OPEN_MODE_WRITE);
-}
-
-int mp_semihosting_rx_char() {
- return mp_semihosting_call(SYS_READC, NULL);
-}
-
-static void mp_semihosting_tx_char(char c) {
- mp_semihosting_call(SYS_WRITEC, &c);
-}
-
-uint32_t mp_semihosting_tx_strn(const char *str, size_t len) {
- if (len == 0) {
- return 0; // nothing to do
- }
- if (len == 1) {
- mp_semihosting_tx_char(*str); // maybe faster?
- return 0;
- }
-
- struct {
- uint32_t fd;
- const char *str;
- uint32_t len;
- } args = {
- .fd = mp_semihosting_stdout,
- .str = str,
- .len = len,
- };
- return mp_semihosting_call(SYS_WRITE, &args);
-}
-
-uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len) {
- // Write chunks of data until (excluding) the first '\n' character,
- // insert a '\r' character, and then continue with the next chunk
- // (starting with '\n').
- // Doing byte-by-byte writes would be easier to implement but is far
- // too slow.
- size_t start = 0;
- for (size_t i = 0; i < len; i++) {
- if (str[i] == '\n') {
- mp_semihosting_tx_strn(str + start, i - start);
- mp_semihosting_tx_char('\r');
- start = i;
- }
- }
- return mp_semihosting_tx_strn(str + start, len - start);
-}