diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-07-03 08:00:50 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-07-03 08:00:50 -0600 |
commit | 1d5a211e1ae3645e9c13163b76fea0a3c87f46f1 (patch) | |
tree | 610128434e35b9b6028609d7cb5d67bcd13b3379 /flashimg/cpu_main/flash_static.c | |
parent | 1be02f3e2379b2cd06dbae775504948ff37bf89a (diff) | |
parent | ad2ef1642096665be998e83f9b6c4b7de308b644 (diff) |
Diffstat (limited to 'flashimg/cpu_main/flash_static.c')
-rw-r--r-- | flashimg/cpu_main/flash_static.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/flashimg/cpu_main/flash_static.c b/flashimg/cpu_main/flash_static.c new file mode 100644 index 0000000..4529ab2 --- /dev/null +++ b/flashimg/cpu_main/flash_static.c @@ -0,0 +1,128 @@ +/* flashimg/cpu_main/flash_static.c - Serve static files from flash over 9P + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <hardware/flash.h> + +#include <libmisc/assert.h> + +#include "flashio.h" + +#include "flash_static.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct flash_static_file, flash_static_file); +LO_IMPLEMENTATION_STATIC(lib9p_srv_fio, struct flash_static_file, flash_static_fio); + +/******************************************************************************/ + +#ifdef NDEBUG +#define flash_static_assert(self) ((void)0) +#else +static void flash_static_assert(struct flash_static_file *self) { + assert(self); + assert(self->io); + assert(XIP_BASE <= (uintptr_t)self->data_start); + assert((uintptr_t)self->data_start <= (uintptr_t)self->data_end); + assert((uintptr_t)self->data_end <= XIP_BASE+PICO_FLASH_SIZE_BYTES); +} +#endif + +static inline size_t flash_static_size(struct flash_static_file *file) { + flash_static_assert(file); + + return (size_t)((uintptr_t)file->data_end - (uintptr_t)file->data_start); +} + +/******************************************************************************/ + +void flash_static_file_free(struct flash_static_file *self) { + flash_static_assert(self); +} +struct lib9p_qid flash_static_file_qid(struct flash_static_file *self) { + flash_static_assert(self); + + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE, + .vers = 1, + .path = self->c.pathnum, + }; +} +error flash_static_file_stat(struct flash_static_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat *out) { + flash_static_assert(self); + assert(ctx); + assert(out); + + *out = ((struct lib9p_srv_stat){ + .qid = flash_static_file_qid(self), + .mode = self->c.perm & 0444, + .atime_sec = self->c.atime, + .mtime_sec = self->c.mtime, + .size = (uint64_t)flash_static_size(self), + .name = lib9p_str(self->c.name), + .owner_uid = { .name = lib9p_str(self->c.u_name), .num = self->c.u_num }, + .owner_gid = { .name = lib9p_str(self->c.g_name), .num = self->c.g_num }, + .last_modifier_uid = { .name = lib9p_str(self->c.m_name), .num = self->c.m_num }, + .extension = lib9p_str(NULL), + }); + return ERROR_NULL; +} +error flash_static_file_wstat(struct flash_static_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat) { + flash_static_assert(self); + assert(ctx); + + return error_new(E_POSIX_EROFS, "read-only part of filesystem"); +} +error flash_static_file_remove(struct flash_static_file *self, struct lib9p_srv_ctx *ctx) { + flash_static_assert(self); + assert(ctx); + + return error_new(E_POSIX_EROFS, "read-only part of filesystem"); +} + +LIB9P_SRV_NOTDIR(, struct flash_static_file, flash_static_file); + +lib9p_srv_fio_or_error flash_static_file_fopen(struct flash_static_file *self, struct lib9p_srv_ctx *ctx, bool rd, bool wr, bool trunc) { + flash_static_assert(self); + assert(ctx); + assert(rd); + assert(!wr); + assert(!trunc); + return ERROR_NEW_VAL(lib9p_srv_fio, LO_BOX(lib9p_srv_fio, self)); +} + +/******************************************************************************/ + +static struct lib9p_qid flash_static_fio_ioqid(struct flash_static_file *self) { + return flash_static_file_qid(self); +} +static void flash_static_fio_iofree(struct flash_static_file *self) { + flash_static_assert(self); +} +static uint32_t flash_static_fio_iounit(struct flash_static_file *self) { + flash_static_assert(self); + return 0; +} +static error flash_static_fio_pread(struct flash_static_file *self, struct lib9p_srv_ctx *ctx, lo_interface io_writer dst, uint64_t byte_offset, uint32_t byte_count) { + flash_static_assert(self); + assert(ctx); + + size_t data_size = flash_static_size(self); + if (byte_offset > (uint64_t)data_size) + return error_new(E_POSIX_EINVAL, "offset is past end-of-file length"); + + if (byte_count > data_size - byte_offset) + byte_count = data_size - byte_offset; + + return flashio_pread_to(self->io, dst, ((uintptr_t)self->data_start - XIP_BASE) + byte_offset, byte_count).err; +} +static uint32_t_or_error flash_static_fio_pwrite(struct flash_static_file *self, struct lib9p_srv_ctx *ctx, + const void *LM_UNUSED(buf), + uint32_t LM_UNUSED(byte_count), + uint64_t LM_UNUSED(byte_offset)) { + flash_static_assert(self); + assert(ctx); + + return ERROR_NEW_ERR(uint32_t, error_new(E_POSIX_EROFS, "read-only part of filesystem")); +} |