1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/conf/landfall-examples/mips-x1600-msc-block.cfg Tue Feb 27 17:27:25 2024 +0100 1.3 @@ -0,0 +1,44 @@ 1.4 +-- vim:set ft=lua: 1.5 + 1.6 +local L4 = require("L4"); 1.7 + 1.8 +local l = L4.default_loader; 1.9 + 1.10 +local io_buses = 1.11 + { 1.12 + common = l:new_channel(); 1.13 + }; 1.14 + 1.15 +l:start({ 1.16 + caps = { 1.17 + common = io_buses.common:svr(), 1.18 + icu = L4.Env.icu, 1.19 + sigma0 = L4.cast(L4.Proto.Factory, L4.Env.sigma0):create(L4.Proto.Sigma0), 1.20 + }, 1.21 + log = { "IO", "y" }, 1.22 + l4re_dbg = L4.Dbg.Warn, 1.23 + }, 1.24 + "rom/io rom/hw_devices.io rom/mips-x1600-msc-block.io"); 1.25 + 1.26 +local block_server = l:new_channel(); 1.27 + 1.28 +l:startv({ 1.29 + caps = { 1.30 + fsserver = block_server:svr(), 1.31 + jdb = L4.Env.jdb, -- to set the server name 1.32 + icu = L4.Env.icu, 1.33 + vbus = io_buses.common, 1.34 + }, 1.35 + log = { "server", "r" }, 1.36 + }, 1.37 + -- arguments: MSC channel/device, DMA channel, card index, memory pages 1.38 + "rom/msc_block_server", "0", "0", "0", "10"); 1.39 + 1.40 +l:startv({ 1.41 + caps = { 1.42 + fsserver = block_server, 1.43 + }, 1.44 + log = { "client", "g" }, 1.45 + }, 1.46 + -- arguments: partition number 1.47 + "rom/msc_block_client", "1");
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/conf/landfall-examples/mips-x1600-msc-block.io Tue Feb 27 17:27:25 2024 +0100 2.3 @@ -0,0 +1,14 @@ 2.4 +-- vi:ft=lua 2.5 +-- configuration file for io 2.6 + 2.7 +local hw = Io.system_bus() 2.8 + 2.9 +local bus = Io.Vi.System_bus 2.10 +{ 2.11 + CPM = wrap(hw:match("x1600-cpm")); 2.12 + DMA = wrap(hw:match("x1600-dma")); 2.13 + GPIO = wrap(hw:match("x1600-gpio")); 2.14 + MSC = wrap(hw:match("x1600-msc")); 2.15 +} 2.16 + 2.17 +Io.add_vbus("common", bus)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/conf/landfall-examples/mips-x1600-msc-block.list Tue Feb 27 17:27:25 2024 +0100 3.3 @@ -0,0 +1,15 @@ 3.4 + 3.5 +modaddr 0x1100000 3.6 + 3.7 +entry mips-x1600-msc-block 3.8 +bootstrap bootstrap -serial 3.9 +kernel fiasco -serial_esc 3.10 +roottask moe rom/mips-x1600-msc-block.cfg 3.11 +module mips-x1600-msc-block.cfg 3.12 +module mips-x1600-msc-block.io 3.13 +module plat-ingenic-x1600/hw_devices.io 3.14 +module l4re 3.15 +module io 3.16 +module ned 3.17 +module msc_block_client 3.18 +module msc_block_server
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/pkg/landfall-examples/msc_block_client/Makefile Tue Feb 27 17:27:25 2024 +0100 4.3 @@ -0,0 +1,12 @@ 4.4 +PKGDIR ?= . 4.5 +L4DIR ?= $(PKGDIR)/../../.. 4.6 + 4.7 +TARGET = msc_block_client 4.8 + 4.9 +MODE = static 4.10 + 4.11 +SRC_CC = msc_block_client.cc 4.12 + 4.13 +REQUIRES_LIBS = l4re_c-util libmem libfsclient libipc libstdc++ libsystypes 4.14 + 4.15 +include $(L4DIR)/mk/prog.mk
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/pkg/landfall-examples/msc_block_client/msc_block_client.cc Tue Feb 27 17:27:25 2024 +0100 5.3 @@ -0,0 +1,93 @@ 5.4 +/* 5.5 + * Test block server access to memory cards. 5.6 + * 5.7 + * Copyright (C) 2024 Paul Boddie <paul@boddie.org.uk> 5.8 + * 5.9 + * This program is free software; you can redistribute it and/or 5.10 + * modify it under the terms of the GNU General Public License as 5.11 + * published by the Free Software Foundation; either version 2 of 5.12 + * the License, or (at your option) any later version. 5.13 + * 5.14 + * This program is distributed in the hope that it will be useful, 5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5.17 + * GNU General Public License for more details. 5.18 + * 5.19 + * You should have received a copy of the GNU General Public License 5.20 + * along with this program; if not, write to the Free Software 5.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 5.22 + * Boston, MA 02110-1301, USA 5.23 + */ 5.24 + 5.25 +#include <l4/sys/err.h> 5.26 +#include <fsclient/client.h> 5.27 +#include <systypes/fcntl.h> 5.28 + 5.29 +#include <stdint.h> 5.30 +#include <stdio.h> 5.31 + 5.32 + 5.33 + 5.34 +static int show_sector(file_t *device) 5.35 +{ 5.36 + uint8_t sector[512]; 5.37 + 5.38 + printf("Seek...\n"); 5.39 + client_seek(device, 1024, SEEK_SET); 5.40 + 5.41 + printf("Read...\n"); 5.42 + offset_t nread = client_read(device, sector, 512); 5.43 + int row, col; 5.44 + 5.45 + if (!nread) 5.46 + { 5.47 + printf("Could not read sector.\n"); 5.48 + return 1; 5.49 + } 5.50 + 5.51 + for (row = 0; row < 512; row += 16) 5.52 + { 5.53 + printf("%04x:", row); 5.54 + 5.55 + for (col = 0; col < 16; col++) 5.56 + printf(" %02x", sector[row + col]); 5.57 + 5.58 + printf("\n"); 5.59 + } 5.60 + 5.61 + return 0; 5.62 +} 5.63 + 5.64 + 5.65 + 5.66 +int main(int argc, char *argv[]) 5.67 +{ 5.68 + if (argc < 1) 5.69 + { 5.70 + printf("Need a partition number.\n"); 5.71 + return 1; 5.72 + } 5.73 + 5.74 + /* Obtain filename and access parameters. */ 5.75 + 5.76 + char *filename = argv[1]; 5.77 + file_t *file; 5.78 + 5.79 + file = client_open(filename, O_RDONLY); 5.80 + 5.81 + if (!client_opened(file)) 5.82 + { 5.83 + printf("Could not obtain file: %s\n", file != NULL ? l4sys_errtostr(file->error) : "(null)"); 5.84 + return 1; 5.85 + } 5.86 + 5.87 + printf("Opened file: %s\n", filename); 5.88 + 5.89 + show_sector(file); 5.90 + 5.91 + client_close(file); 5.92 + printf("End of test.\n"); 5.93 + return 0; 5.94 +} 5.95 + 5.96 +// vim: tabstop=2 expandtab shiftwidth=2
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/pkg/landfall-examples/msc_block_server/Makefile Tue Feb 27 17:27:25 2024 +0100 6.3 @@ -0,0 +1,16 @@ 6.4 +PKGDIR ?= . 6.5 +L4DIR ?= $(PKGDIR)/../../.. 6.6 + 6.7 +TARGET = msc_block_server 6.8 + 6.9 +MODE = static 6.10 + 6.11 +SRC_CC = \ 6.12 + msc_block_server.cc msc_region_accessor.cc \ 6.13 + msc_region_opener.cc msc_region_operations.cc 6.14 + 6.15 +REQUIRES_LIBS = \ 6.16 + l4re_c-util libmem libfsserver libresource libipc libstdc++ libsystypes \ 6.17 + libio libdrivers-cpm libdrivers-dma libdrivers-msc libdevice-util 6.18 + 6.19 +include $(L4DIR)/mk/prog.mk
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/pkg/landfall-examples/msc_block_server/msc_block_server.cc Tue Feb 27 17:27:25 2024 +0100 7.3 @@ -0,0 +1,264 @@ 7.4 +/* 7.5 + * A dataspace server exposing regions of a MMC/SD card. 7.6 + * 7.7 + * Copyright (C) 2020, 2021, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 7.8 + * 7.9 + * This program is free software; you can redistribute it and/or 7.10 + * modify it under the terms of the GNU General Public License as 7.11 + * published by the Free Software Foundation; either version 2 of 7.12 + * the License, or (at your option) any later version. 7.13 + * 7.14 + * This program is distributed in the hope that it will be useful, 7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.17 + * GNU General Public License for more details. 7.18 + * 7.19 + * You should have received a copy of the GNU General Public License 7.20 + * along with this program; if not, write to the Free Software 7.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 7.22 + * Boston, MA 02110-1301, USA 7.23 + */ 7.24 + 7.25 +#include <l4/devices/cpm-x1600.h> 7.26 +#include <l4/devices/dma.h> 7.27 +#include <l4/devices/dma-x1600.h> 7.28 +#include <l4/devices/memory.h> 7.29 +#include <l4/devices/msc-x1600.h> 7.30 + 7.31 +#include <l4/re/c/util/cap_alloc.h> 7.32 +#include <l4/sys/debugger.h> 7.33 +#include <l4/sys/err.h> 7.34 +#include <l4/sys/factory.h> 7.35 +#include <l4/sys/icu.h> 7.36 +#include <l4/sys/ipc.h> 7.37 +#include <l4/sys/irq.h> 7.38 + 7.39 +#include <ipc/thread.h> 7.40 + 7.41 +#include <stdio.h> 7.42 +#include <stdlib.h> 7.43 + 7.44 +#include <mem/memory_incremental.h> 7.45 +#include <fsserver/page_queue_shared.h> 7.46 +#include <fsserver/pages.h> 7.47 +#include <resource/resource_server.h> 7.48 +#include <systypes/env.h> 7.49 + 7.50 +#include "msc_region_opener.h" 7.51 +#include "msc_region_operations.h" 7.52 + 7.53 + 7.54 + 7.55 +/* Common configuration. */ 7.56 + 7.57 +static l4_cap_idx_t icucap; 7.58 + 7.59 + 7.60 + 7.61 +/* Device and resource discovery. */ 7.62 + 7.63 +static long item_in_range(long start, long end, long index) 7.64 +{ 7.65 + if (start < end) 7.66 + return start + index; 7.67 + else if (start > end) 7.68 + return start - index; 7.69 + else 7.70 + return start; 7.71 +} 7.72 + 7.73 + 7.74 + 7.75 +/* Common functions. */ 7.76 + 7.77 +static int init_irq(int num, l4_cap_idx_t irq, l4_uint32_t start, l4_uint32_t end) 7.78 +{ 7.79 + /* Create interrupt object. */ 7.80 + 7.81 + long err = l4_error(l4_factory_create_irq(l4re_global_env->factory, irq)); 7.82 + 7.83 + if (err) 7.84 + { 7.85 + printf("Could not create IRQ object: %ld\n", err); 7.86 + return 1; 7.87 + } 7.88 + 7.89 + /* Bind interrupt objects to IRQ numbers. */ 7.90 + 7.91 + err = l4_error(l4_icu_bind(icucap, 7.92 + item_in_range(start, end, num), 7.93 + irq)); 7.94 + 7.95 + if (err) 7.96 + { 7.97 + printf("Could not bind IRQ to the ICU: %ld\n", err); 7.98 + return 1; 7.99 + } 7.100 + 7.101 + return 0; 7.102 +} 7.103 + 7.104 + 7.105 + 7.106 +/* Peripheral resources. */ 7.107 + 7.108 +static Cpm_x1600_chip *cpm; 7.109 +static Dma_x1600_chip *dma; 7.110 +static Msc_x1600_chip *msc; 7.111 + 7.112 +/* Obtain an abstraction for the memory card. */ 7.113 + 7.114 +static MscRegionOperations *get_msc_region_operations(int msc_channel_num, 7.115 + int dma_channel_num, 7.116 + int card) 7.117 +{ 7.118 + l4_addr_t cpm_base = 0, cpm_base_end = 0; 7.119 + l4_addr_t dma_base = 0, dma_base_end = 0; 7.120 + l4_addr_t msc_base = 0, msc_base_end = 0; 7.121 + l4_addr_t msc_phys_base = 0, msc_phys_base_end = 0; 7.122 + l4_uint32_t dma_irq_start = 0, dma_irq_end = 0; 7.123 + l4_uint32_t msc_irq_start = 0, msc_irq_end = 0; 7.124 + 7.125 + icucap = l4re_env_get_cap("icu"); 7.126 + 7.127 + /* Obtain resource details describing I/O memory. */ 7.128 + 7.129 + if (get_memory("x1600-cpm", &cpm_base, &cpm_base_end) < 0) 7.130 + return NULL; 7.131 + 7.132 + cpm = new Cpm_x1600_chip(cpm_base); 7.133 + 7.134 + if (get_memory("x1600-dma", &dma_base, &dma_base_end) < 0) 7.135 + return NULL; 7.136 + 7.137 + dma = new Dma_x1600_chip(dma_base, dma_base_end, cpm); 7.138 + 7.139 + if (get_irq("x1600-dma", &dma_irq_start, &dma_irq_end) < 0) 7.140 + return NULL; 7.141 + 7.142 + l4_cap_idx_t dma_irq = l4re_util_cap_alloc(); 7.143 + 7.144 + if (init_irq(0, dma_irq, dma_irq_start, dma_irq_end)) 7.145 + return NULL; 7.146 + 7.147 + dma->enable(); 7.148 + 7.149 + if (get_memory_complete("x1600-msc", &msc_base, &msc_base_end, 7.150 + &msc_phys_base, &msc_phys_base_end) < 0) 7.151 + return NULL; 7.152 + 7.153 + msc = new Msc_x1600_chip(msc_phys_base, msc_base, msc_base_end, cpm); 7.154 + 7.155 + if (get_irq("x1600-msc", &msc_irq_start, &msc_irq_end) < 0) 7.156 + return NULL; 7.157 + 7.158 + l4_cap_idx_t msc_irq = l4re_util_cap_alloc(); 7.159 + 7.160 + if (init_irq(msc_channel_num, msc_irq, msc_irq_start, msc_irq_end)) 7.161 + return NULL; 7.162 + 7.163 + Dma_x1600_channel *dma_channel = dma->get_channel(dma_channel_num, dma_irq); 7.164 + Msc_channel *msc_channel = msc->get_channel(msc_channel_num, msc_irq, dma_channel); 7.165 + 7.166 + msc_channel->enable(); 7.167 + 7.168 + if (card >= msc_channel->num_cards()) 7.169 + return NULL; 7.170 + 7.171 + struct dma_region region; 7.172 + 7.173 + if (get_dma_region(512, 12, ®ion)) 7.174 + return NULL; 7.175 + 7.176 + return new MscRegionOperations(msc_channel, card, region); 7.177 +} 7.178 + 7.179 + 7.180 + 7.181 +/* Default number of pages for files. */ 7.182 + 7.183 +const unsigned int MEMORY_PAGES = 20; 7.184 + 7.185 + 7.186 + 7.187 +/* Server program. */ 7.188 + 7.189 +int main(int argc, char *argv[]) 7.190 +{ 7.191 + l4_debugger_set_object_name(l4re_env()->main_thread, "block_server"); 7.192 + long err; 7.193 + 7.194 + /* Introduce concurrency control. */ 7.195 + 7.196 + err = ipc_thread_init(); 7.197 + 7.198 + if (err) 7.199 + { 7.200 + printf("Initialisation error: %s\n", l4sys_errtostr(err)); 7.201 + return 1; 7.202 + } 7.203 + 7.204 + if (argc < 4) 7.205 + { 7.206 + printf("Need a MSC channel/peripheral number, a DMA channel number, " \ 7.207 + "and a card number.\n\n" \ 7.208 + "A number of memory pages can be indicated for the use of the " \ 7.209 + "server.\n\n" \ 7.210 + "A named capability from the environment can be specified.\n"); 7.211 + return 1; 7.212 + } 7.213 + 7.214 + int msc_channel_num = atoi(argv[1]); 7.215 + int dma_channel_num = atoi(argv[2]); 7.216 + int card = atoi(argv[3]); 7.217 + 7.218 + unsigned int memory_pages = MEMORY_PAGES; 7.219 + 7.220 + if (argc > 4) 7.221 + memory_pages = atoi(argv[4]); 7.222 + 7.223 + const char *server_name = (argc > 5) ? argv[5] : ENV_FILESYSTEM_SERVER_NAME; 7.224 + 7.225 + /* Obtain a DMA space for associating allocated memory with physical 7.226 + addresses. */ 7.227 + 7.228 + l4_cap_idx_t dma_space; 7.229 + 7.230 + err = get_dma_space(&dma_space); 7.231 + 7.232 + if (err) 7.233 + { 7.234 + printf("Could not obtain DMA space: %s\n", l4sys_errtostr(err)); 7.235 + return 1; 7.236 + } 7.237 + 7.238 + MscRegionOperations *ops = get_msc_region_operations(msc_channel_num, 7.239 + dma_channel_num, 7.240 + card); 7.241 + 7.242 + if (ops == NULL) 7.243 + { 7.244 + printf("Could not access memory card peripheral.\n"); 7.245 + return 1; 7.246 + } 7.247 + 7.248 + /* Some memory plus infrastructure. */ 7.249 + 7.250 + MemoryIncremental mem(memory_pages, PAGE_SIZE, dma_space); 7.251 + PageQueueShared queue; 7.252 + Pages pages(&mem, &queue); 7.253 + ResourceRegistry registry(&pages); 7.254 + MscRegionOpener opener(®istry, ops); 7.255 + 7.256 + /* Register a server associating it with the given object. */ 7.257 + 7.258 + ResourceServer server(&opener); 7.259 + server.bind(server_name); 7.260 + 7.261 + printf("Starting server using %d pages...\n", memory_pages); 7.262 + server.start(); 7.263 + 7.264 + return 0; 7.265 +} 7.266 + 7.267 +// vim: tabstop=2 expandtab shiftwidth=2
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/pkg/landfall-examples/msc_block_server/msc_region_accessor.cc Tue Feb 27 17:27:25 2024 +0100 8.3 @@ -0,0 +1,97 @@ 8.4 +/* 8.5 + * A memory card region accessor. 8.6 + * 8.7 + * Copyright (C) 2021, 2024 Paul Boddie <paul@boddie.org.uk> 8.8 + * 8.9 + * This program is free software; you can redistribute it and/or 8.10 + * modify it under the terms of the GNU General Public License as 8.11 + * published by the Free Software Foundation; either version 2 of 8.12 + * the License, or (at your option) any later version. 8.13 + * 8.14 + * This program is distributed in the hope that it will be useful, 8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.17 + * GNU General Public License for more details. 8.18 + * 8.19 + * You should have received a copy of the GNU General Public License 8.20 + * along with this program; if not, write to the Free Software 8.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 8.22 + * Boston, MA 02110-1301, USA 8.23 + */ 8.24 + 8.25 +#include <string.h> 8.26 + 8.27 +#include <algorithm> 8.28 + 8.29 +#include "msc_region_accessor.h" 8.30 + 8.31 + 8.32 + 8.33 +MscRegionAccessor::MscRegionAccessor(MscRegionOperations *ops, 8.34 + uint32_t start_block, uint32_t num_blocks, 8.35 + fileid_t fileid) 8.36 +: Accessor(fileid), _ops(ops) 8.37 +{ 8.38 + // NOTE: Block size assumption employed. 8.39 + 8.40 + _start = start_block * 512; 8.41 + _size = num_blocks * 512; 8.42 +} 8.43 + 8.44 +/* Return the size of the file. */ 8.45 + 8.46 +offset_t MscRegionAccessor::get_size() 8.47 +{ 8.48 + return _size; 8.49 +} 8.50 + 8.51 +/* Update the size of the file. */ 8.52 + 8.53 +void MscRegionAccessor::set_size(offset_t size) 8.54 +{ 8.55 + (void) size; 8.56 +} 8.57 + 8.58 +/* Data transfer helper methods. */ 8.59 + 8.60 +/* Fill the populated portion of a flexpage. */ 8.61 + 8.62 +void MscRegionAccessor::fill_populated(Flexpage *flexpage) 8.63 +{ 8.64 + offset_t filepos = flexpage->base_offset; 8.65 + offset_t populated_size = std::min(flexpage->size, _size - filepos); 8.66 + 8.67 + /* Tag the region with file state. */ 8.68 + 8.69 + flexpage->region->fill(fileid, filepos); 8.70 + 8.71 + /* Fill the region with file content. */ 8.72 + 8.73 + _ops->read(flexpage->base_addr, flexpage->base_addr_physical, 8.74 + _start + filepos, populated_size); 8.75 + 8.76 + /* Pad the flexpage with zero. */ 8.77 + 8.78 + if (populated_size < flexpage->size) 8.79 + memset((void *) (flexpage->base_addr + populated_size), 0, 8.80 + flexpage->size - populated_size); 8.81 +} 8.82 + 8.83 +/* Flush the populated portion of a flexpage. */ 8.84 + 8.85 +void MscRegionAccessor::flush_populated(Flexpage *flexpage) 8.86 +{ 8.87 + offset_t filepos = flexpage->base_offset; 8.88 + offset_t populated_size = std::min(flexpage->size, _size - filepos); 8.89 + 8.90 + /* Remove the file state tag from the region. */ 8.91 + 8.92 + flexpage->region->flush(); 8.93 + 8.94 + /* Flush the file content. */ 8.95 + 8.96 + _ops->write(flexpage->base_addr, flexpage->base_addr_physical, 8.97 + _start + filepos, populated_size); 8.98 +} 8.99 + 8.100 +// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/pkg/landfall-examples/msc_block_server/msc_region_accessor.h Tue Feb 27 17:27:25 2024 +0100 9.3 @@ -0,0 +1,57 @@ 9.4 +/* 9.5 + * A memory card region accessor. 9.6 + * 9.7 + * Copyright (C) 2021, 2024 Paul Boddie <paul@boddie.org.uk> 9.8 + * 9.9 + * This program is free software; you can redistribute it and/or 9.10 + * modify it under the terms of the GNU General Public License as 9.11 + * published by the Free Software Foundation; either version 2 of 9.12 + * the License, or (at your option) any later version. 9.13 + * 9.14 + * This program is distributed in the hope that it will be useful, 9.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.17 + * GNU General Public License for more details. 9.18 + * 9.19 + * You should have received a copy of the GNU General Public License 9.20 + * along with this program; if not, write to the Free Software 9.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 9.22 + * Boston, MA 02110-1301, USA 9.23 + */ 9.24 + 9.25 +#pragma once 9.26 + 9.27 +#include <stdio.h> 9.28 + 9.29 +#include <fsserver/accessor.h> 9.30 + 9.31 +#include "msc_region_operations.h" 9.32 + 9.33 + 9.34 + 9.35 +/* A memory card region accessor, providing flexpages corresponding to the 9.36 + regions within an exposed memory card region or partition. */ 9.37 + 9.38 +class MscRegionAccessor : public Accessor 9.39 +{ 9.40 +protected: 9.41 + MscRegionOperations *_ops; 9.42 + uint32_t _start; 9.43 + offset_t _size; 9.44 + 9.45 + /* Data transfer helper methods. */ 9.46 + 9.47 + virtual void fill_populated(Flexpage *flexpage); 9.48 + 9.49 + virtual void flush_populated(Flexpage *flexpage); 9.50 + 9.51 +public: 9.52 + explicit MscRegionAccessor(MscRegionOperations *ops, uint32_t start_block, 9.53 + uint32_t num_blocks, fileid_t fileid); 9.54 + 9.55 + virtual offset_t get_size(); 9.56 + 9.57 + virtual void set_size(offset_t size); 9.58 +}; 9.59 + 9.60 +// vim: tabstop=4 expandtab shiftwidth=4
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/pkg/landfall-examples/msc_block_server/msc_region_opener.cc Tue Feb 27 17:27:25 2024 +0100 10.3 @@ -0,0 +1,148 @@ 10.4 +/* 10.5 + * An opener for regions of a memory card. 10.6 + * 10.7 + * Copyright (C) 2021, 2022, 2024 Paul Boddie <paul@boddie.org.uk> 10.8 + * 10.9 + * This program is free software; you can redistribute it and/or 10.10 + * modify it under the terms of the GNU General Public License as 10.11 + * published by the Free Software Foundation; either version 2 of 10.12 + * the License, or (at your option) any later version. 10.13 + * 10.14 + * This program is distributed in the hope that it will be useful, 10.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.17 + * GNU General Public License for more details. 10.18 + * 10.19 + * You should have received a copy of the GNU General Public License 10.20 + * along with this program; if not, write to the Free Software 10.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 10.22 + * Boston, MA 02110-1301, USA 10.23 + */ 10.24 + 10.25 +#include <dirent.h> 10.26 +#include <stdio.h> 10.27 +#include <string.h> 10.28 +#include <sys/stat.h> 10.29 +#include <unistd.h> 10.30 + 10.31 +#include <resource/resource_server.h> 10.32 + 10.33 +#include "msc_region_accessor.h" 10.34 +#include "msc_region_opener.h" 10.35 + 10.36 + 10.37 + 10.38 +MscRegionOpener::~MscRegionOpener() 10.39 +{ 10.40 +} 10.41 + 10.42 +bool MscRegionOpener::accessing_directory(flags_t flags, fileid_t fileid) 10.43 +{ 10.44 + (void) flags; (void) fileid; 10.45 + return false; 10.46 +} 10.47 + 10.48 +bool MscRegionOpener::accessing_file(flags_t flags, fileid_t fileid) 10.49 +{ 10.50 + (void) flags; (void) fileid; 10.51 + return true; 10.52 +} 10.53 + 10.54 +/* Test if a directory is empty. */ 10.55 + 10.56 +bool MscRegionOpener::directory_is_empty(fileid_t fileid) 10.57 +{ 10.58 + (void) fileid; 10.59 + return false; 10.60 +} 10.61 + 10.62 +/* Return a file identifier for the given 'path'. */ 10.63 + 10.64 +long MscRegionOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid) 10.65 +{ 10.66 + (void) flags; 10.67 + 10.68 + // Convert the path to an integer for use as the file identifier. 10.69 + 10.70 + if (!(strlen(path) && isdigit(path[0]))) 10.71 + return -L4_ENOENT; 10.72 + 10.73 + *fileid = atoi(path); 10.74 + return L4_EOK; 10.75 +} 10.76 + 10.77 +/* Return a new accessor for 'fileid'. */ 10.78 + 10.79 +long MscRegionOpener::make_accessor(flags_t flags, fileid_t fileid, 10.80 + Accessor **accessor) 10.81 +{ 10.82 + // NOTE: Not testing for create or write flags. 10.83 + 10.84 + (void) flags; 10.85 + 10.86 + // Find the given partition and initialise the accessor with the appropriate 10.87 + // details. 10.88 + 10.89 + uint32_t start_block, num_blocks; 10.90 + 10.91 + if (_ops->get_partition(fileid, &start_block, &num_blocks)) 10.92 + return -L4_ENOENT; 10.93 + 10.94 + *accessor = new MscRegionAccessor(_ops, start_block, num_blocks, fileid); 10.95 + return L4_EOK; 10.96 +} 10.97 + 10.98 +/* Return a directory accessor for 'fileid'. 10.99 + NOTE: Currently unimplemented. */ 10.100 + 10.101 +long MscRegionOpener::make_directory_accessor(flags_t flags, fileid_t fileid, 10.102 + DirectoryAccessor **accessor) 10.103 +{ 10.104 + (void) flags; (void) fileid; (void) accessor; 10.105 + return -L4_EPERM; 10.106 +} 10.107 + 10.108 + 10.109 + 10.110 +/* Make a new directory. */ 10.111 + 10.112 +long MscRegionOpener::make_directory_object(const char *path, sys_mode_t mode) 10.113 +{ 10.114 + (void) path; (void) mode; 10.115 + return -L4_EPERM; 10.116 +} 10.117 + 10.118 +/* Remove a filesystem object. */ 10.119 + 10.120 +long MscRegionOpener::remove_object(fileid_t fileid) 10.121 +{ 10.122 + (void) fileid; 10.123 + return -L4_EPERM; 10.124 +} 10.125 + 10.126 +/* Rename a filesystem object, placing source inside the parent of target. */ 10.127 + 10.128 +long MscRegionOpener::rename_object(const char *source, const char *target) 10.129 +{ 10.130 + (void) source; (void) target; 10.131 + return -L4_EPERM; 10.132 +} 10.133 + 10.134 +/* Populate a memory region with statistics metadata for a filesystem object. 10.135 + NOTE: Currently unimplemented. */ 10.136 + 10.137 +long MscRegionOpener::stat_object(const char *path, void *base, offset_t size) 10.138 +{ 10.139 + (void) path; (void) base; (void) size; 10.140 + return -L4_EPERM; 10.141 +} 10.142 + 10.143 +/* Unlink a filesystem object. */ 10.144 + 10.145 +long MscRegionOpener::unlink_object(fileid_t parent_fileid, fileid_t fileid) 10.146 +{ 10.147 + (void) parent_fileid; (void) fileid; 10.148 + return -L4_EPERM; 10.149 +} 10.150 + 10.151 +// vim: tabstop=4 expandtab shiftwidth=4
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/pkg/landfall-examples/msc_block_server/msc_region_opener.h Tue Feb 27 17:27:25 2024 +0100 11.3 @@ -0,0 +1,79 @@ 11.4 +/* 11.5 + * An opener for regions of a memory card. 11.6 + * 11.7 + * Copyright (C) 2021, 2022, 2024 Paul Boddie <paul@boddie.org.uk> 11.8 + * 11.9 + * This program is free software; you can redistribute it and/or 11.10 + * modify it under the terms of the GNU General Public License as 11.11 + * published by the Free Software Foundation; either version 2 of 11.12 + * the License, or (at your option) any later version. 11.13 + * 11.14 + * This program is distributed in the hope that it will be useful, 11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.17 + * GNU General Public License for more details. 11.18 + * 11.19 + * You should have received a copy of the GNU General Public License 11.20 + * along with this program; if not, write to the Free Software 11.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 11.22 + * Boston, MA 02110-1301, USA 11.23 + */ 11.24 + 11.25 +#pragma once 11.26 + 11.27 +#include <mutex> 11.28 + 11.29 +#include <fsserver/opener_resource.h> 11.30 + 11.31 +#include "msc_region_operations.h" 11.32 + 11.33 + 11.34 + 11.35 +/* Support for providing access to memory card regions. */ 11.36 + 11.37 +class MscRegionOpener : public OpenerResource 11.38 +{ 11.39 +protected: 11.40 + MscRegionOperations *_ops; 11.41 + std::mutex _lock; 11.42 + 11.43 +public: 11.44 + explicit MscRegionOpener(ResourceRegistry *registry, MscRegionOperations *ops) 11.45 + : OpenerResource(registry), _ops(ops) 11.46 + { 11.47 + } 11.48 + 11.49 + virtual ~MscRegionOpener(); 11.50 + 11.51 + /* Convenience methods determining different object types. */ 11.52 + 11.53 + virtual bool accessing_directory(flags_t flags, fileid_t fileid); 11.54 + 11.55 + virtual bool accessing_file(flags_t flags, fileid_t fileid); 11.56 + 11.57 + virtual bool directory_is_empty(fileid_t fileid); 11.58 + 11.59 + /* File opening methods. */ 11.60 + 11.61 + virtual long get_fileid(const char *path, flags_t flags, fileid_t *fileid); 11.62 + 11.63 + virtual long make_accessor(flags_t flags, fileid_t fileid, 11.64 + Accessor **accessor); 11.65 + 11.66 + virtual long make_directory_accessor(flags_t flags, fileid_t fileid, 11.67 + DirectoryAccessor **accessor); 11.68 + 11.69 + /* Filesystem object access and manipulation methods. */ 11.70 + 11.71 + virtual long make_directory_object(const char *path, sys_mode_t mode); 11.72 + 11.73 + virtual long remove_object(fileid_t fileid); 11.74 + 11.75 + virtual long rename_object(const char *source, const char *target); 11.76 + 11.77 + virtual long stat_object(const char *path, void *base, offset_t size); 11.78 + 11.79 + virtual long unlink_object(fileid_t parent_fileid, fileid_t fileid); 11.80 +}; 11.81 + 11.82 +// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/pkg/landfall-examples/msc_block_server/msc_region_operations.cc Tue Feb 27 17:27:25 2024 +0100 12.3 @@ -0,0 +1,106 @@ 12.4 +/* 12.5 + * Access to memory cards. 12.6 + * 12.7 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk> 12.8 + * 12.9 + * This program is free software; you can redistribute it and/or 12.10 + * modify it under the terms of the GNU General Public License as 12.11 + * published by the Free Software Foundation; either version 2 of 12.12 + * the License, or (at your option) any later version. 12.13 + * 12.14 + * This program is distributed in the hope that it will be useful, 12.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.17 + * GNU General Public License for more details. 12.18 + * 12.19 + * You should have received a copy of the GNU General Public License 12.20 + * along with this program; if not, write to the Free Software 12.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 12.22 + * Boston, MA 02110-1301, USA 12.23 + */ 12.24 + 12.25 +#include <l4/devices/msc.h> 12.26 +#include <l4/sys/cache.h> 12.27 + 12.28 +#include "msc_region_operations.h" 12.29 + 12.30 + 12.31 + 12.32 +MscRegionOperations::MscRegionOperations(Msc_channel *msc_channel, uint8_t card, 12.33 + struct dma_region region) 12.34 +: _msc_channel(msc_channel), _card(card), _region(region) 12.35 +{ 12.36 +} 12.37 + 12.38 +long MscRegionOperations::read_partition_table(struct partition_table_entry **entry) 12.39 +{ 12.40 + l4_cache_inv_data(_region.vaddr, _region.vaddr + _region.size); 12.41 + 12.42 + uint32_t transferred = _msc_channel->read(_card, &_region, 0, _region.size); 12.43 + 12.44 + if (!transferred) 12.45 + return -L4_EIO; 12.46 + 12.47 + *entry = get_partition_table((uint8_t *) _region.vaddr); 12.48 + 12.49 + if (*entry == NULL) 12.50 + return -L4_EIO; 12.51 + 12.52 + return L4_EOK; 12.53 +} 12.54 + 12.55 +/* Public operations. */ 12.56 + 12.57 +long MscRegionOperations::get_partition(uint8_t partition, 12.58 + uint32_t *start_block, 12.59 + uint32_t *num_blocks) 12.60 +{ 12.61 + std::lock_guard<std::mutex> guard(_lock); 12.62 + 12.63 + // Use the fileid to select the partition. 12.64 + 12.65 + if (partition >= 4) 12.66 + return -L4_ENOENT; 12.67 + 12.68 + struct partition_table_entry *entry; 12.69 + long err = read_partition_table(&entry); 12.70 + 12.71 + if (err) 12.72 + return err; 12.73 + 12.74 + if (!entry[partition].num_sectors) 12.75 + return -L4_ENOENT; 12.76 + 12.77 + *start_block = entry[partition].lba_first_sector; 12.78 + *num_blocks = entry[partition].num_sectors; 12.79 + 12.80 + return L4_EOK; 12.81 +} 12.82 + 12.83 +void MscRegionOperations::read(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, 12.84 + offset_t filepos, offset_t size) 12.85 +{ 12.86 + std::lock_guard<std::mutex> guard(_lock); 12.87 + 12.88 + struct dma_region region; 12.89 + 12.90 + // NOTE: Truncating the file position and size. 12.91 + 12.92 + region.vaddr = vaddr; 12.93 + region.paddr = paddr; 12.94 + region.size = size; 12.95 + 12.96 + l4_cache_inv_data(vaddr, vaddr + size); 12.97 + 12.98 + _msc_channel->read(_card, ®ion, (uint32_t) filepos, (uint32_t) size); 12.99 +} 12.100 + 12.101 +void MscRegionOperations::write(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, 12.102 + offset_t filepos, offset_t size) 12.103 +{ 12.104 + std::lock_guard<std::mutex> guard(_lock); 12.105 + 12.106 + // NOTE: To be implemented. 12.107 + 12.108 + (void) vaddr; (void) paddr; (void) filepos; (void) size; 12.109 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/pkg/landfall-examples/msc_block_server/msc_region_operations.h Tue Feb 27 17:27:25 2024 +0100 13.3 @@ -0,0 +1,59 @@ 13.4 +/* 13.5 + * Access to memory cards. 13.6 + * 13.7 + * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk> 13.8 + * 13.9 + * This program is free software; you can redistribute it and/or 13.10 + * modify it under the terms of the GNU General Public License as 13.11 + * published by the Free Software Foundation; either version 2 of 13.12 + * the License, or (at your option) any later version. 13.13 + * 13.14 + * This program is distributed in the hope that it will be useful, 13.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.17 + * GNU General Public License for more details. 13.18 + * 13.19 + * You should have received a copy of the GNU General Public License 13.20 + * along with this program; if not, write to the Free Software 13.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 13.22 + * Boston, MA 02110-1301, USA 13.23 + */ 13.24 + 13.25 +#pragma once 13.26 + 13.27 +#include <mutex> 13.28 + 13.29 +#include <l4/devices/boot.h> 13.30 +#include <l4/devices/dma.h> 13.31 +#include <l4/devices/msc-common.h> 13.32 +#include <systypes/base.h> 13.33 + 13.34 + 13.35 + 13.36 +#ifdef __cplusplus 13.37 + 13.38 +class MscRegionOperations 13.39 +{ 13.40 +protected: 13.41 + std::mutex _lock; 13.42 + Msc_channel *_msc_channel; 13.43 + uint8_t _card; 13.44 + struct dma_region _region; 13.45 + 13.46 +public: 13.47 + explicit MscRegionOperations(Msc_channel *msc_channel, uint8_t card, 13.48 + struct dma_region region); 13.49 + 13.50 + long get_partition(uint8_t partition, uint32_t *start_block, 13.51 + uint32_t *num_blocks); 13.52 + 13.53 + long read_partition_table(struct partition_table_entry **entry); 13.54 + 13.55 + void read(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, offset_t pos, 13.56 + offset_t size); 13.57 + 13.58 + void write(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, offset_t pos, 13.59 + offset_t size); 13.60 +}; 13.61 + 13.62 +#endif /* __cplusplus */