/* flashimg/cpu_main/flash_static.c - Serve static files from flash over 9P * * Copyright (C) 2024-2025 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ #include #include #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")); }