usbuart: Moved the SemiHosting implementation to usb_serial.c

This commit is contained in:
dragonmux 2022-08-19 00:46:34 +01:00 committed by Piotr Esden-Tempski
parent 15a37f830a
commit 35e88d0409
2 changed files with 77 additions and 79 deletions

View File

@ -212,4 +212,81 @@ size_t usbuart_debug_write(const char *buf, const size_t len)
return len;
}
/*
* newlib defines _write as a weak link'd function for user code to override.
*
* This function forms the root of the implementation of a variety of functions
* that can write to stdout/stderr, including printf().
*
* The result of this function is the number of bytes written.
*/
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
int _write(const int file, const void *const ptr, const size_t len)
{
(void)file;
#ifdef PLATFORM_HAS_DEBUG
if (debug_bmp)
return usbuart_debug_write(ptr, len);
#endif
return len;
}
/*
* newlib defines isatty as a weak link'd function for user code to override.
*
* The result of this function is always 'true'.
*/
int isatty(const int file)
{
(void)file;
return true;
}
enum {
RDI_SYS_OPEN = 0x01,
};
typedef struct ex_frame {
uint32_t r0;
const uint32_t *params;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uintptr_t lr;
uintptr_t return_address;
} ex_frame_s;
void debug_monitor_handler(void) __attribute__((used)) __attribute__((naked));
/*
* This implements the other half of the newlib syscall puzzle.
* When newlib is built for ARM, various calls that do file IO
* such as printf end up calling [_swiwrite](https://github.com/mirror/newlib-cygwin/blob/master/newlib/libc/sys/arm/syscalls.c#L317)
* and other similar low-level implementation functions. These
* generate `swi` instructions for the "RDI Monitor" and that lands us.. here.
*
* The RDI calling convention sticks the file number in r0, the buffer pointer in r1, and length in r2.
* ARMv7-M's SWI (SVC) instruction then takes all that and maps it into an exception frame on the stack.
*/
void debug_monitor_handler(void)
{
ex_frame_s *frame;
__asm__(
"mov %[frame], sp" :
[frame] "=r" (frame)
);
/* Make sure to return to the instruction after the SWI/BKPT */
frame->return_address += 2U;
switch (frame->r0) {
case RDI_SYS_OPEN:
frame->r0 = 1;
break;
default:
frame->r0 = UINT32_MAX;
}
__asm__("bx lr");
}
#endif

View File

@ -492,82 +492,3 @@ void USBUSART_DMA_RXTX_ISR(void)
USBUSART_DMA_TX_ISR();
}
#endif
#ifdef ENABLE_DEBUG
/*
* newlib defines _write as a weak link'd function for user code to override.
*
* This function forms the root of the implementation of a variety of functions
* that can write to stdout/stderr, including printf().
*
* The result of this function is the number of bytes written.
*/
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
int _write(const int file, const void *const ptr, const size_t len)
{
(void)file;
#ifdef PLATFORM_HAS_DEBUG
if (debug_bmp)
return usbuart_debug_write(ptr, len);
#endif
return len;
}
/*
* newlib defines isatty as a weak link'd function for user code to override.
*
* The result of this function is always 'true'.
*/
int isatty(const int file)
{
(void)file;
return true;
}
enum {
RDI_SYS_OPEN = 0x01,
};
typedef struct ex_frame {
uint32_t r0;
const uint32_t *params;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uintptr_t lr;
uintptr_t return_address;
} ex_frame_s;
void debug_monitor_handler(void) __attribute__((used)) __attribute__((naked));
/*
* This implements the other half of the newlib syscall puzzle.
* When newlib is built for ARM, various calls that do file IO
* such as printf end up calling [_swiwrite](https://github.com/mirror/newlib-cygwin/blob/master/newlib/libc/sys/arm/syscalls.c#L317)
* and other similar low-level implementation functions. These
* generate `swi` instructions for the "RDI Monitor" and that lands us.. here.
*
* The RDI calling convention sticks the file number in r0, the buffer pointer in r1, and length in r2.
* ARMv7-M's SWI (SVC) instruction then takes all that and maps it into an exception frame on the stack.
*/
void debug_monitor_handler(void)
{
ex_frame_s *frame;
__asm__(
"mov %[frame], sp" :
[frame] "=r" (frame)
);
/* Make sure to return to the instruction after the SWI/BKPT */
frame->return_address += 2U;
switch (frame->r0) {
case RDI_SYS_OPEN:
frame->r0 = 1;
break;
default:
frame->r0 = UINT32_MAX;
}
__asm__("bx lr");
}
#endif