diff options
Diffstat (limited to 'cmd/sbc_harness')
20 files changed, 0 insertions, 1374 deletions
diff --git a/cmd/sbc_harness/CMakeLists.txt b/cmd/sbc_harness/CMakeLists.txt deleted file mode 100644 index 6e722d7..0000000 --- a/cmd/sbc_harness/CMakeLists.txt +++ /dev/null @@ -1,84 +0,0 @@ -# cmd/sbc_harness/CMakeLists.txt - Build script for main sbc_harness.uf2 firmware file -# -# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> -# SPDX-License-Identifier: AGPL-3.0-or-later - -if (PICO_PLATFORM STREQUAL "rp2040") - -# Compile ###################################################################### - -add_library(sbc_harness_objs OBJECT - main.c - usb_keyboard.c - tusb_log.c - - fs_harness_flash_bin.c - fs_harness_uptime_txt.c -) -target_include_directories(sbc_harness_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) -target_include_directories(sbc_harness_objs PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(sbc_harness_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(sbc_harness_objs - pico_runtime - pico_stdio_uart - - hardware_flash - hardware_watchdog - - libmisc - libfmt - libusb - libdhcp - libhw_cr - lib9p_srv - lib9p_util -) -pico_minimize_runtime(sbc_harness_objs - INCLUDE PRINTF PRINTF_MINIMAL PRINTF_LONG_LONG PRINTF_PTRDIFF_T -) -target_compile_definitions(sbc_harness_objs PRIVATE - #PICO_USE_FASTEST_SUPPORTED_CLOCK=1 - - # Calculated by `./3rd-party/pico-sdk/src/rp2_common/hardware_clocks/scripts/vcocalc.py --cmake-only 170` - PLL_SYS_REFDIV=2 - PLL_SYS_VCO_FREQ_HZ=1530000000 - PLL_SYS_POSTDIV1=3 - PLL_SYS_POSTDIV2=3 - SYS_CLK_HZ=170000000 -) - -suppress_tinyusb_warnings() - -# Analyze the stack ############################################################ - -add_stack_analysis(sbc_harness_stack.c sbc_harness_objs) - -# Link ######################################################################### - -add_executable(sbc_harness) -target_sources(sbc_harness PRIVATE - sbc_harness_stack.c - "$<TARGET_OBJECTS:sbc_harness_objs>" -) -target_link_libraries(sbc_harness - pico_standard_link -) -target_link_options(sbc_harness PRIVATE "$<TARGET_PROPERTY:sbc_harness_objs,LINK_OPTIONS>") -pico_add_extra_outputs(sbc_harness) # create .map/.bin/.hex/.uf2 files in addition to .elf -pico_set_program_url(sbc_harness "https://git.lukeshu.com/sbc-harness") - -# Embed ######################################################################## - -target_embed_sources(sbc_harness_objs sbc_harness static.h - static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS.md - static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/agpl-3.0.txt - static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/pico-sdk.bsd3.txt - static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/printf.mit.txt - static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/tinyusb.mit.txt - static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/newlib.txt - static/Documentation/harness_rom_bin.txt - static/Documentation/harness_flash_bin.txt - static/Documentation/harness_uptime_txt.txt -) - -endif() diff --git a/cmd/sbc_harness/config/config.h b/cmd/sbc_harness/config/config.h deleted file mode 100644 index 5367dbe..0000000 --- a/cmd/sbc_harness/config/config.h +++ /dev/null @@ -1,114 +0,0 @@ -/* config.h - Compile-time configuration for sbc_harness - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#include <stddef.h> /* for size_t */ - -#define CONFIG_FLASH_DEBUG 1 - -#define _CONFIG_9P_MAX_CONNS 3 /* FIXME: bump this back up to 8 */ -#define _CONFIG_9P_MAX_REQS (2*_CONFIG_9P_MAX_CONNS) - -/* RP2040 *********************************************************************/ - -#define CONFIG_RP2040_SPI_DEBUG 1 /* bool */ - -/* W5500 **********************************************************************/ - -/** - * When allocating an arbitrary local port, what range should it be - * allocated from? - * - * These are the default values of the Linux kernel's - * net.ipv4.ip_local_port_range, so I figure they're probably good - * values to use. - */ -#define CONFIG_W5500_LOCAL_PORT_MIN 32768 -#define CONFIG_W5500_LOCAL_PORT_MAX 60999 - -#define CONFIG_W5500_VALIDATE_SPI 1 /* bool */ -#define CONFIG_W5500_DEBUG 0 /* bool */ -#define CONFIG_W5500_LL_DEBUG 0 /* bool */ - -/* 9P *************************************************************************/ - -#define CONFIG_9P_MAX_ERR_SIZE 128 /* 128 is what Plan 9 4e uses */ - -/** - * This max-msg-size is sized so that a Twrite message can return - * 8KiB of data. - * - * This is the same as the default in Plan 9 4e's lib9p; it has the - * comment that "24" is "ample room for Twrite/Rread header - * (iounit)". In fact, the Twrite header is only 23 bytes - * ("size[4] Twrite[1] tag[2] fid[4] offset[8] count[4]") and the - * Rread header is even shorter at 11 bytes ("size[4] Rread[1] - * tag[2] count[4]"), so "24" appears to be the size of the Twrite - * header rounded up to a nice round number. - * - * In older versions of 9P ("9P1"), the max message size was - * defined as part of the protocol specification rather than - * negotiated. In Plan 9 1e it was (8*1024)+128, and was bumped to - * (8*1024)+160 in 2e and 3e. - */ -#define CONFIG_9P_SRV_MAX_MSG_SIZE ((4*1024)+24) -/** - * Maximum host-data-structure size. A message may be larger in - * unmarshaled-host-structures than marshaled-net-bytes due to (1) - * struct padding, (2) array pointers. - */ -#define CONFIG_9P_SRV_MAX_HOSTMSG_SIZE CONFIG_9P_SRV_MAX_MSG_SIZE+16 - -#define CONFIG_9P_ENABLE_9P2000 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_e 0 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_L 0 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_p9p 0 /* bool */ - -/* DHCP ***********************************************************************/ - -#define CONFIG_DHCP_CAN_RECV_UNICAST_IP_WITHOUT_IP 0 /* bool */ -#define CONFIG_DHCP_DEBUG 1 /* bool */ -#define CONFIG_DHCP_OPT_SIZE 312 /* minimum of 312 */ -#define CONFIG_DHCP_SELECTING_NS (5*NS_PER_S) - -/* USB KEYBOARD ***************************************************************/ - -/** - * Which USB port to use for the Root Hub. - * - * The RP2040 only has 1 port, so it's gotta be port #0. - */ -#define CONFIG_USB_COMMON_RHPORT 0 - -#define CONFIG_USB_COMMON_DEBUG 1 /* bool */ - -/* COROUTINE ******************************************************************/ - -extern const size_t CONFIG_COROUTINE_STACK_SIZE_dhcp_cr; -extern const size_t CONFIG_COROUTINE_STACK_SIZE_init_cr; -extern const size_t CONFIG_COROUTINE_STACK_SIZE_read9p_cr; -extern const size_t CONFIG_COROUTINE_STACK_SIZE_write9p_cr; -extern const size_t CONFIG_COROUTINE_STACK_SIZE_usb_common_cr; -extern const size_t CONFIG_COROUTINE_STACK_SIZE_usb_keyboard_cr; -extern const size_t CONFIG_COROUTINE_STACK_SIZE_w5500_irq_cr; -#define CONFIG_COROUTINE_NAME_LEN 16 -#define CONFIG_COROUTINE_MEASURE_STACK 1 /* bool */ -#define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */ -#define CONFIG_COROUTINE_DEBUG 0 /* bool */ -#define CONFIG_COROUTINE_VALGRIND 0 /* bool */ -#define CONFIG_COROUTINE_GDB 1 /* bool */ - -#define CONFIG_COROUTINE_NUM ( \ - 1 /* usb_common */ + \ - 1 /* usb_keyboard */ + \ - 1 /* W5500 irq handler */ + \ - _CONFIG_9P_MAX_CONNS /* 9P accept()+read() */ + \ - _CONFIG_9P_MAX_REQS /* 9P work+write() */ ) - -#endif /* _CONFIG_H_ */ diff --git a/cmd/sbc_harness/config/tusb_config.h b/cmd/sbc_harness/config/tusb_config.h deleted file mode 100644 index 0a6d3e4..0000000 --- a/cmd/sbc_harness/config/tusb_config.h +++ /dev/null @@ -1,129 +0,0 @@ -/* tusb_config.h - Compile-time configuration for the TinyUSB library - * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * SPDX-License-Identifier: MIT - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * 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. - * - */ - -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -//-------------------------------------------------------------------- -// Override the default definition of TU_ASSERT() to use our logging -//-------------------------------------------------------------------- - -// "magically" select between the 1-arg and 2-args variants, inject a -// stringified version of `_cond`. -// -// Note: Use GNU-C `, ##__VA_ARGS__`, not standard C `__VA_OPT__(,) -// __VA_ARGS__`; because __VA_OPT__ doesn't handle present-but-empty -// arguments the way that we need. -#define TU_ASSERT(_cond, ...) \ - _GET_3RD_ARG(_cond, ##__VA_ARGS__, \ - _LIBMISC_TU_ASSERT_2ARGS, _LIBMISC_TU_ASSERT_1ARGS, _dummy) \ - (_cond, #_cond, ##__VA_ARGS__) - -#define _LIBMISC_TU_ASSERT_1ARGS(_cond, _cond_str) \ - _LIBMISC_TU_ASSERT_2ARGS(_cond, _cond_str, false) - -#define _LIBMISC_TU_ASSERT_2ARGS(_cond, _cond_str, _ret) \ - do { \ - if ( !(_cond) ) { \ - _libmisc_tu_mess_failed(_cond_str, \ - __FILE__, __LINE__, __func__); \ - TU_BREAKPOINT(); \ - return _ret; \ - } \ - } while(0) - -void _libmisc_tu_mess_failed(const char *expr, - const char *file, unsigned int line, const char *func); - -//-------------------------------------------------------------------- -// Configuration: common -//-------------------------------------------------------------------- - -// defined by compiler flags -#ifndef CFG_TUSB_MCU -#error CFG_TUSB_MCU must be defined -#endif - -// Conditional because it might be defined with `-D` on the command -// line if `cmake -DCMAKE_BUILD_TYPE=Debug`. -#ifndef CFG_TUSB_DEBUG -#define CFG_TUSB_DEBUG 0 -#endif - -// USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. -// Tinyusb use follows macros to declare transferring memory so that they can be put -// into those specific section. -// e.g -// - CFG_TUSB_MEM SECTION : [[gnu::section(".usb_ram")]] -// - CFG_TUSB_MEM_ALIGN : [[gnu::aligned(4)]] -#define CFG_TUSB_MEM_SECTION /* blank */ -#define CFG_TUSB_MEM_ALIGN [[gnu::aligned(4)]] - -#define CFG_TUD_ENABLED 1 -#define CFG_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED - -//-------------------------------------------------------------------- -// Configuration: TinyUSB Device (TUD) -//-------------------------------------------------------------------- - -// control endpoint max packet size (only 8, 16, 32, or 64 are valid) -#define CFG_TUD_ENDPOINT0_SIZE 64 - -// Which of TinyUSB's built-in class drivers to enable. -// -// If a class takes an int, that's the maximum number of interfaces of -// that type that may be listed in the same configuration descriptor. -#define CFG_TUD_CDC 0 // int : Communications Device Class (e.g. ttyUSB) https://www.usb.org/sites/default/files/CDC1.2_WMC1.1_012011.zip -#define CFG_TUD_MSC 0 // bool: Mass Storage Class https://www.usb.org/sites/default/files/Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf -#define CFG_TUD_HID 1 // int : Human Interface Device https://www.usb.org/sites/default/files/hid1_11.pdf -#define CFG_TUD_AUDIO 0 // int : Audio https://www.usb.org/sites/default/files/audio10.pdf -#define CFG_TUD_VIDEO 0 // int : Video https://www.usb.org/sites/default/files/USB_Video_Class_1_5.zip -#define CFG_TUD_MIDI 0 // int : Musical Instrument Digital Interface https://www.usb.org/sites/default/files/USB%20MIDI%20v2_0.pdf -#define CFG_TUD_VENDOR 0 // int : ??? -#define CFG_TUD_USBTMC 0 // bool: Test & Measurement Class https://www.usb.org/sites/default/files/USBTMC_1_006a.zip -#define CFG_TUD_DFU_RUNTIME 0 // bool: Device Firmware Upgrade https://www.usb.org/sites/default/files/DFU_1.1.pdf -#define CFG_TUD_DFU 0 // bool: Device Firmware Upgrade https://www.usb.org/sites/default/files/DFU_1.1.pdf -#define CFG_TUD_ECM_RNDIS 0 // bool: net -#define CFG_TUD_NCM 0 // bool: net -#define CFG_TUD_BTH 0 // bool: Bluetooth - -// HID buffer size Should be sufficient to hold ID (if any) + Data -#define CFG_TUD_HID_EP_BUFSIZE 8 - -//-------------------------------------------------------------------- -#ifdef __cplusplus -} -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/cmd/sbc_harness/fs_harness_flash_bin.c b/cmd/sbc_harness/fs_harness_flash_bin.c deleted file mode 100644 index bc3d061..0000000 --- a/cmd/sbc_harness/fs_harness_flash_bin.c +++ /dev/null @@ -1,312 +0,0 @@ -/* sbc_harness/fs_harness_flash_bin.c - 9P access to flash storage - * - * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#include <string.h> - -#include <hardware/flash.h> -#include <hardware/watchdog.h> - -#define LOG_NAME FLASH -#include <libmisc/log.h> - -#include <util9p/static.h> - -#define IMPLEMENTATION_FOR_FS_HARNESS_FLASH_BIN YES -#include "fs_harness_flash_bin.h" - -LO_IMPLEMENTATION_C(lib9p_srv_file, struct flash_file, flash_file, static); - -LO_IMPLEMENTATION_H(lib9p_srv_fio, struct flash_file, flash_file); -LO_IMPLEMENTATION_C(lib9p_srv_fio, struct flash_file, flash_file, static); - -#define DATA_START ((const char *)(XIP_NOALLOC_BASE)) -#define DATA_SIZE PICO_FLASH_SIZE_BYTES -#define DATA_HSIZE (DATA_SIZE/2) -static_assert(DATA_SIZE % FLASH_SECTOR_SIZE == 0); -static_assert(DATA_HSIZE % FLASH_SECTOR_SIZE == 0); - -/* There are some memcpy()s (and memcmp()s?) in here that can (and - * arguably should) be replaced with SSI DMA. */ - -/* ab_flash_* (mid-level utilities for our A/B write scheme) ******************/ - -/** - * Copy the upper half of flash to the lower half of flash, then reboot. - * - * @param buf : a scratch buffer that is at least FLASH_SECTOR_SIZE - */ -[[noreturn]] static void __no_inline_not_in_flash_func(ab_flash_finalize)(uint8_t *buf) { - assert(buf); - - infof("copying upper flash to lower flash..."); - - cr_save_and_disable_interrupts(); - - for (size_t off = 0; off < DATA_HSIZE; off += FLASH_SECTOR_SIZE) { - memcpy(buf, DATA_START+DATA_HSIZE+off, FLASH_SECTOR_SIZE); - if (memcmp(DATA_START+off, buf, FLASH_SECTOR_SIZE) == 0) - continue; - flash_range_erase(off, FLASH_SECTOR_SIZE); - flash_range_program(off, buf, FLASH_SECTOR_SIZE); - } - - infof("rebooting..."); - - watchdog_reboot(0, 0, 300); - - for (;;) - asm volatile ("nop"); -} - -/** - * Set the upper half of flash to all zero bytes. - * - * @param buf : a scratch buffer that is at least FLASH_SECTOR_SIZE - */ -static void ab_flash_initialize_zero(uint8_t *buf) { - assert(buf); - - memset(buf, 0, FLASH_SECTOR_SIZE); - - infof("zeroing upper flash..."); - for (size_t off = DATA_HSIZE; off < DATA_SIZE; off += FLASH_SECTOR_SIZE) { - if (memcmp(buf, DATA_START+off, FLASH_SECTOR_SIZE) == 0) - continue; - bool saved = cr_save_and_disable_interrupts(); - /* No need to `flash_range_erase()`; the way the flash - * works is that _erase() sets all bits to 1, and - * _program() sets some bits to 0. If we don't need - * any bits to be 1, then we can skip the - * _erase(). */ - flash_range_program(off, buf, FLASH_SECTOR_SIZE); - cr_restore_interrupts(saved); - } - debugf("... zeroed"); -} - -/** - * Copy the lower half of flash to the upper half of flash. - * - * @param buf : a scratch buffer that is at least FLASH_SECTOR_SIZE - */ -static void ab_flash_initialize(uint8_t *buf) { - assert(buf); - - infof("initializing upper flash..."); - for (size_t off = 0; off < DATA_HSIZE; off += FLASH_SECTOR_SIZE) { - memcpy(buf, DATA_START+off, FLASH_SECTOR_SIZE); - if (memcmp(buf, DATA_START+DATA_HSIZE+off, FLASH_SECTOR_SIZE) == 0) - continue; - bool saved = cr_save_and_disable_interrupts(); - flash_range_erase(DATA_HSIZE+off, FLASH_SECTOR_SIZE); - flash_range_program(DATA_HSIZE+off, buf, FLASH_SECTOR_SIZE); - cr_restore_interrupts(saved); - } - debugf("... initialized"); -} - -/** - * Write `dat` to flash sector `pos`+(DATA_SIZE/2) (i.e. `pos` is a - * sector in the lower half, but this function writes to the upper - * half). - * - * @param pos : start-position of the sector to write to, must be in the upper half of the flash - * @param dat : the FLASH_SECTOR_SIZE bytes to write - */ -static void ab_flash_write_sector(size_t pos, uint8_t *dat) { - assert(pos < DATA_HSIZE); - assert(pos % FLASH_SECTOR_SIZE == 0); - assert(dat); - - pos += DATA_HSIZE; - - infof("write flash sector @ %zu...", pos); - if (memcmp(dat, DATA_START+pos, FLASH_SECTOR_SIZE) != 0) { - bool saved = cr_save_and_disable_interrupts(); - flash_range_erase(pos, FLASH_SECTOR_SIZE); - flash_range_program(pos, dat, FLASH_SECTOR_SIZE); - cr_restore_interrupts(saved); - } - debugf("... written"); -} - -/* srv_file *******************************************************************/ - -static void flash_file_free(struct flash_file *self) { - assert(self); -} -static struct lib9p_qid flash_file_qid(struct flash_file *self) { - assert(self); - - return (struct lib9p_qid){ - .type = LIB9P_QT_FILE|LIB9P_QT_EXCL, - .vers = 1, - .path = self->pathnum, - }; -} - -static struct lib9p_stat flash_file_stat(struct flash_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - - return (struct lib9p_stat){ - .kern_type = 0, - .kern_dev = 0, - .file_qid = flash_file_qid(self), - .file_mode = LIB9P_DM_EXCL|0666, - .file_atime = UTIL9P_ATIME, - .file_mtime = UTIL9P_MTIME, - .file_size = DATA_SIZE, - .file_name = lib9p_str(self->name), - .file_owner_uid = lib9p_str("root"), - .file_owner_gid = lib9p_str("root"), - .file_last_modified_uid = lib9p_str("root"), - .file_extension = lib9p_str(NULL), - .file_owner_n_uid = 0, - .file_owner_n_gid = 0, - .file_last_modified_n_uid = 0, - }; -} -static void flash_file_wstat(struct flash_file *self, struct lib9p_srv_ctx *ctx, - struct lib9p_stat) { - assert(self); - assert(ctx); - - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem"); -} -static void flash_file_remove(struct flash_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem"); -} - -LIB9P_SRV_NOTDIR(struct flash_file, flash_file); - -static lo_interface lib9p_srv_fio flash_file_fopen(struct flash_file *self, struct lib9p_srv_ctx *ctx, - bool rd, bool wr, bool trunc) { - assert(self); - assert(ctx); - - if (rd) { - self->rbuf.ok = false; - } - - if (wr) { - if (trunc) { - ab_flash_initialize_zero(self->wbuf.dat); - self->written = true; - } else { - ab_flash_initialize(self->wbuf.dat); - self->written = false; - } - self->wbuf.ok = false; - } - - return lo_box_flash_file_as_lib9p_srv_fio(self); -} - -/* srv_fio ********************************************************************/ - -static uint32_t flash_file_iounit(struct flash_file *self) { - assert(self); - return FLASH_SECTOR_SIZE; -} - -static void flash_file_iofree(struct flash_file *self) { - assert(self); - - if (self->wbuf.ok) - ab_flash_write_sector(self->wbuf.pos, self->wbuf.dat); - - if (self->written) - ab_flash_finalize(self->wbuf.dat); -} - -static void flash_file_pread(struct flash_file *self, struct lib9p_srv_ctx *ctx, - uint32_t byte_count, uint64_t byte_offset, - struct iovec *ret) { - assert(self); - assert(ctx); - assert(ret); - - if (byte_offset > DATA_SIZE) { - lib9p_error(&ctx->basectx, - LIB9P_ERRNO_L_EINVAL, "offset is past the chip size"); - return; - } - - /* Assume that somewhere down the line the iovec we return - * will be passed to DMA. We don't want the DMA engine to hit - * (slow) XIP (for instance, this can cause reads/writes to - * the SSP to get out of sync with eachother), so copy the - * data to a buffer in (fast) RAM first. It's lame that the - * DMA engine can only have a DREQ on one side of the channel. - */ - if (byte_offset == DATA_SIZE) { - *ret = (struct iovec){ - .iov_len = 0, - }; - return; - } - size_t sector_base = LM_ROUND_DOWN(byte_offset, FLASH_SECTOR_SIZE); - if (byte_offset + byte_count > sector_base + FLASH_SECTOR_SIZE) - byte_count = (sector_base + FLASH_SECTOR_SIZE) - byte_offset; - assert(byte_offset + byte_count <= DATA_SIZE); - - if (!self->rbuf.ok || self->rbuf.pos != sector_base) { - self->rbuf.ok = true; - self->rbuf.pos = sector_base; - memcpy(self->rbuf.dat, DATA_START+sector_base, FLASH_SECTOR_SIZE); - } - - *ret = (struct iovec){ - .iov_base = &self->rbuf.dat[byte_offset-sector_base], - .iov_len = byte_count, - }; -} - -/* TODO: Short/corrupt writes are dangerous. This should either (1) - * check a checksum, (2) use uf2 instead of verbatim data, or (3) use - * ihex instead of verbatim data. */ -static uint32_t flash_file_pwrite(struct flash_file *self, struct lib9p_srv_ctx *ctx, - void *buf, - uint32_t byte_count, - uint64_t byte_offset) { - assert(self); - assert(ctx); - - if (byte_offset > DATA_HSIZE) { - lib9p_error(&ctx->basectx, - LIB9P_ERRNO_L_EINVAL, "offset is past half the chip size"); - return 0; - } - if (byte_count == 0) - return 0; - if (byte_offset == DATA_HSIZE) { - lib9p_error(&ctx->basectx, - LIB9P_ERRNO_L_EINVAL, "offset is at half the chip size"); - return 0; - } - - size_t sector_base = LM_ROUND_DOWN(byte_offset, FLASH_SECTOR_SIZE); - if (byte_offset + byte_count > sector_base + FLASH_SECTOR_SIZE) - byte_count = (sector_base + FLASH_SECTOR_SIZE) - byte_offset; - assert(byte_offset + byte_count < DATA_HSIZE); - - if (self->wbuf.ok && self->wbuf.pos != sector_base) - ab_flash_write_sector(self->wbuf.pos, self->wbuf.dat); - if (!self->wbuf.ok || self->wbuf.pos != sector_base) { - self->wbuf.ok = true; - self->wbuf.pos = sector_base; - if (byte_count != FLASH_SECTOR_SIZE) - memcpy(self->wbuf.dat, DATA_START+DATA_HSIZE+sector_base, FLASH_SECTOR_SIZE); - } - memcpy(&self->wbuf.dat[byte_offset-sector_base], buf, byte_count); - - self->written = true; - return byte_count; -} diff --git a/cmd/sbc_harness/fs_harness_flash_bin.h b/cmd/sbc_harness/fs_harness_flash_bin.h deleted file mode 100644 index 36382be..0000000 --- a/cmd/sbc_harness/fs_harness_flash_bin.h +++ /dev/null @@ -1,30 +0,0 @@ -/* sbc_harness/fs_harness_flash_bin.h - 9P access to flash storage - * - * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _SBC_HARNESS_FS_HARNESS_FLASH_BIN_H_ -#define _SBC_HARNESS_FS_HARNESS_FLASH_BIN_H_ - -#include <hardware/flash.h> /* for FLASH_SECTOR_SIZE */ - -#include <lib9p/srv.h> - -struct flash_file { - char *name; - uint64_t pathnum; - - BEGIN_PRIVATE(FS_HARNESS_FLASH_BIN); - bool written; - struct { - bool ok; - size_t pos; - uint8_t dat[FLASH_SECTOR_SIZE]; - } wbuf, rbuf; - END_PRIVATE(FS_HARNESS_FLASH_BIN); -}; -LO_IMPLEMENTATION_H(lib9p_srv_file, struct flash_file, flash_file); -#define lo_box_flash_file_as_lib9p_srv_file(obj) util9p_box(flash_file, obj) - -#endif /* _SBC_HARNESS_FS_HARNESS_FLASH_BIN_H_ */ diff --git a/cmd/sbc_harness/fs_harness_uptime_txt.c b/cmd/sbc_harness/fs_harness_uptime_txt.c deleted file mode 100644 index 1425bf9..0000000 --- a/cmd/sbc_harness/fs_harness_uptime_txt.c +++ /dev/null @@ -1,156 +0,0 @@ -/* sbc_harness/fs_harness_uptime_txt.c - 9P access to harness uptime - * - * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#include <stdio.h> /* for snprintf() */ -#include <stdlib.h> /* for malloc(), free() */ - -#include <libhw/generic/alarmclock.h> -#include <util9p/static.h> - -#include "fs_harness_uptime_txt.h" - -LO_IMPLEMENTATION_C(lib9p_srv_file, struct uptime_file, uptime_file, static); - -struct uptime_fio { - struct uptime_file *parent; - size_t buf_len; - char buf[24]; /* len(str(UINT64_MAX)+"ns\n\0") */ -}; - -LO_IMPLEMENTATION_H(lib9p_srv_fio, struct uptime_fio, uptime_fio); -LO_IMPLEMENTATION_C(lib9p_srv_fio, struct uptime_fio, uptime_fio, static); - -/* srv_file *******************************************************************/ - -static void uptime_file_free(struct uptime_file *self) { - assert(self); -} -static struct lib9p_qid uptime_file_qid(struct uptime_file *self) { - assert(self); - - return (struct lib9p_qid){ - .type = LIB9P_QT_FILE, - .vers = 1, - .path = self->pathnum, - }; -} - -static struct lib9p_stat uptime_file_stat(struct uptime_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - - uint64_t now = LO_CALL(bootclock, get_time_ns); - uint64_t size = 0; - while (now) { - size++; - now /= 10; - } - if (!size) - size++; - size += 3; - - return (struct lib9p_stat){ - .kern_type = 0, - .kern_dev = 0, - .file_qid = uptime_file_qid(self), - .file_mode = 0444, - .file_atime = UTIL9P_ATIME, - .file_mtime = UTIL9P_MTIME, - .file_size = size, - .file_name = lib9p_str(self->name), - .file_owner_uid = lib9p_str("root"), - .file_owner_gid = lib9p_str("root"), - .file_last_modified_uid = lib9p_str("root"), - .file_extension = lib9p_str(NULL), - .file_owner_n_uid = 0, - .file_owner_n_gid = 0, - .file_last_modified_n_uid = 0, - }; -} -static void uptime_file_wstat(struct uptime_file *self, struct lib9p_srv_ctx *ctx, - struct lib9p_stat) { - assert(self); - assert(ctx); - - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem"); -} -static void uptime_file_remove(struct uptime_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem"); -} - -LIB9P_SRV_NOTDIR(struct uptime_file, uptime_file); - -static lo_interface lib9p_srv_fio uptime_file_fopen(struct uptime_file *self, struct lib9p_srv_ctx *ctx, - bool LM_UNUSED(rd), bool LM_UNUSED(wr), bool LM_UNUSED(trunc)) { - assert(self); - assert(ctx); - - struct uptime_fio *ret = malloc(sizeof(struct uptime_fio)); - ret->parent = self; - ret->buf_len = 0; - - return lo_box_uptime_fio_as_lib9p_srv_fio(ret); -} - -/* srv_fio ********************************************************************/ - -static uint32_t uptime_fio_iounit(struct uptime_fio *self) { - assert(self); - return sizeof(self->buf)-1; -} - -static void uptime_fio_iofree(struct uptime_fio *self) { - assert(self); - free(self); -} - -static struct lib9p_qid uptime_fio_qid(struct uptime_fio *self) { - assert(self); - assert(self->parent); - return uptime_file_qid(self->parent); -} - -static void uptime_fio_pread(struct uptime_fio *self, struct lib9p_srv_ctx *ctx, - uint32_t byte_count, uint64_t byte_offset, - struct iovec *ret) { - assert(self); - assert(ctx); - assert(ret); - - if (byte_offset == 0 || self->buf_len == 0) { - uint64_t now = LO_CALL(bootclock, get_time_ns); - self->buf_len = snprintf(self->buf, sizeof(self->buf), "%"PRIu64"ns\n", now); - } - - if (byte_offset > (uint64_t)self->buf_len) { - lib9p_error(&ctx->basectx, - LIB9P_ERRNO_L_EINVAL, "offset is past end-of-file length"); - return; - } - - size_t beg_off = (size_t)byte_offset; - size_t end_off = beg_off + (size_t)byte_count; - if (end_off > self->buf_len) - end_off = self->buf_len; - *ret = (struct iovec){ - .iov_base = &self->buf[beg_off], - .iov_len = end_off-beg_off, - }; -} - -static uint32_t uptime_fio_pwrite(struct uptime_fio *self, struct lib9p_srv_ctx *ctx, - void *LM_UNUSED(buf), - uint32_t LM_UNUSED(byte_count), - uint64_t LM_UNUSED(byte_offset)) { - assert(self); - assert(ctx); - - lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem"); - return 0; -} diff --git a/cmd/sbc_harness/fs_harness_uptime_txt.h b/cmd/sbc_harness/fs_harness_uptime_txt.h deleted file mode 100644 index 7bf2945..0000000 --- a/cmd/sbc_harness/fs_harness_uptime_txt.h +++ /dev/null @@ -1,19 +0,0 @@ -/* sbc_harness/fs_harness_uptime_txt.h - 9P access to harness uptime - * - * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _SBC_HARNESS_FS_HARNESS_UPTIME_TXT_H_ -#define _SBC_HARNESS_FS_HARNESS_UPTIME_TXT_H_ - -#include <lib9p/srv.h> - -struct uptime_file { - char *name; - uint64_t pathnum; -}; -LO_IMPLEMENTATION_H(lib9p_srv_file, struct uptime_file, uptime_file); -#define lo_box_uptime_file_as_lib9p_srv_file(obj) util9p_box(uptime_file, obj) - -#endif /* _SBC_HARNESS_FS_HARNESS_UPTIME_TXT_H_ */ diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c deleted file mode 100644 index 5630e83..0000000 --- a/cmd/sbc_harness/main.c +++ /dev/null @@ -1,253 +0,0 @@ -/* sbc_harness/main.c - Main entry point and event loop for sbc-harness - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -/* libc */ -#include <string.h> /* libc: for strlen() */ - -/* pico-sdk */ -#include <pico/stdio_uart.h> /* pico-sdk:pico_stdio_uart: for stdio_uart_init() */ -#include <hardware/flash.h> /* pico-sdk:hardware_flash: for flash_get_unique_id() */ - -/* our OS */ -#include <libcr/coroutine.h> -#include <libhw/generic/alarmclock.h> /* so we can set `bootclock` */ -#include <libhw/rp2040_hwspi.h> -#include <libhw/rp2040_hwtimer.h> -#include <libhw/w5500.h> - -/* our application libraries */ -#include <libdhcp/client.h> -#include <libusb/usb_common.h> -#include <lib9p/srv.h> -#include <util9p/static.h> - -/* our utility libraries */ -#include <libmisc/hash.h> -#define LOG_NAME MAIN -#include <libmisc/log.h> - -/* local headers */ -#include "usb_keyboard.h" -#include "static.h" -#include "fs_harness_flash_bin.h" -#include "fs_harness_uptime_txt.h" - -/* configuration **************************************************************/ - -#include "config.h" - -#ifndef _CONFIG_9P_MAX_CONNS - #error config.h must define _CONFIG_9P_MAX_CONNS -#endif -#ifndef _CONFIG_9P_MAX_REQS - #error config.h must define _CONFIG_9P_MAX_REQS -#endif - -/* file tree ******************************************************************/ - -enum { PATH_BASE = __COUNTER__ }; -#define PATH_COUNTER __COUNTER__ - PATH_BASE - -#define STATIC_FILE(STRNAME, ...) UTIL9P_STATIC_FILE(PATH_COUNTER, STRNAME, __VA_ARGS__) -#define STATIC_DIR(STRNAME, ...) UTIL9P_STATIC_DIR(PATH_COUNTER, STRNAME, __VA_ARGS__) - -#define API_FILE(STRNAME, SYMNAME, ...) \ - lo_box_##SYMNAME##_file_as_lib9p_srv_file(&((struct SYMNAME##_file){ \ - .name = STRNAME, \ - .pathnum = PATH_COUNTER \ - __VA_OPT__(,) __VA_ARGS__ \ - })) - -struct lib9p_srv_file root = - STATIC_DIR("", - STATIC_DIR("Documentation", - STATIC_FILE("YOUR_RIGHTS_AND_OBLIGATIONS.md", - .data_start = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_md_start, - .data_end = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_md_end), - STATIC_DIR("YOUR_RIGHTS_AND_OBLIGATIONS", - STATIC_FILE("agpl-3.0.txt", - .data_start = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_agpl_3_0_txt_start, - .data_end = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_agpl_3_0_txt_end), - STATIC_FILE("pico-sdk.bsd3.txt", - .data_start = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_pico_sdk_bsd3_txt_start, - .data_end = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_pico_sdk_bsd3_txt_end), - STATIC_FILE("printf.mit.txt", - .data_start = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_printf_mit_txt_start, - .data_end = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_printf_mit_txt_end), - STATIC_FILE("tinyusb.mit.txt", - .data_start = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_tinyusb_mit_txt_start, - .data_end = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_tinyusb_mit_txt_end), - STATIC_FILE("newlib.txt", - .data_start = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_newlib_txt_start, - .data_end = _binary_static_Documentation_YOUR_RIGHTS_AND_OBLIGATIONS_newlib_txt_end), - ), - STATIC_FILE("harness_rom_bin.txt", - .data_start = _binary_static_Documentation_harness_rom_bin_txt_start, - .data_end = _binary_static_Documentation_harness_rom_bin_txt_end), - STATIC_FILE("harness_flash_bin.txt", - .data_start = _binary_static_Documentation_harness_flash_bin_txt_start, - .data_end = _binary_static_Documentation_harness_flash_bin_txt_end), - STATIC_FILE("harness_uptime_txt.txt", - .data_start = _binary_static_Documentation_harness_uptime_txt_txt_start, - .data_end = _binary_static_Documentation_harness_uptime_txt_txt_end), - ), - STATIC_DIR("harness", - STATIC_FILE("rom.bin", - .data_start = (void*)0x00000000, - .data_size = 16*1024), - API_FILE("flash.bin", - flash), - API_FILE("uptime.txt", - uptime), - // TODO: system.log - // TODO: proc.txt - // TODO: cpuinfo.txt - // TODO: ctl - ), - STATIC_DIR("dut", - // TODO: hdmi.nut - // TODO: uart.txt - // TODO: usb-keyboard.txt - ), - ); - -static lo_interface lib9p_srv_file get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), struct lib9p_s LM_UNUSED(treename)) { - return root; -} - -/* Code ***********************************************************************/ - -/* -static COROUTINE hello_world_cr(void *_chan) { - const char *msg = "Hello world!\n"; - usb_keyboard_rpc_t *chan = _chan; - cr_begin(); - - for (size_t i = 0;; i = (i+1) % strlen(msg)) { - int result = usb_keyboard_rpc_send_req(chan, (uint32_t)msg[i]); - if (result < 1) { - errorf("error sending rune U+%d", (uint32_t)msg[i]); - break; - } - } - - cr_end(); -} -*/ - -struct { - struct rp2040_hwspi dev_spi; - struct w5500 dev_w5500; - usb_keyboard_rpc_t keyboard_chan; - uint16_t usb_serial[sizeof(uint64_t)*2]; /* UTF-16 */ - struct lib9p_srv srv; -} globals; - -static COROUTINE dhcp_cr(void *) { - cr_begin(); - - dhcp_client_main(lo_box_w5500_if_as_net_iface(&globals.dev_w5500), "harness"); - - cr_end(); -} - -static COROUTINE read9p_cr(void *) { - cr_begin(); - - lo_interface net_iface iface = lo_box_w5500_if_as_net_iface(&globals.dev_w5500); - lo_interface net_stream_listener listener = LO_CALL(iface, tcp_listen, LIB9P_DEFAULT_PORT_9FS); - - lib9p_srv_accept_and_read_loop(&globals.srv, listener); - - cr_end(); -} - -static COROUTINE write9p_cr(void *) { - cr_begin(); - - lib9p_srv_worker_loop(&globals.srv); - - cr_end(); -} - -const char *const hexdig = "0123456789ABCDEF"; -static_assert(_CONFIG_9P_MAX_REQS <= 16); - -COROUTINE init_cr(void *) { - cr_begin(); - - /* NOR flash chips have a (bog-?)standard "RUID" "Read Unique - * ID" instruction; use our flash chip's unique ID as the - * basis for our serial numbers. */ - uint64_t flash_id64; - static_assert(sizeof(flash_id64) == FLASH_UNIQUE_ID_SIZE_BYTES); - flash_get_unique_id((uint8_t *)&flash_id64); - uint32_t flash_id32 = hash(&flash_id64, sizeof(flash_id64)); - static_assert(sizeof(flash_id32) == sizeof(hash(NULL, 0))); - uint8_t flash_id24[3] = { - (uint8_t)((flash_id32 >> 16) & 0xFF), - (uint8_t)((flash_id32 >> 8) & 0xFF), - (uint8_t)((flash_id32 >> 0) & 0xFF), - }; - - rp2040_hwspi_init(&globals.dev_spi, "W5500", RP2040_HWSPI_0, - SPI_MODE_0, /* the W5500 supports mode 0 or mode 3 */ - 42500000, /* min(w5500, hwspi); w5500=80MHz; hwspi=42.5MHz, see rp2040_hwspi.h for a comment about why this is so low */ - 30, /* W5500 datasheet says min(T_CS = SCSn High Time) = 30ns */ - 0, /* bogus write write data when doing a read */ - 16, /* PIN_MISO */ - 19, /* PIN_MOSI */ - 18, /* PIN_CLK */ - 17, /* PIN_CS */ - 0, 1, 2, 3); /* DMA channels */ - w5500_init(&globals.dev_w5500, "W5500", - lo_box_rp2040_hwspi_as_spi(&globals.dev_spi), - 21, /* PIN_INTR */ - 20, /* PIN_RESET */ - ((struct net_eth_addr){{ - /* vendor ID: "Wiznet" */ - 0x00, 0x08, 0xDC, - /* serial number */ - flash_id24[0], flash_id24[1], flash_id24[2], - }})); - - static_assert(sizeof(flash_id64)*2 == LM_ARRAY_LEN(globals.usb_serial)); - for (size_t i = 0; i < LM_ARRAY_LEN(globals.usb_serial); i++) - globals.usb_serial[i] = hexdig[(flash_id64 >> ((sizeof(flash_id64)*8)-((i+1)*4))) & 0xF]; - usb_common_earlyinit(globals.usb_serial, sizeof(globals.usb_serial)); - usb_keyboard_init(); - usb_common_lateinit(); - - globals.keyboard_chan = (usb_keyboard_rpc_t){0}; - - globals.srv.rootdir = get_root; - - /* set up coroutines **************************************************/ - coroutine_add("usb_common", usb_common_cr, NULL); - coroutine_add("usb_keyboard", usb_keyboard_cr, &globals.keyboard_chan); - //coroutine_add("hello_world", hello_world_cr, &globals.keyboard_chan); - coroutine_add("dhcp", dhcp_cr, NULL); - for (int i = 0; i < _CONFIG_9P_MAX_CONNS; i++) { - char name[] = {'r', 'e', 'a', 'd', '-', hexdig[i], '\0'}; - coroutine_add(name, read9p_cr, NULL); - } - for (int i = 0; i < _CONFIG_9P_MAX_REQS; i++) { - char name[] = {'w', 'r', 'i', 't', 'e', '-', hexdig[i], '\0'}; - coroutine_add(name, write9p_cr, NULL); - } - - cr_exit(); -} - -int main() { - bootclock = rp2040_hwtimer(0); - stdio_uart_init(); - /* char *hdr = "=" * (80-strlen("info : MAIN: ")); */ - infof("==================================================================="); - coroutine_add("init", init_cr, NULL); - coroutine_main(); - assert_notreached("all coroutines exited"); -} diff --git a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS.md b/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS.md deleted file mode 100644 index b3fc12e..0000000 --- a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS.md +++ /dev/null @@ -1,29 +0,0 @@ -<!-- - Documentation/YOUR_RIGHTS_AND_OBLIGATIONS.md - Overview of your - rights and obligations with regard to the SBC-Harness firmware - - Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - SPDX-License-Identifier: AGPL-3.0-or-later ---> - -The firmware running on the SBC-Harness is Free Software -- if you -have access to this file, then you have the freedom to use, study, -share, and improve the firmware; as long as you follow a few -conditions that basically amount to "paying it forward". - -The precise terms of your rights and obligations are given in the -files in the `YOUR_RIGHTS_AND_OBLIGATIONS/` directory. You must obey -each of the files in that directory when distributing -verbatim-or-modified copies of the firmware: - - - `agpl-3.0.txt`: The firmware is as-a-whole licensed to you under - the terms of the GNU Affero General Public License (GNU AGPL) as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. This is the main - document that protects your rights and defines your obligations. - - - other files: The firmware makes use of other code that is under - various other licenses. When taken with the AGPL, they amount to - requiring that you pass along the copyright and license text in - those files when you distribute verbatim-or-modified copies of the - firmware. diff --git a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/agpl-3.0.txt b/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/agpl-3.0.txt deleted file mode 120000 index 8a9b6f3..0000000 --- a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/agpl-3.0.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../../COPYING.txt
\ No newline at end of file diff --git a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/newlib.txt b/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/newlib.txt deleted file mode 120000 index 5c5939c..0000000 --- a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/newlib.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../../3rd-party/COPYING.newlib.txt
\ No newline at end of file diff --git a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/pico-sdk.bsd3.txt b/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/pico-sdk.bsd3.txt deleted file mode 120000 index 52c4374..0000000 --- a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/pico-sdk.bsd3.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../../3rd-party/pico-sdk/LICENSE.TXT
\ No newline at end of file diff --git a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/printf.mit.txt b/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/printf.mit.txt deleted file mode 120000 index 5a6e342..0000000 --- a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/printf.mit.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../../3rd-party/pico-sdk/src/rp2_common/pico_printf/LICENSE
\ No newline at end of file diff --git a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/tinyusb.mit.txt b/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/tinyusb.mit.txt deleted file mode 120000 index 22a67cf..0000000 --- a/cmd/sbc_harness/static/Documentation/YOUR_RIGHTS_AND_OBLIGATIONS/tinyusb.mit.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../../3rd-party/pico-sdk/lib/tinyusb/LICENSE
\ No newline at end of file diff --git a/cmd/sbc_harness/static/Documentation/harness_flash_bin.txt b/cmd/sbc_harness/static/Documentation/harness_flash_bin.txt deleted file mode 100644 index 115f2ee..0000000 --- a/cmd/sbc_harness/static/Documentation/harness_flash_bin.txt +++ /dev/null @@ -1,33 +0,0 @@ -NAME - /harness/flash.bin - -DESCRIPTION - Access to the flash storage chip (where the harness firmware - is stored). - - Any number of readers may read the flash contents. - - Only one writer can have the file open at a time; once the - file is closed, the harness reboots into the new firmware. - Writes to the top half of the chip will fail. - -BUGS - - The size of the chip is configured at compile-time. If the - firmware is loaded onto hardware with a larger flash chip - than it was compiled for, then the upper part of the chip - will not be accessible with this file. If the firmware is - loaded onto hardware with a smaller flash chip than it was - compiled for, then accessing the missing upper part of the - chip will crash. - - - When writing to the flash using this file, only half of the - chip capacity is usable; the top half and bottom half are - mirrors of each-other. This is to avoid the firmware - crashing as its program text is overwritten; the firmware is - executing out of the bottom half, and writing to the top - half; once the file is closed, a minimal in-RAM function - copies the top half to the bottom half and reboots. - -AUTHOR - Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/cmd/sbc_harness/static/Documentation/harness_rom_bin.txt b/cmd/sbc_harness/static/Documentation/harness_rom_bin.txt deleted file mode 100644 index 63fd0a3..0000000 --- a/cmd/sbc_harness/static/Documentation/harness_rom_bin.txt +++ /dev/null @@ -1,41 +0,0 @@ -NAME - /harness/rom.bin - -DESCRIPTION - Read access to the RP2040 CPU's ROM. This contains code that - initializes the chip to load the main firmware from the - external flash chip, provides a failsafe USB-programmable - mode, and provides a few functions that the main firmware can - call to. - -BUGS - This ROM is programmed into the chip at the factory; revising - it means issuing a new revison of the RP2040 CPU. So while - the source code to the ROM is freely available to be used, - studied, and shared; one cannot install modified versions onto - the CPU. - -HISTORY - - RP2040 B0 : chips manufactured before September 2020 or so - - RP2040 B1 : chips manufactured after September 2020 or so - - Released to the public January 2021; chance whether you get - a B0 or a B1 chip. - - RP2040 B2 : released September 2021 - - Printed on the physical CPU is a label that indicates which - revision it is. For example: - - RP2-B2 21/24 - - indicates that it is the "B2" revision (and was manufactured - the 21st week (late May) of 2024). - -SEE ALSO - - /harness/cpuinfo.txt can report which CPU version you have. - - - The source code to each ROM revision is published at - https://github.com/raspberrypi/pico-bootrom-rp2040 - -AUTHOR - Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/cmd/sbc_harness/static/Documentation/harness_uptime_txt.txt b/cmd/sbc_harness/static/Documentation/harness_uptime_txt.txt deleted file mode 100644 index 1ab86f7..0000000 --- a/cmd/sbc_harness/static/Documentation/harness_uptime_txt.txt +++ /dev/null @@ -1,17 +0,0 @@ -NAME - /harness/uptime.txt - -DESCRIPTION - Reading this file gives a text string of the format - `sprintf("%uns\n", uptime_ns)` indicating the harness's uptime - in an integer number of nanoseconds. - -BUGS - Using nanoseconds gives the illusion of more precision than - there actually is; the harness' clock only has microsecond - resolution; the last 3 digits of the returned nanosecond count - will always be 0. - -AUTHOR - Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> - SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/cmd/sbc_harness/tusb_log.c b/cmd/sbc_harness/tusb_log.c deleted file mode 100644 index 4c6b7df..0000000 --- a/cmd/sbc_harness/tusb_log.c +++ /dev/null @@ -1,15 +0,0 @@ -/* sbc_harness/tusb_log.c - Logger for tusb_config.h - * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#define LOG_NAME TINY_USB -#include <libmisc/log.h> - -void _libmisc_tu_mess_failed(const char *expr, - const char *file, unsigned int line, const char *func) { - errorf("%s:%u:%s(): assertion \"%s\" failed", - file, line, func, - expr); -} diff --git a/cmd/sbc_harness/usb_keyboard.c b/cmd/sbc_harness/usb_keyboard.c deleted file mode 100644 index 7dd8a24..0000000 --- a/cmd/sbc_harness/usb_keyboard.c +++ /dev/null @@ -1,117 +0,0 @@ -/* sbc_harness/usb_keyboard.c - Implementation of a USB keyboard device - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#include <tusb.h> - -#include <libusb/tusb_helpers.h> /* for TUD_ENDPOINT_IN */ -#include <libusb/usb_common.h> -#include <libmisc/macro.h> - -#include "usb_keyboard.h" - -/** - * A USB-HID "Report Descriptor" (see USB-HID 1.11 §6.2.2 "Report - * Descriptor") describing a keyboard. - */ -static uint8_t const hid_report_descriptor_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD() }; - -static uint8_t kbd_ifc = 0; - -void usb_keyboard_init() { - if (kbd_ifc) - return; - - kbd_ifc = usb_add_interface(cfgnum_std, TUD_HID_DESC_LEN, (uint8_t[]){ - /* USB-HID input-only descriptor for inclusion in the config descriptor; consisting of 3 parts: - * 1. an interface descriptor (USB 2.0 §9.6.5 "Interface"), - * 2. a class-specific (class=HID) descriptor of type HID (USB-HID 1.11 §6.2.1 "HID Descriptor"), - * 3. an endpoint descriptor for inputs (USB 2.0 §9.6.6 "Endpoint"). - * The TUD_HID_DESCRIPTOR() macro takes care of this for us. */ - TUD_HID_DESCRIPTOR( - 0, /* interface : bInterfaceNumber ; Number of this interface (0-indexed) */ - STRID_KBD_IFC, /* interface : iInterface ; Index of string descriptor describing this interface */ - HID_ITF_PROTOCOL_KEYBOARD, /* interface : bInterfaceProtocol ; see USB-HID 1.11 §4.3 "Protocols" */ - sizeof(hid_report_descriptor_keyboard), /* hid : wDescriptorLength ; Total size of report descriptor */ - TUD_ENDPOINT_IN | 1, /* endpoint : bEndpointAddress ; Direction | endpoint number (arbitrary?) */ - CFG_TUD_HID_EP_BUFSIZE, /* endpoint : wMaxPacketSize ; Maximum packet size this endpoint is capable of sending or receiving */ - 10), /* endpoint : bInterval ; poll interval (in milliseconds?) */ - }); -} - -static uint8_t ascii2keycode[128][2] = { HID_ASCII_TO_KEYCODE }; - -COROUTINE usb_keyboard_cr(void *_chan) { - usb_keyboard_rpc_t *chan = _chan; - cr_begin(); - - uint8_t report_id = 0; - uint8_t modifier = 0; - uint8_t keycodes[6] = {0}; - for (;;) { - while (!tud_hid_n_ready(kbd_ifc)) - cr_yield(); - - if (cr_rpc_can_recv_req(chan)) { - usb_keyboard_rpc_req_t req = cr_rpc_recv_req(chan); - uint32_t rune = req.req; - - modifier = ascii2keycode[rune][0] ? KEYBOARD_MODIFIER_LEFTSHIFT : 0; - keycodes[0] = ascii2keycode[rune][1]; - tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes); - - while (!tud_hid_n_ready(kbd_ifc)) - cr_yield(); - - modifier = 0; - keycodes[0] = 0; - tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes); - - cr_rpc_send_resp(req, 1); - } else { - modifier = 0; - keycodes[0] = 0; - tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes); - } - } - - cr_end(); -} - -/** - * Return a pointer to the HID "Report Descriptor" (see USB-HID 1.11 - * §6.2.2 "Report Descriptor") for the given index. - */ -uint8_t const *tud_hid_descriptor_report_cb(uint8_t index) { - static uint8_t const *reports[] = { - hid_report_descriptor_keyboard, - }; - if (index >= TU_ARRAY_SIZE(reports)) - return NULL; - return reports[index]; -} - -uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) -{ - // TODO not implemented - (void) instance; - (void) report_id; - (void) report_type; - (void) buffer; - (void) reqlen; - - return 0; -} - -// Invoked when received SET_REPORT control request or -// received data on OUT endpoint ( Report ID = 0, Type = 0 ) -void tud_hid_set_report_cb(uint8_t LM_UNUSED(instance), - uint8_t LM_UNUSED(report_id), - hid_report_type_t LM_UNUSED(report_type), - uint8_t const *LM_UNUSED(buffer), - uint16_t LM_UNUSED(bufsize)) -{ - // TODO not implemented -} diff --git a/cmd/sbc_harness/usb_keyboard.h b/cmd/sbc_harness/usb_keyboard.h deleted file mode 100644 index cf8483b..0000000 --- a/cmd/sbc_harness/usb_keyboard.h +++ /dev/null @@ -1,20 +0,0 @@ -/* sbc_harness/usb_keyboard.h - Implementation of a USB keyboard device - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _SBC_HARNESS_USB_KEYBOARD_H_ -#define _SBC_HARNESS_USB_KEYBOARD_H_ - -#include <stdint.h> /* for uint32_t */ - -#include <libcr/coroutine.h> /* for COROUTINE */ -#include <libcr_ipc/rpc.h> /* for CR_RPC_DECLARE */ - -CR_RPC_DECLARE(usb_keyboard_rpc, uint32_t, int); - -void usb_keyboard_init(void); -COROUTINE usb_keyboard_cr(void *arg); - -#endif /* _SBC_HARNESS_USB_KEYBOARD_H_ */ |