1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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"));
}
|