diff --git a/Makefile b/Makefile index d19a219..9a4a529 100644 --- a/Makefile +++ b/Makefile @@ -4,12 +4,14 @@ CC = clang INCLUDE=include -# Note that QEMU_DEBUG needs to be defined! +# If you want debug_puts() etcetera to output something on our QEMU +# debug port, use -DQEMU_DEBUG below, or -DTKEY_DEBUG to use Tkeys USB debug pipe CFLAGS = -target riscv32-unknown-none-elf -march=rv32iczmmul -mabi=ilp32 \ -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common \ -fno-builtin-printf -fno-builtin-putchar -nostdlib -mno-relax -flto \ -Wall -Werror=implicit-function-declaration \ - -I $(INCLUDE) -I . -D QEMU_DEBUG + -I $(INCLUDE) -I . + # -DQEMU_DEBUG -DTKEY_DEBUG AS = clang AR = llvm-ar @@ -38,12 +40,13 @@ libcrt0.a: libcrt0/crt0.o # Common C functions LIBOBJS=libcommon/assert.o libcommon/blake2s.o libcommon/led.o libcommon/lib.o \ - libcommon/proto.o libcommon/touch.o libcommon/qemu_debug.o + libcommon/proto.o libcommon/touch.o libcommon/qemu_debug.o \ + libcommon/tkey_debug.o libcommon.a: $(LIBOBJS) $(AR) -qc $@ $(LIBOBJS) $(LIBOBJS): include/tkey/assert.h include/tkey/blake2s.h include/tkey/led.h \ include/tkey/lib.h include/tkey/proto.h include/tkey/tk1_mem.h \ - include/tkey/touch.h include/tkey/qemu_debug.h + include/tkey/touch.h include/tkey/debug.h # Monocypher MONOOBJS=monocypher/monocypher.o monocypher/monocypher-ed25519.o diff --git a/example-app/Makefile b/example-app/Makefile index ffa1a16..fc13395 100644 --- a/example-app/Makefile +++ b/example-app/Makefile @@ -2,12 +2,15 @@ P := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) LIBDIR ?= $(P)/../ OBJCOPY ?= llvm-objcopy CC = clang + +# If you want debug_puts() etcetera to output something on our QEMU +# debug port, use -DQEMU_DEBUG below, or -DTKEY_DEBUG to use Tkeys USB debug pipe CFLAGS = -g -target riscv32-unknown-none-elf -march=rv32iczmmul -mabi=ilp32 -mcmodel=medany \ -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf \ -fno-builtin-putchar -nostdlib -mno-relax -flto \ -Wall -Werror=implicit-function-declaration \ - -I $(LIBDIR)/include -I $(LIBDIR) \ -# -D QEMU_DEBUG + -I $(LIBDIR)/include -I $(LIBDIR) + # -DQEMU_DEBUG -DTKEY_DEBUG INCLUDE=$(LIBDIR)/include diff --git a/example-app/blue.c b/example-app/blue.c index 556ae89..0dd3e0f 100644 --- a/example-app/blue.c +++ b/example-app/blue.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #define SLEEPTIME 100000 @@ -15,10 +15,10 @@ void sleep(uint32_t n) int main(void) { - qemu_puts("Hello, world!\n"); - qemu_puts("Going to sleep between blinks: "); - qemu_putinthex(SLEEPTIME); - qemu_lf(); + debug_puts("Hello, world!\n"); + debug_puts("Going to sleep between blinks: "); + debug_putinthex(SLEEPTIME); + debug_lf(); for (;;) { led_set(LED_RED); diff --git a/include/tkey/debug.h b/include/tkey/debug.h new file mode 100644 index 0000000..881b6a4 --- /dev/null +++ b/include/tkey/debug.h @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2023 Tillitis AB +// SPDX-License-Identifier: BSD-2-Clause + +#ifndef TKEY_DEBUG_H +#define TKEY_DEBUG_H + +#include + +#if defined(QEMU_DEBUG) + +void qemu_putchar(const uint8_t ch); +void qemu_lf(); +void qemu_putinthex(const uint32_t n); +void qemu_puts(const char *s); +void qemu_puthex(const uint8_t ch); +void qemu_hexdump(const uint8_t *buf, int len); + +#define debug_putchar qemu_putchar +#define debug_lf qemu_lf +#define debug_putinthex qemu_putinthex +#define debug_puts qemu_puts +#define debug_puthex qemu_puthex +#define debug_hexdump qemu_hexdump + +#elif defined(TKEY_DEBUG) + +void tkey_putchar(const uint8_t ch); +void tkey_lf(); +void tkey_putinthex(const uint32_t n); +void tkey_puts(const char *s); +void tkey_puthex(const uint8_t ch); +void tkey_hexdump(const uint8_t *buf, int len); + +#define debug_putchar tkey_putchar +#define debug_lf tkey_lf +#define debug_putinthex tkey_putinthex +#define debug_puts tkey_puts +#define debug_puthex tkey_puthex +#define debug_hexdump tkey_hexdump + +#else + +#define debug_putchar(ch) +#define debug_lf() +#define debug_putinthex(n) +#define debug_puts(s) +#define debug_puthex(ch) +#define debug_hexdump(buf, len) + +#endif + +#endif diff --git a/include/tkey/proto.h b/include/tkey/proto.h index 4d39618..2f528c8 100644 --- a/include/tkey/proto.h +++ b/include/tkey/proto.h @@ -8,6 +8,7 @@ #define TKEY_PROTO_H enum mode { + MODE_TKEYCTRL = 0x20, MODE_CDC = 0x40, MODE_HID = 0x80, }; diff --git a/include/tkey/qemu_debug.h b/include/tkey/qemu_debug.h deleted file mode 100644 index 660e149..0000000 --- a/include/tkey/qemu_debug.h +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Tillitis AB -// SPDX-License-Identifier: BSD-2-Clause - -#ifndef TKEY_QEMU_DEBUG_H -#define TKEY_QEMU_DEBUG_H - -#include - -#ifndef QEMU_DEBUG -#define qemu_putchar(ch) -#define qemu_lf() -#define qemu_putinthex(n) -#define qemu_puts(s) -#define qemu_puthex(ch) -#define qemu_hexdump(buf, len) -#else -int qemu_putchar(const uint8_t ch); -void qemu_lf(); -void qemu_putinthex(const uint32_t n); -void qemu_puts(const char *s); -void qemu_puthex(const uint8_t ch); -void qemu_hexdump(const uint8_t *buf, int len); -#endif - -#endif diff --git a/libcommon/assert.c b/libcommon/assert.c index 2da69cb..fe9c470 100644 --- a/libcommon/assert.c +++ b/libcommon/assert.c @@ -3,20 +3,20 @@ #include #include -#include +#include void assert_fail(const char *assertion, const char *file, unsigned int line, const char *function) { - qemu_puts("assert: "); - qemu_puts(assertion); - qemu_puts(" "); - qemu_puts(file); - qemu_puts(":"); - qemu_putinthex(line); - qemu_puts(" "); - qemu_puts(function); - qemu_lf(); + debug_puts("assert: "); + debug_puts(assertion); + debug_puts(" "); + debug_puts(file); + debug_puts(":"); + debug_putinthex(line); + debug_puts(" "); + debug_puts(function); + debug_lf(); // Force illegal instruction to halt CPU asm volatile("unimp"); diff --git a/libcommon/proto.c b/libcommon/proto.c index 4835ccb..0e99220 100644 --- a/libcommon/proto.c +++ b/libcommon/proto.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include // clang-format off @@ -86,10 +86,10 @@ uint8_t readbyte(uint8_t *mode, uint8_t *mode_bytes_left) { if (*mode_bytes_left == 0) { *mode = readbyte_(); - if (*mode != MODE_CDC) { - qemu_puts("We only support MODE_CDC\n"); - } else { + if ((*mode == MODE_CDC) || (*mode == MODE_HID) || (*mode == MODE_TKEYCTRL)) { *mode_bytes_left = readbyte_(); + } else { + debug_puts("We only support MODE_CDC, MODE_HID and MODE_TKEYCTRL\n"); } } uint8_t b = readbyte_(); diff --git a/libcommon/qemu_debug.c b/libcommon/qemu_debug.c index 3bd4f46..8a9de06 100644 --- a/libcommon/qemu_debug.c +++ b/libcommon/qemu_debug.c @@ -3,18 +3,21 @@ #include #include -#include #include +#ifndef QEMU_DEBUG +#define QEMU_DEBUG +#endif + +#include + // clang-format off static volatile uint8_t* const debugtx = (volatile uint8_t *)TK1_MMIO_QEMU_DEBUG; // clang-format on -int qemu_putchar(const uint8_t ch) +void qemu_putchar(const uint8_t ch) { *debugtx = ch; - - return ch; } void qemu_lf() @@ -92,7 +95,7 @@ void qemu_hexdump(const uint8_t *buf, int len) for (int i = 0; i < len; i++) { qemu_puthex(byte_buf[i]); if (i % 2 == 1) { - (void)qemu_putchar(' '); + qemu_putchar(' '); } if ((i + 1) % 16 == 0) { diff --git a/libcommon/tkey_debug.c b/libcommon/tkey_debug.c new file mode 100644 index 0000000..99895dc --- /dev/null +++ b/libcommon/tkey_debug.c @@ -0,0 +1,158 @@ +// SPDX-FileCopyrightText: 2023 Tillitis AB +// SPDX-License-Identifier: BSD-2-Clause + +#include +#include +#include +#include + +#ifndef TKEY_DEBUG +#define TKEY_DEBUG +#endif + +#include + +// clang-format off +static volatile uint32_t *can_tx = (volatile uint32_t *)TK1_MMIO_UART_TX_STATUS; +static volatile uint32_t *tx = (volatile uint32_t *)TK1_MMIO_UART_TX_DATA; +// clang-format on + +void tkey_writebyte(uint8_t b) +{ + for (;;) { + if (*can_tx) { + *tx = b; + return; + } + } +} + +void tkey_write(const uint8_t *buf, size_t nbytes) +{ + for (int i = 0; i < nbytes; i++) { + tkey_writebyte(buf[i]); + } +} + +void tkey_write_with_header(const uint8_t *buf, size_t nbytes) +{ + tkey_writebyte(MODE_TKEYCTRL); + tkey_writebyte(nbytes); + + for (int i = 0; i < nbytes; i++) { + tkey_writebyte(buf[i]); + } +} + +void tkey_putchar(const uint8_t ch) +{ + tkey_writebyte(MODE_TKEYCTRL); + tkey_writebyte(1); + + tkey_writebyte(ch); +} + +void tkey_lf() +{ + tkey_writebyte(MODE_TKEYCTRL); + tkey_writebyte(1); + + tkey_writebyte('\n'); +} + +static char hexnibble(const uint8_t ch) +{ + switch (ch) { + case 0x0: + return '0'; + case 0x1: + return '1'; + case 0x2: + return '2'; + case 0x3: + return '3'; + case 0x4: + return '4'; + case 0x5: + return '5'; + case 0x6: + return '6'; + case 0x7: + return '7'; + case 0x8: + return '8'; + case 0x9: + return '9'; + case 0xa: + return 'a'; + case 0xb: + return 'b'; + case 0xc: + return 'c'; + case 0xd: + return 'd'; + case 0xe: + return 'e'; + case 0xf: + return 'f'; + } + + return '0'; +} + +void tkey_puthex(const uint8_t ch) +{ + tkey_writebyte(MODE_TKEYCTRL); + tkey_writebyte(2); + + tkey_writebyte(hexnibble(ch >> 4 & 0x0f)); + tkey_writebyte(hexnibble(ch & 0x0f)); +} + +void tkey_putinthex(const uint32_t n) +{ + uint8_t buf[4]; + + tkey_writebyte(MODE_TKEYCTRL); + tkey_writebyte(2); + + memcpy(buf, &n, 4); + tkey_write((uint8_t*) "0x", 2); + for (int i = 3; i > -1; i--) { + tkey_puthex(buf[i]); + } +} + +size_t tkey_strlen(const char *str) +{ + register const char *s; + for (s = str; *s; ++s); + return (s - str); +} + +void tkey_puts(const char *s) +{ + size_t len = tkey_strlen(s); /* TODO: Fix splitup of lengths longer than 255 to multiple strings */ + + tkey_writebyte(MODE_TKEYCTRL); + tkey_writebyte(len); + tkey_write((const uint8_t*) s, len); +} + +void tkey_hexdump(const uint8_t *buf, int len) +{ + uint8_t *byte_buf = (uint8_t *)buf; + + for (int i = 0; i < len; i++) { + tkey_puthex(byte_buf[i]); + if (i % 2 == 1) { + tkey_putchar(' '); + } + + if ((i + 1) % 16 == 0) { + tkey_lf(); + } + } + + tkey_lf(); +} diff --git a/libcommon/touch.c b/libcommon/touch.c index cb4ac0b..3914564 100644 --- a/libcommon/touch.c +++ b/libcommon/touch.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include // CPU clock frequenzy in Hz