1.1 --- a/Makefile Thu Apr 01 00:57:43 2021 +0200
1.2 +++ b/Makefile Fri Apr 02 01:27:50 2021 +0200
1.3 @@ -43,21 +43,19 @@
1.4
1.5 COMMON_SRC_CC = memory/memory_utils.cc
1.6
1.7 -PLAIN_SRC_CC_dstest_block_client = tests/dstest_block_client.cc file.cc
1.8 +PLAIN_SRC_CC_dstest_block_client = tests/dstest_block_client.cc client/file.cc
1.9
1.10 -PLAIN_SRC_CC_dstest_host_client = tests/dstest_host_client.cc file.cc
1.11 +PLAIN_SRC_CC_dstest_host_client = tests/dstest_host_client.cc client/file.cc
1.12
1.13 -PLAIN_SRC_CC_dstest_pipe_client = tests/dstest_pipe_client.cc file.cc
1.14 +PLAIN_SRC_CC_dstest_pipe_client = tests/dstest_pipe_client.cc client/file.cc
1.15
1.16 -PLAIN_SRC_CC_dstest_test_client = tests/dstest_test_client.cc file.cc
1.17 +PLAIN_SRC_CC_dstest_test_client = tests/dstest_test_client.cc client/file.cc
1.18
1.19 PLAIN_SRC_CC_common_server = \
1.20 - accessor.cc \
1.21 - ipc.cc \
1.22 - mapping/access_map.cc mapping/flexpage.cc mapping/page_mapper.cc \
1.23 - memory/memory_incremental.cc memory/memory_preallocated.cc \
1.24 - memory/region.cc \
1.25 - pager.cc \
1.26 + generic/accessor.cc generic/pager.cc \
1.27 + mapping/access_map.cc mapping/flexpage.cc mapping/ipc.cc \
1.28 + memory/memory_incremental.cc mapping/page_mapper.cc \
1.29 + memory/memory_preallocated.cc memory/region.cc \
1.30 pages/page_queue.cc pages/page_queue_partitioned.cc \
1.31 pages/page_queue_shared.cc pages/pages.cc \
1.32 resource_server.cc
1.33 @@ -65,7 +63,7 @@
1.34 PLAIN_SRC_CC_common_file_server = \
1.35 files/file_pager.cc files/file_paging.cc \
1.36 files/opener_resource.cc files/opener_context_resource.cc \
1.37 - simple_pager.cc
1.38 + generic/simple_pager.cc
1.39
1.40 PLAIN_SRC_CC_dstest_block_server = \
1.41 $(PLAIN_SRC_CC_common_server) \
1.42 @@ -136,7 +134,9 @@
1.43
1.44 REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes
1.45
1.46 -PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/mapping $(PKGDIR)/memory \
1.47 +PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/client \
1.48 + $(PKGDIR)/files $(PKGDIR)/generic \
1.49 + $(PKGDIR)/mapping $(PKGDIR)/memory \
1.50 $(PKGDIR)/pages $(PKGDIR)/pipes \
1.51 $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
1.52
2.1 --- a/accessor.cc Thu Apr 01 00:57:43 2021 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,73 +0,0 @@
2.4 -#include "accessor.h"
2.5 -
2.6 -#include <string.h>
2.7 -
2.8 -
2.9 -
2.10 -Accessor::Accessor(fileid_t fileid, offset_t size)
2.11 -: _size(size), fileid(fileid)
2.12 -{
2.13 -}
2.14 -
2.15 -/* Return the size of the file. */
2.16 -
2.17 -offset_t Accessor::get_size()
2.18 -{
2.19 - return _size;
2.20 -}
2.21 -
2.22 -/* Update the size of the file. */
2.23 -
2.24 -void Accessor::set_size(offset_t size)
2.25 -{
2.26 - _size = size;
2.27 -}
2.28 -
2.29 -/* Perform any closing operation on the file. */
2.30 -
2.31 -void Accessor::close()
2.32 -{
2.33 -}
2.34 -
2.35 -/* Perform any opening operation on the file. */
2.36 -
2.37 -void Accessor::open()
2.38 -{
2.39 -}
2.40 -
2.41 -/* Data transfer methods. */
2.42 -
2.43 -void Accessor::fill(Flexpage *flexpage)
2.44 -{
2.45 - /* Filling completely beyond the end of file should produce an empty
2.46 - flexpage. This could potentially be a shared read-only flexpage that
2.47 - would be replaced by an independent writable flexpage if ever written. */
2.48 -
2.49 - if (flexpage->base_offset < _size)
2.50 - fill_populated(flexpage);
2.51 - else
2.52 - memset((void *) flexpage->base_addr, 0, flexpage->size);
2.53 -}
2.54 -
2.55 -void Accessor::flush(Flexpage *flexpage)
2.56 -{
2.57 - /* Flushing completely beyond the end of file should discard the
2.58 - flexpage. */
2.59 -
2.60 - if (flexpage->base_offset < _size)
2.61 - flush_populated(flexpage);
2.62 -}
2.63 -
2.64 -/* Data transfer helper methods. */
2.65 -
2.66 -void Accessor::fill_populated(Flexpage *flexpage)
2.67 -{
2.68 - (void) flexpage;
2.69 -}
2.70 -
2.71 -void Accessor::flush_populated(Flexpage *flexpage)
2.72 -{
2.73 - (void) flexpage;
2.74 -}
2.75 -
2.76 -// vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/accessor.h Thu Apr 01 00:57:43 2021 +0200
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,42 +0,0 @@
3.4 -#pragma once
3.5 -
3.6 -#include "flexpage.h"
3.7 -
3.8 -/* A file accessor, providing flexpages corresponding to file regions. */
3.9 -
3.10 -class Accessor
3.11 -{
3.12 -protected:
3.13 - offset_t _size;
3.14 -
3.15 - /* Data transfer helper methods. */
3.16 -
3.17 - virtual void fill_populated(Flexpage *flexpage);
3.18 -
3.19 - virtual void flush_populated(Flexpage *flexpage);
3.20 -
3.21 -public:
3.22 - fileid_t fileid;
3.23 -
3.24 - explicit Accessor(fileid_t fileid, offset_t size=0);
3.25 -
3.26 - virtual ~Accessor()
3.27 - {
3.28 - }
3.29 -
3.30 - virtual offset_t get_size();
3.31 -
3.32 - virtual void set_size(offset_t size);
3.33 -
3.34 - virtual void close();
3.35 -
3.36 - virtual void open();
3.37 -
3.38 - /* Data transfer methods. */
3.39 -
3.40 - virtual void fill(Flexpage *flexpage);
3.41 -
3.42 - virtual void flush(Flexpage *flexpage);
3.43 -};
3.44 -
3.45 -// vim: tabstop=4 expandtab shiftwidth=4
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/client/file.cc Fri Apr 02 01:27:50 2021 +0200
4.3 @@ -0,0 +1,320 @@
4.4 +/*
4.5 + * File access convenience functions.
4.6 + *
4.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
4.8 + *
4.9 + * This program is free software; you can redistribute it and/or
4.10 + * modify it under the terms of the GNU General Public License as
4.11 + * published by the Free Software Foundation; either version 2 of
4.12 + * the License, or (at your option) any later version.
4.13 + *
4.14 + * This program is distributed in the hope that it will be useful,
4.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.17 + * GNU General Public License for more details.
4.18 + *
4.19 + * You should have received a copy of the GNU General Public License
4.20 + * along with this program; if not, write to the Free Software
4.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
4.22 + * Boston, MA 02110-1301, USA
4.23 + */
4.24 +
4.25 +#include <ipc/cap_alloc.h>
4.26 +#include <ipc/mem_ipc.h>
4.27 +
4.28 +#include <string.h>
4.29 +
4.30 +#include "dataspace_client.h"
4.31 +#include "file_client.h"
4.32 +#include "opener_client.h"
4.33 +#include "opener_context_client.h"
4.34 +#include "pipe_client.h"
4.35 +#include "pipe_opener_client.h"
4.36 +#include "mapped_file_client.h"
4.37 +
4.38 +#include "file.h"
4.39 +
4.40 +
4.41 +
4.42 +/* Release resources for the given file. */
4.43 +
4.44 +void file_close(file_t *file)
4.45 +{
4.46 + if (l4_is_valid_cap(file->ref))
4.47 + ipc_cap_free_um(file->ref);
4.48 +
4.49 + if (file->memory != NULL)
4.50 + ipc_detach_dataspace(file->memory);
4.51 +
4.52 + file_init(file);
4.53 +}
4.54 +
4.55 +/* Initialise a file structure for a context obtained from the given server. */
4.56 +
4.57 +long file_context(file_t *file, l4_cap_idx_t server)
4.58 +{
4.59 + client_Opener opener(server);
4.60 + unsigned long size, flags;
4.61 + long err;
4.62 +
4.63 + file_init(file);
4.64 +
4.65 + err = opener.context(&file->ref);
4.66 + if (err)
4.67 + return err;
4.68 +
4.69 + client_Dataspace context_ds(file->ref);
4.70 +
4.71 + err = context_ds.info(&size, &flags);
4.72 + if (err)
4.73 + return err;
4.74 +
4.75 + file->start_pos = 0;
4.76 + file->end_pos = size;
4.77 +
4.78 + return ipc_attach_dataspace(file->ref, size, (void **) &file->memory);
4.79 +}
4.80 +
4.81 +/* Open a file using the given structure and context. */
4.82 +
4.83 +long file_context_open(file_t *file, file_t *context)
4.84 +{
4.85 + client_OpenerContext openercontext(context->ref);
4.86 + file_init(file);
4.87 + return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref);
4.88 +}
4.89 +
4.90 +/* Initialise the given file structure. */
4.91 +
4.92 +void file_init(file_t *file)
4.93 +{
4.94 + file->memory = NULL;
4.95 + file->ref = L4_INVALID_CAP;
4.96 + file->start_pos = 0;
4.97 + file->end_pos = 0;
4.98 + file->data_end = 0;
4.99 +}
4.100 +
4.101 +/* Open a file using the given structure, indicating the filename and
4.102 + filesystem server. This is a convenience function invoking file_context and
4.103 + file_context_open. */
4.104 +
4.105 +long file_open(file_t *file, const char *filename, l4_cap_idx_t server)
4.106 +{
4.107 + file_t context;
4.108 + long err;
4.109 +
4.110 + err = file_context(&context, server);
4.111 + if (err)
4.112 + return err;
4.113 +
4.114 + if (!file_string_set(&context, filename, 0, NULL))
4.115 + return -L4_ENOMEM;
4.116 +
4.117 + err = file_context_open(file, &context);
4.118 + file_close(&context);
4.119 + return err;
4.120 +}
4.121 +
4.122 +
4.123 +
4.124 +/* Map a region of the given file to a memory region. */
4.125 +
4.126 +long file_mmap(file_t *file, offset_t position, offset_t length)
4.127 +{
4.128 + client_MappedFile mapped_file(file->ref);
4.129 + long err = mapped_file.mmap(position, length, &file->start_pos, &file->end_pos, &file->data_end);
4.130 +
4.131 + if (err)
4.132 + return err;
4.133 +
4.134 + return ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory);
4.135 +}
4.136 +
4.137 +/* Resize a file. */
4.138 +
4.139 +long file_resize(file_t *file, offset_t size)
4.140 +{
4.141 + client_File _file(file->ref);
4.142 + offset_t file_size = size;
4.143 + long err = _file.resize(&file_size);
4.144 +
4.145 + if (!err)
4.146 + {
4.147 + /* Determine the extent of the file in this region. */
4.148 +
4.149 + if (file_size > file->end_pos)
4.150 + file->data_end = file_span(file);
4.151 + else
4.152 + file->data_end = file_size - file->start_pos;
4.153 +
4.154 + /* Update the file size locally. */
4.155 +
4.156 + file->size = file_size;
4.157 + }
4.158 +
4.159 + return err;
4.160 +}
4.161 +
4.162 +
4.163 +
4.164 +/* Return the amount of data in the mapped region for the given file. */
4.165 +
4.166 +offset_t file_populated_span(file_t *file)
4.167 +{
4.168 + offset_t size = file_span(file);
4.169 + return (file->data_end < size) ? file->data_end : size;
4.170 +}
4.171 +
4.172 +/* Return the size of the mapped region for the given file. */
4.173 +
4.174 +offset_t file_span(file_t *file)
4.175 +{
4.176 + return file->end_pos - file->start_pos;
4.177 +}
4.178 +
4.179 +
4.180 +
4.181 +/* Get a pointer to any terminated string at the given offset or NULL if the
4.182 + data from offset is not terminated. */
4.183 +
4.184 +char *file_string_get(file_t *file, offset_t offset)
4.185 +{
4.186 + offset_t limit = file_span(file) - offset;
4.187 +
4.188 + if (strnlen(file->memory + offset, limit) < limit)
4.189 + return file->memory + offset;
4.190 + else
4.191 + return NULL;
4.192 +}
4.193 +
4.194 +/* Copy a string to the mapped region at the given offset, returning 1 (true)
4.195 + where all characters were copied, 0 (false) otherwise. The precise number of
4.196 + characters copied, excluding the zero terminator is provided via the written
4.197 + parameter if it is not specified as NULL. */
4.198 +
4.199 +int file_string_set(file_t *file, const char *data, offset_t offset,
4.200 + offset_t *written)
4.201 +{
4.202 + offset_t i, pos, limit = file_span(file);
4.203 +
4.204 + /* Do not attempt to copy data with an invalid offset. */
4.205 +
4.206 + if (offset >= limit)
4.207 + {
4.208 + if (written != NULL)
4.209 + *written = 0;
4.210 + return 0;
4.211 + }
4.212 +
4.213 + /* Copy the data to the given offset, stopping at the end of the region. */
4.214 +
4.215 + for (i = 0, pos = offset; pos < limit; i++, pos++)
4.216 + {
4.217 + file->memory[pos] = data[i];
4.218 +
4.219 + /* Terminator written, can return immediately. */
4.220 +
4.221 + if (!data[i])
4.222 + {
4.223 + if (written != NULL)
4.224 + *written = pos - offset;
4.225 + return 1;
4.226 + }
4.227 + }
4.228 +
4.229 + /* Terminate the incomplete string at the end of the region. */
4.230 +
4.231 + file->memory[limit - 1] = '\0';
4.232 + if (written != NULL)
4.233 + *written = limit - 1 - offset;
4.234 + return 0;
4.235 +}
4.236 +
4.237 +
4.238 +
4.239 +/* Open two pipe endpoints using the given pipe server. */
4.240 +
4.241 +long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server)
4.242 +{
4.243 + client_PipeOpener opener(server);
4.244 +
4.245 + file_init(reader);
4.246 + file_init(writer);
4.247 +
4.248 + long err = opener.pipe(size, &reader->ref, &writer->ref);
4.249 + if (err)
4.250 + return err;
4.251 +
4.252 + err = pipe_next(writer) || pipe_next(reader);
4.253 +
4.254 + if (err)
4.255 + {
4.256 + file_close(reader);
4.257 + file_close(writer);
4.258 + }
4.259 +
4.260 + return err;
4.261 +}
4.262 +
4.263 +/* Access the current region for a pipe endpoint. */
4.264 +
4.265 +long pipe_current(file_t *pipe)
4.266 +{
4.267 + client_Pipe _pipe(pipe->ref);
4.268 + long err = _pipe.current_region(&pipe->data_end, &pipe->size);
4.269 + char *memory = pipe->memory;
4.270 +
4.271 + if (err)
4.272 + return err;
4.273 +
4.274 + pipe->end_pos = pipe->size;
4.275 +
4.276 + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory);
4.277 + if (err)
4.278 + return err;
4.279 +
4.280 + if (memory != NULL)
4.281 + ipc_detach_dataspace(memory);
4.282 +
4.283 + return L4_EOK;
4.284 +}
4.285 +
4.286 +/* Access the next region for a pipe endpoint, updating the eventual size of
4.287 + the current region. */
4.288 +
4.289 +long pipe_next(file_t *pipe)
4.290 +{
4.291 + client_Pipe _pipe(pipe->ref);
4.292 + long err = _pipe.next_region(&pipe->data_end, &pipe->size);
4.293 + char *memory = pipe->memory;
4.294 +
4.295 + if (err)
4.296 + return err;
4.297 +
4.298 + pipe->end_pos = pipe->size;
4.299 +
4.300 + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory);
4.301 + if (err)
4.302 + return err;
4.303 +
4.304 + if (memory != NULL)
4.305 + ipc_detach_dataspace(memory);
4.306 +
4.307 + return L4_EOK;
4.308 +}
4.309 +
4.310 +/* Set the size of the written region. */
4.311 +
4.312 +long pipe_written(file_t *pipe, offset_t size)
4.313 +{
4.314 + if (size <= pipe->size)
4.315 + {
4.316 + pipe->data_end = size;
4.317 + return L4_EOK;
4.318 + }
4.319 + else
4.320 + return -L4_EINVAL;
4.321 +}
4.322 +
4.323 +// vim: tabstop=2 expandtab shiftwidth=2
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/client/file.h Fri Apr 02 01:27:50 2021 +0200
5.3 @@ -0,0 +1,95 @@
5.4 +/*
5.5 + * File access convenience functions and types.
5.6 + *
5.7 + * Copyright (C) 2021 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/types.h>
5.26 +
5.27 +#include <systypes/base.h>
5.28 +
5.29 +
5.30 +
5.31 +EXTERN_C_BEGIN
5.32 +
5.33 +/* File access abstraction. */
5.34 +
5.35 +typedef struct
5.36 +{
5.37 + /* File object reference. */
5.38 +
5.39 + l4_cap_idx_t ref;
5.40 +
5.41 + /* Mapped memory accessing a file region. */
5.42 +
5.43 + char *memory;
5.44 +
5.45 + /* File region parameters. */
5.46 +
5.47 + offset_t start_pos, end_pos; /* start and end positions of region */
5.48 + offset_t data_end; /* amount of data in the region */
5.49 +
5.50 + /* Total size of file. */
5.51 +
5.52 + offset_t size;
5.53 +
5.54 +} file_t;
5.55 +
5.56 +
5.57 +
5.58 +/* File operations. */
5.59 +
5.60 +void file_close(file_t *file);
5.61 +long file_open(file_t *file, const char *filename, l4_cap_idx_t server);
5.62 +
5.63 +/* File lifecycle operations. */
5.64 +
5.65 +long file_context(file_t *file, l4_cap_idx_t server);
5.66 +long file_context_open(file_t *file, file_t *context);
5.67 +void file_init(file_t *file);
5.68 +
5.69 +/* File and region operations. */
5.70 +
5.71 +long file_mmap(file_t *file, offset_t position, offset_t length);
5.72 +long file_resize(file_t *file, offset_t size);
5.73 +
5.74 +/* File and region properties. */
5.75 +
5.76 +offset_t file_populated_span(file_t *file);
5.77 +offset_t file_span(file_t *file);
5.78 +
5.79 +/* Convenience functions. */
5.80 +
5.81 +char *file_string_get(file_t *file, offset_t offset);
5.82 +int file_string_set(file_t *file, const char *data, offset_t offset, offset_t *written);
5.83 +
5.84 +
5.85 +
5.86 +/* Pipe operations. */
5.87 +
5.88 +long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server);
5.89 +
5.90 +/* Pipe region operations. */
5.91 +
5.92 +long pipe_current(file_t *pipe);
5.93 +long pipe_next(file_t *pipe);
5.94 +long pipe_written(file_t *pipe, offset_t size);
5.95 +
5.96 +EXTERN_C_END
5.97 +
5.98 +// vim: tabstop=2 expandtab shiftwidth=2
6.1 --- a/file.cc Thu Apr 01 00:57:43 2021 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,320 +0,0 @@
6.4 -/*
6.5 - * File access convenience functions.
6.6 - *
6.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
6.8 - *
6.9 - * This program is free software; you can redistribute it and/or
6.10 - * modify it under the terms of the GNU General Public License as
6.11 - * published by the Free Software Foundation; either version 2 of
6.12 - * the License, or (at your option) any later version.
6.13 - *
6.14 - * This program is distributed in the hope that it will be useful,
6.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.17 - * GNU General Public License for more details.
6.18 - *
6.19 - * You should have received a copy of the GNU General Public License
6.20 - * along with this program; if not, write to the Free Software
6.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
6.22 - * Boston, MA 02110-1301, USA
6.23 - */
6.24 -
6.25 -#include <ipc/cap_alloc.h>
6.26 -#include <ipc/mem_ipc.h>
6.27 -
6.28 -#include <string.h>
6.29 -
6.30 -#include "dataspace_client.h"
6.31 -#include "file_client.h"
6.32 -#include "opener_client.h"
6.33 -#include "opener_context_client.h"
6.34 -#include "pipe_client.h"
6.35 -#include "pipe_opener_client.h"
6.36 -#include "mapped_file_client.h"
6.37 -
6.38 -#include "file.h"
6.39 -
6.40 -
6.41 -
6.42 -/* Release resources for the given file. */
6.43 -
6.44 -void file_close(file_t *file)
6.45 -{
6.46 - if (l4_is_valid_cap(file->ref))
6.47 - ipc_cap_free_um(file->ref);
6.48 -
6.49 - if (file->memory != NULL)
6.50 - ipc_detach_dataspace(file->memory);
6.51 -
6.52 - file_init(file);
6.53 -}
6.54 -
6.55 -/* Initialise a file structure for a context obtained from the given server. */
6.56 -
6.57 -long file_context(file_t *file, l4_cap_idx_t server)
6.58 -{
6.59 - client_Opener opener(server);
6.60 - unsigned long size, flags;
6.61 - long err;
6.62 -
6.63 - file_init(file);
6.64 -
6.65 - err = opener.context(&file->ref);
6.66 - if (err)
6.67 - return err;
6.68 -
6.69 - client_Dataspace context_ds(file->ref);
6.70 -
6.71 - err = context_ds.info(&size, &flags);
6.72 - if (err)
6.73 - return err;
6.74 -
6.75 - file->start_pos = 0;
6.76 - file->end_pos = size;
6.77 -
6.78 - return ipc_attach_dataspace(file->ref, size, (void **) &file->memory);
6.79 -}
6.80 -
6.81 -/* Open a file using the given structure and context. */
6.82 -
6.83 -long file_context_open(file_t *file, file_t *context)
6.84 -{
6.85 - client_OpenerContext openercontext(context->ref);
6.86 - file_init(file);
6.87 - return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref);
6.88 -}
6.89 -
6.90 -/* Initialise the given file structure. */
6.91 -
6.92 -void file_init(file_t *file)
6.93 -{
6.94 - file->memory = NULL;
6.95 - file->ref = L4_INVALID_CAP;
6.96 - file->start_pos = 0;
6.97 - file->end_pos = 0;
6.98 - file->data_end = 0;
6.99 -}
6.100 -
6.101 -/* Open a file using the given structure, indicating the filename and
6.102 - filesystem server. This is a convenience function invoking file_context and
6.103 - file_context_open. */
6.104 -
6.105 -long file_open(file_t *file, const char *filename, l4_cap_idx_t server)
6.106 -{
6.107 - file_t context;
6.108 - long err;
6.109 -
6.110 - err = file_context(&context, server);
6.111 - if (err)
6.112 - return err;
6.113 -
6.114 - if (!file_string_set(&context, filename, 0, NULL))
6.115 - return -L4_ENOMEM;
6.116 -
6.117 - err = file_context_open(file, &context);
6.118 - file_close(&context);
6.119 - return err;
6.120 -}
6.121 -
6.122 -
6.123 -
6.124 -/* Map a region of the given file to a memory region. */
6.125 -
6.126 -long file_mmap(file_t *file, offset_t position, offset_t length)
6.127 -{
6.128 - client_MappedFile mapped_file(file->ref);
6.129 - long err = mapped_file.mmap(position, length, &file->start_pos, &file->end_pos, &file->data_end);
6.130 -
6.131 - if (err)
6.132 - return err;
6.133 -
6.134 - return ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory);
6.135 -}
6.136 -
6.137 -/* Resize a file. */
6.138 -
6.139 -long file_resize(file_t *file, offset_t size)
6.140 -{
6.141 - client_File _file(file->ref);
6.142 - offset_t file_size = size;
6.143 - long err = _file.resize(&file_size);
6.144 -
6.145 - if (!err)
6.146 - {
6.147 - /* Determine the extent of the file in this region. */
6.148 -
6.149 - if (file_size > file->end_pos)
6.150 - file->data_end = file_span(file);
6.151 - else
6.152 - file->data_end = file_size - file->start_pos;
6.153 -
6.154 - /* Update the file size locally. */
6.155 -
6.156 - file->size = file_size;
6.157 - }
6.158 -
6.159 - return err;
6.160 -}
6.161 -
6.162 -
6.163 -
6.164 -/* Return the amount of data in the mapped region for the given file. */
6.165 -
6.166 -offset_t file_populated_span(file_t *file)
6.167 -{
6.168 - offset_t size = file_span(file);
6.169 - return (file->data_end < size) ? file->data_end : size;
6.170 -}
6.171 -
6.172 -/* Return the size of the mapped region for the given file. */
6.173 -
6.174 -offset_t file_span(file_t *file)
6.175 -{
6.176 - return file->end_pos - file->start_pos;
6.177 -}
6.178 -
6.179 -
6.180 -
6.181 -/* Get a pointer to any terminated string at the given offset or NULL if the
6.182 - data from offset is not terminated. */
6.183 -
6.184 -char *file_string_get(file_t *file, offset_t offset)
6.185 -{
6.186 - offset_t limit = file_span(file) - offset;
6.187 -
6.188 - if (strnlen(file->memory + offset, limit) < limit)
6.189 - return file->memory + offset;
6.190 - else
6.191 - return NULL;
6.192 -}
6.193 -
6.194 -/* Copy a string to the mapped region at the given offset, returning 1 (true)
6.195 - where all characters were copied, 0 (false) otherwise. The precise number of
6.196 - characters copied, excluding the zero terminator is provided via the written
6.197 - parameter if it is not specified as NULL. */
6.198 -
6.199 -int file_string_set(file_t *file, const char *data, offset_t offset,
6.200 - offset_t *written)
6.201 -{
6.202 - offset_t i, pos, limit = file_span(file);
6.203 -
6.204 - /* Do not attempt to copy data with an invalid offset. */
6.205 -
6.206 - if (offset >= limit)
6.207 - {
6.208 - if (written != NULL)
6.209 - *written = 0;
6.210 - return 0;
6.211 - }
6.212 -
6.213 - /* Copy the data to the given offset, stopping at the end of the region. */
6.214 -
6.215 - for (i = 0, pos = offset; pos < limit; i++, pos++)
6.216 - {
6.217 - file->memory[pos] = data[i];
6.218 -
6.219 - /* Terminator written, can return immediately. */
6.220 -
6.221 - if (!data[i])
6.222 - {
6.223 - if (written != NULL)
6.224 - *written = pos - offset;
6.225 - return 1;
6.226 - }
6.227 - }
6.228 -
6.229 - /* Terminate the incomplete string at the end of the region. */
6.230 -
6.231 - file->memory[limit - 1] = '\0';
6.232 - if (written != NULL)
6.233 - *written = limit - 1 - offset;
6.234 - return 0;
6.235 -}
6.236 -
6.237 -
6.238 -
6.239 -/* Open two pipe endpoints using the given pipe server. */
6.240 -
6.241 -long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server)
6.242 -{
6.243 - client_PipeOpener opener(server);
6.244 -
6.245 - file_init(reader);
6.246 - file_init(writer);
6.247 -
6.248 - long err = opener.pipe(size, &reader->ref, &writer->ref);
6.249 - if (err)
6.250 - return err;
6.251 -
6.252 - err = pipe_next(writer) || pipe_next(reader);
6.253 -
6.254 - if (err)
6.255 - {
6.256 - file_close(reader);
6.257 - file_close(writer);
6.258 - }
6.259 -
6.260 - return err;
6.261 -}
6.262 -
6.263 -/* Access the current region for a pipe endpoint. */
6.264 -
6.265 -long pipe_current(file_t *pipe)
6.266 -{
6.267 - client_Pipe _pipe(pipe->ref);
6.268 - long err = _pipe.current_region(&pipe->data_end, &pipe->size);
6.269 - char *memory = pipe->memory;
6.270 -
6.271 - if (err)
6.272 - return err;
6.273 -
6.274 - pipe->end_pos = pipe->size;
6.275 -
6.276 - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory);
6.277 - if (err)
6.278 - return err;
6.279 -
6.280 - if (memory != NULL)
6.281 - ipc_detach_dataspace(memory);
6.282 -
6.283 - return L4_EOK;
6.284 -}
6.285 -
6.286 -/* Access the next region for a pipe endpoint, updating the eventual size of
6.287 - the current region. */
6.288 -
6.289 -long pipe_next(file_t *pipe)
6.290 -{
6.291 - client_Pipe _pipe(pipe->ref);
6.292 - long err = _pipe.next_region(&pipe->data_end, &pipe->size);
6.293 - char *memory = pipe->memory;
6.294 -
6.295 - if (err)
6.296 - return err;
6.297 -
6.298 - pipe->end_pos = pipe->size;
6.299 -
6.300 - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory);
6.301 - if (err)
6.302 - return err;
6.303 -
6.304 - if (memory != NULL)
6.305 - ipc_detach_dataspace(memory);
6.306 -
6.307 - return L4_EOK;
6.308 -}
6.309 -
6.310 -/* Set the size of the written region. */
6.311 -
6.312 -long pipe_written(file_t *pipe, offset_t size)
6.313 -{
6.314 - if (size <= pipe->size)
6.315 - {
6.316 - pipe->data_end = size;
6.317 - return L4_EOK;
6.318 - }
6.319 - else
6.320 - return -L4_EINVAL;
6.321 -}
6.322 -
6.323 -// vim: tabstop=2 expandtab shiftwidth=2
7.1 --- a/file.h Thu Apr 01 00:57:43 2021 +0200
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,95 +0,0 @@
7.4 -/*
7.5 - * File access convenience functions and types.
7.6 - *
7.7 - * Copyright (C) 2021 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/sys/types.h>
7.26 -
7.27 -#include <systypes/base.h>
7.28 -
7.29 -
7.30 -
7.31 -EXTERN_C_BEGIN
7.32 -
7.33 -/* File access abstraction. */
7.34 -
7.35 -typedef struct
7.36 -{
7.37 - /* File object reference. */
7.38 -
7.39 - l4_cap_idx_t ref;
7.40 -
7.41 - /* Mapped memory accessing a file region. */
7.42 -
7.43 - char *memory;
7.44 -
7.45 - /* File region parameters. */
7.46 -
7.47 - offset_t start_pos, end_pos; /* start and end positions of region */
7.48 - offset_t data_end; /* amount of data in the region */
7.49 -
7.50 - /* Total size of file. */
7.51 -
7.52 - offset_t size;
7.53 -
7.54 -} file_t;
7.55 -
7.56 -
7.57 -
7.58 -/* File operations. */
7.59 -
7.60 -void file_close(file_t *file);
7.61 -long file_open(file_t *file, const char *filename, l4_cap_idx_t server);
7.62 -
7.63 -/* File lifecycle operations. */
7.64 -
7.65 -long file_context(file_t *file, l4_cap_idx_t server);
7.66 -long file_context_open(file_t *file, file_t *context);
7.67 -void file_init(file_t *file);
7.68 -
7.69 -/* File and region operations. */
7.70 -
7.71 -long file_mmap(file_t *file, offset_t position, offset_t length);
7.72 -long file_resize(file_t *file, offset_t size);
7.73 -
7.74 -/* File and region properties. */
7.75 -
7.76 -offset_t file_populated_span(file_t *file);
7.77 -offset_t file_span(file_t *file);
7.78 -
7.79 -/* Convenience functions. */
7.80 -
7.81 -char *file_string_get(file_t *file, offset_t offset);
7.82 -int file_string_set(file_t *file, const char *data, offset_t offset, offset_t *written);
7.83 -
7.84 -
7.85 -
7.86 -/* Pipe operations. */
7.87 -
7.88 -long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server);
7.89 -
7.90 -/* Pipe region operations. */
7.91 -
7.92 -long pipe_current(file_t *pipe);
7.93 -long pipe_next(file_t *pipe);
7.94 -long pipe_written(file_t *pipe, offset_t size);
7.95 -
7.96 -EXTERN_C_END
7.97 -
7.98 -// vim: tabstop=2 expandtab shiftwidth=2
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/generic/accessor.cc Fri Apr 02 01:27:50 2021 +0200
8.3 @@ -0,0 +1,73 @@
8.4 +#include "accessor.h"
8.5 +
8.6 +#include <string.h>
8.7 +
8.8 +
8.9 +
8.10 +Accessor::Accessor(fileid_t fileid, offset_t size)
8.11 +: _size(size), fileid(fileid)
8.12 +{
8.13 +}
8.14 +
8.15 +/* Return the size of the file. */
8.16 +
8.17 +offset_t Accessor::get_size()
8.18 +{
8.19 + return _size;
8.20 +}
8.21 +
8.22 +/* Update the size of the file. */
8.23 +
8.24 +void Accessor::set_size(offset_t size)
8.25 +{
8.26 + _size = size;
8.27 +}
8.28 +
8.29 +/* Perform any closing operation on the file. */
8.30 +
8.31 +void Accessor::close()
8.32 +{
8.33 +}
8.34 +
8.35 +/* Perform any opening operation on the file. */
8.36 +
8.37 +void Accessor::open()
8.38 +{
8.39 +}
8.40 +
8.41 +/* Data transfer methods. */
8.42 +
8.43 +void Accessor::fill(Flexpage *flexpage)
8.44 +{
8.45 + /* Filling completely beyond the end of file should produce an empty
8.46 + flexpage. This could potentially be a shared read-only flexpage that
8.47 + would be replaced by an independent writable flexpage if ever written. */
8.48 +
8.49 + if (flexpage->base_offset < _size)
8.50 + fill_populated(flexpage);
8.51 + else
8.52 + memset((void *) flexpage->base_addr, 0, flexpage->size);
8.53 +}
8.54 +
8.55 +void Accessor::flush(Flexpage *flexpage)
8.56 +{
8.57 + /* Flushing completely beyond the end of file should discard the
8.58 + flexpage. */
8.59 +
8.60 + if (flexpage->base_offset < _size)
8.61 + flush_populated(flexpage);
8.62 +}
8.63 +
8.64 +/* Data transfer helper methods. */
8.65 +
8.66 +void Accessor::fill_populated(Flexpage *flexpage)
8.67 +{
8.68 + (void) flexpage;
8.69 +}
8.70 +
8.71 +void Accessor::flush_populated(Flexpage *flexpage)
8.72 +{
8.73 + (void) flexpage;
8.74 +}
8.75 +
8.76 +// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/generic/accessor.h Fri Apr 02 01:27:50 2021 +0200
9.3 @@ -0,0 +1,42 @@
9.4 +#pragma once
9.5 +
9.6 +#include "flexpage.h"
9.7 +
9.8 +/* A file accessor, providing flexpages corresponding to file regions. */
9.9 +
9.10 +class Accessor
9.11 +{
9.12 +protected:
9.13 + offset_t _size;
9.14 +
9.15 + /* Data transfer helper methods. */
9.16 +
9.17 + virtual void fill_populated(Flexpage *flexpage);
9.18 +
9.19 + virtual void flush_populated(Flexpage *flexpage);
9.20 +
9.21 +public:
9.22 + fileid_t fileid;
9.23 +
9.24 + explicit Accessor(fileid_t fileid, offset_t size=0);
9.25 +
9.26 + virtual ~Accessor()
9.27 + {
9.28 + }
9.29 +
9.30 + virtual offset_t get_size();
9.31 +
9.32 + virtual void set_size(offset_t size);
9.33 +
9.34 + virtual void close();
9.35 +
9.36 + virtual void open();
9.37 +
9.38 + /* Data transfer methods. */
9.39 +
9.40 + virtual void fill(Flexpage *flexpage);
9.41 +
9.42 + virtual void flush(Flexpage *flexpage);
9.43 +};
9.44 +
9.45 +// vim: tabstop=4 expandtab shiftwidth=4
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/generic/pager.cc Fri Apr 02 01:27:50 2021 +0200
10.3 @@ -0,0 +1,91 @@
10.4 +#include "dataspace_server.h"
10.5 +#include "ipc.h"
10.6 +#include "pager.h"
10.7 +
10.8 +
10.9 +
10.10 +Pager::Pager(PageMapper *mapper, flags_t flags)
10.11 +: _start(0), _size(0), _mapper(mapper), _flags(flags)
10.12 +{
10.13 + /* Some pagers may not be initialised with a mapper. */
10.14 +
10.15 + if (_mapper != NULL)
10.16 + _mapper->attach();
10.17 +}
10.18 +
10.19 +/* Close the pager. */
10.20 +
10.21 +void Pager::close()
10.22 +{
10.23 + if (_mapper != NULL)
10.24 + _mapper->detach();
10.25 +}
10.26 +
10.27 +/* Flush data to the file. */
10.28 +
10.29 +long Pager::flush(offset_t populated_size, offset_t *size)
10.30 +{
10.31 + _mapper->flush_all(_start, populated_size);
10.32 +
10.33 + *size = _mapper->get_data_size();
10.34 + return L4_EOK;
10.35 +}
10.36 +
10.37 +/* Resize the underlying file. */
10.38 +
10.39 +long Pager::resize(offset_t *size)
10.40 +{
10.41 + _mapper->set_data_size(*size);
10.42 +
10.43 + *size = _mapper->get_data_size();
10.44 + return L4_EOK;
10.45 +}
10.46 +
10.47 +/* Expose a region of the file. */
10.48 +
10.49 +long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end)
10.50 +{
10.51 + _start = trunc(position, PAGE_SIZE);
10.52 + _size = round(position + length, PAGE_SIZE) - _start;
10.53 +
10.54 + *start_pos = _start;
10.55 + *end_pos = _start + _size;
10.56 + *data_end = 0;
10.57 +
10.58 + return L4_EOK;
10.59 +}
10.60 +
10.61 +/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot'
10.62 + (flexpage offset). */
10.63 +
10.64 +long Pager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
10.65 +{
10.66 + offset_t file_offset = _start + offset;
10.67 + offset_t max_offset = _start + _size;
10.68 + Flexpage *flexpage = _mapper->get(file_offset, flags);
10.69 +
10.70 + /* Issue the flexpage via the IPC system. */
10.71 +
10.72 + long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, region);
10.73 +
10.74 + if (!err)
10.75 + err = complete_Dataspace_map(*region);
10.76 +
10.77 + /* After the flexpage is issued, it is queued for future reuse. */
10.78 +
10.79 + _mapper->queue(flexpage);
10.80 +
10.81 + if (err)
10.82 + return err;
10.83 +
10.84 + return IPC_MESSAGE_SENT;
10.85 +}
10.86 +
10.87 +/* Return the total size of the data. */
10.88 +
10.89 +offset_t Pager::get_data_size()
10.90 +{
10.91 + return _mapper->get_data_size();
10.92 +}
10.93 +
10.94 +// vim: tabstop=4 expandtab shiftwidth=4
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/generic/pager.h Fri Apr 02 01:27:50 2021 +0200
11.3 @@ -0,0 +1,43 @@
11.4 +#pragma once
11.5 +
11.6 +#include <systypes/base.h>
11.7 +
11.8 +#include "page_mapper.h"
11.9 +#include "resource.h"
11.10 +
11.11 +
11.12 +
11.13 +/* A pager exposing a dataspace. */
11.14 +
11.15 +class Pager : public Resource
11.16 +{
11.17 +protected:
11.18 + offset_t _start, _size;
11.19 + PageMapper *_mapper;
11.20 + flags_t _flags;
11.21 +
11.22 +public:
11.23 + explicit Pager(PageMapper *mapper, flags_t flags);
11.24 +
11.25 + virtual void close();
11.26 +
11.27 + /* Paging methods. */
11.28 +
11.29 + virtual long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
11.30 +
11.31 + /* Limit methods. */
11.32 +
11.33 + offset_t get_data_size();
11.34 +
11.35 + /* File methods. */
11.36 +
11.37 + virtual long flush(offset_t populated_size, offset_t *size);
11.38 +
11.39 + virtual long resize(offset_t *size);
11.40 +
11.41 + /* Mapped file methods. */
11.42 +
11.43 + virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end);
11.44 +};
11.45 +
11.46 +// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/generic/resource.h Fri Apr 02 01:27:50 2021 +0200
12.3 @@ -0,0 +1,56 @@
12.4 +/*
12.5 + * Common resource classes and functions.
12.6 + *
12.7 + * Copyright (C) 2018, 2019, 2020 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 +#pragma once
12.26 +
12.27 +#include <ipc/server.h>
12.28 +
12.29 +
12.30 +
12.31 +/* A generic class for an object potentially needing to be closed after use. */
12.32 +
12.33 +class Resource
12.34 +{
12.35 +public:
12.36 + virtual ~Resource()
12.37 + {
12.38 + }
12.39 +
12.40 + /* Server details. */
12.41 +
12.42 + virtual int expected_items() = 0;
12.43 +
12.44 + virtual ipc_server_handler_type handler() = 0;
12.45 +
12.46 + virtual void *interface() = 0;
12.47 +
12.48 + /* Deallocation of resources. */
12.49 +
12.50 + virtual void close()
12.51 + {
12.52 + }
12.53 +
12.54 + /* Activation. */
12.55 +
12.56 + virtual void activate()
12.57 + {
12.58 + }
12.59 +};
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/generic/simple_pager.cc Fri Apr 02 01:27:50 2021 +0200
13.3 @@ -0,0 +1,62 @@
13.4 +#include <l4/re/c/dataspace.h>
13.5 +
13.6 +#include "dataspace_server.h"
13.7 +#include "memory_incremental.h"
13.8 +#include "ipc.h"
13.9 +#include "simple_pager.h"
13.10 +
13.11 +
13.12 +
13.13 +SimplePager::SimplePager(Memory *memory)
13.14 +{
13.15 + if (memory == NULL)
13.16 + _memory = new MemoryIncremental();
13.17 + else
13.18 + _memory = memory;
13.19 +
13.20 + _region = _memory->region();
13.21 +}
13.22 +
13.23 +void SimplePager::close()
13.24 +{
13.25 + if (_region != NULL)
13.26 + {
13.27 + _memory->release(_region);
13.28 + _region = NULL;
13.29 + }
13.30 +}
13.31 +
13.32 +/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot'
13.33 + (flexpage offset). */
13.34 +
13.35 +long SimplePager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
13.36 +{
13.37 + Flexpage flexpage(_region);
13.38 +
13.39 + flexpage.reset(offset);
13.40 + flexpage.upgrade(flags);
13.41 +
13.42 + /* Send the flexpage explicitly. */
13.43 +
13.44 + long err = ipc_prepare_flexpage(&flexpage, offset, _region->size(), hot_spot, region);
13.45 +
13.46 + if (err)
13.47 + return err;
13.48 +
13.49 + err = complete_Dataspace_map(*region);
13.50 +
13.51 + if (err)
13.52 + return err;
13.53 +
13.54 + return IPC_MESSAGE_SENT;
13.55 +}
13.56 +
13.57 +long SimplePager::info(offset_t *size, flags_t *flags)
13.58 +{
13.59 + *size = _region->size();
13.60 + *flags = L4_FPAGE_RW;
13.61 +
13.62 + return L4_EOK;
13.63 +}
13.64 +
13.65 +// vim: tabstop=4 expandtab shiftwidth=4
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/generic/simple_pager.h Fri Apr 02 01:27:50 2021 +0200
14.3 @@ -0,0 +1,30 @@
14.4 +#pragma once
14.5 +
14.6 +#include "dataspace_interface.h"
14.7 +#include "flexpage.h"
14.8 +#include "memory.h"
14.9 +#include "resource.h"
14.10 +
14.11 +
14.12 +
14.13 +/* A simple pager exposing a single memory region as a dataspace. */
14.14 +
14.15 +class SimplePager : public Dataspace, public Resource
14.16 +{
14.17 +protected:
14.18 + Memory *_memory;
14.19 + Region *_region;
14.20 +
14.21 +public:
14.22 + explicit SimplePager(Memory *memory=NULL);
14.23 +
14.24 + void close();
14.25 +
14.26 + /* Paging methods. */
14.27 +
14.28 + long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
14.29 +
14.30 + long info(offset_t *size, flags_t *flags);
14.31 +};
14.32 +
14.33 +// vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/generic/types.h Fri Apr 02 01:27:50 2021 +0200
15.3 @@ -0,0 +1,9 @@
15.4 +#pragma once
15.5 +
15.6 +/* File identification. */
15.7 +
15.8 +typedef unsigned long fileid_t;
15.9 +
15.10 +#define FILEID_INVALID (~0UL)
15.11 +
15.12 +// vim: tabstop=4 expandtab shiftwidth=4
16.1 --- a/ipc.cc Thu Apr 01 00:57:43 2021 +0200
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,46 +0,0 @@
16.4 -#include <l4/re/c/dataspace.h>
16.5 -#include <l4/re/consts.h>
16.6 -#include <l4/sys/task.h>
16.7 -
16.8 -#include "ipc.h"
16.9 -#include "send_flexpage.h"
16.10 -
16.11 -
16.12 -
16.13 -/* Make an L4 representation of the given flexpage. */
16.14 -
16.15 -static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage)
16.16 -{
16.17 - return l4_fpage(send_flexpage->base_addr, send_flexpage->order,
16.18 - (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO);
16.19 -}
16.20 -
16.21 -/* Make a representation of a flexpage for the IPC system. */
16.22 -
16.23 -long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset,
16.24 - unsigned long max_offset, l4_addr_t hot_spot,
16.25 - l4_snd_fpage_t *region)
16.26 -{
16.27 - SendFlexpage send_flexpage = flexpage->to_send(offset, hot_spot, max_offset);
16.28 -
16.29 - /* NOTE: Consider l4_fpage_invalid() as the fpage here. */
16.30 -
16.31 - if (!send_flexpage.order)
16.32 - return -L4_ERANGE;
16.33 -
16.34 - region->fpage = ipc_get_fpage(&send_flexpage);
16.35 - region->snd_base = hot_spot;
16.36 -
16.37 - return L4_EOK;
16.38 -}
16.39 -
16.40 -/* Unmap the given flexpage. */
16.41 -
16.42 -void ipc_unmap_flexpage(Flexpage *flexpage)
16.43 -{
16.44 - SendFlexpage send_flexpage = flexpage->to_unmap();
16.45 -
16.46 - l4_task_unmap(L4RE_THIS_TASK_CAP, ipc_get_fpage(&send_flexpage), L4_FP_OTHER_SPACES);
16.47 -}
16.48 -
16.49 -// vim: tabstop=4 expandtab shiftwidth=4
17.1 --- a/ipc.h Thu Apr 01 00:57:43 2021 +0200
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,15 +0,0 @@
17.4 -#pragma once
17.5 -
17.6 -#include <l4/sys/ipc.h>
17.7 -
17.8 -#include "flexpage.h"
17.9 -
17.10 -
17.11 -
17.12 -long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset,
17.13 - unsigned long max_offset, l4_addr_t hot_spot,
17.14 - l4_snd_fpage_t *region);
17.15 -
17.16 -void ipc_unmap_flexpage(Flexpage *flexpage);
17.17 -
17.18 -// vim: tabstop=4 expandtab shiftwidth=4
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/mapping/ipc.cc Fri Apr 02 01:27:50 2021 +0200
18.3 @@ -0,0 +1,46 @@
18.4 +#include <l4/re/c/dataspace.h>
18.5 +#include <l4/re/consts.h>
18.6 +#include <l4/sys/task.h>
18.7 +
18.8 +#include "ipc.h"
18.9 +#include "send_flexpage.h"
18.10 +
18.11 +
18.12 +
18.13 +/* Make an L4 representation of the given flexpage. */
18.14 +
18.15 +static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage)
18.16 +{
18.17 + return l4_fpage(send_flexpage->base_addr, send_flexpage->order,
18.18 + (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO);
18.19 +}
18.20 +
18.21 +/* Make a representation of a flexpage for the IPC system. */
18.22 +
18.23 +long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset,
18.24 + unsigned long max_offset, l4_addr_t hot_spot,
18.25 + l4_snd_fpage_t *region)
18.26 +{
18.27 + SendFlexpage send_flexpage = flexpage->to_send(offset, hot_spot, max_offset);
18.28 +
18.29 + /* NOTE: Consider l4_fpage_invalid() as the fpage here. */
18.30 +
18.31 + if (!send_flexpage.order)
18.32 + return -L4_ERANGE;
18.33 +
18.34 + region->fpage = ipc_get_fpage(&send_flexpage);
18.35 + region->snd_base = hot_spot;
18.36 +
18.37 + return L4_EOK;
18.38 +}
18.39 +
18.40 +/* Unmap the given flexpage. */
18.41 +
18.42 +void ipc_unmap_flexpage(Flexpage *flexpage)
18.43 +{
18.44 + SendFlexpage send_flexpage = flexpage->to_unmap();
18.45 +
18.46 + l4_task_unmap(L4RE_THIS_TASK_CAP, ipc_get_fpage(&send_flexpage), L4_FP_OTHER_SPACES);
18.47 +}
18.48 +
18.49 +// vim: tabstop=4 expandtab shiftwidth=4
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/mapping/ipc.h Fri Apr 02 01:27:50 2021 +0200
19.3 @@ -0,0 +1,15 @@
19.4 +#pragma once
19.5 +
19.6 +#include <l4/sys/ipc.h>
19.7 +
19.8 +#include "flexpage.h"
19.9 +
19.10 +
19.11 +
19.12 +long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset,
19.13 + unsigned long max_offset, l4_addr_t hot_spot,
19.14 + l4_snd_fpage_t *region);
19.15 +
19.16 +void ipc_unmap_flexpage(Flexpage *flexpage);
19.17 +
19.18 +// vim: tabstop=4 expandtab shiftwidth=4
20.1 --- a/pager.cc Thu Apr 01 00:57:43 2021 +0200
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,91 +0,0 @@
20.4 -#include "dataspace_server.h"
20.5 -#include "ipc.h"
20.6 -#include "pager.h"
20.7 -
20.8 -
20.9 -
20.10 -Pager::Pager(PageMapper *mapper, flags_t flags)
20.11 -: _start(0), _size(0), _mapper(mapper), _flags(flags)
20.12 -{
20.13 - /* Some pagers may not be initialised with a mapper. */
20.14 -
20.15 - if (_mapper != NULL)
20.16 - _mapper->attach();
20.17 -}
20.18 -
20.19 -/* Close the pager. */
20.20 -
20.21 -void Pager::close()
20.22 -{
20.23 - if (_mapper != NULL)
20.24 - _mapper->detach();
20.25 -}
20.26 -
20.27 -/* Flush data to the file. */
20.28 -
20.29 -long Pager::flush(offset_t populated_size, offset_t *size)
20.30 -{
20.31 - _mapper->flush_all(_start, populated_size);
20.32 -
20.33 - *size = _mapper->get_data_size();
20.34 - return L4_EOK;
20.35 -}
20.36 -
20.37 -/* Resize the underlying file. */
20.38 -
20.39 -long Pager::resize(offset_t *size)
20.40 -{
20.41 - _mapper->set_data_size(*size);
20.42 -
20.43 - *size = _mapper->get_data_size();
20.44 - return L4_EOK;
20.45 -}
20.46 -
20.47 -/* Expose a region of the file. */
20.48 -
20.49 -long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end)
20.50 -{
20.51 - _start = trunc(position, PAGE_SIZE);
20.52 - _size = round(position + length, PAGE_SIZE) - _start;
20.53 -
20.54 - *start_pos = _start;
20.55 - *end_pos = _start + _size;
20.56 - *data_end = 0;
20.57 -
20.58 - return L4_EOK;
20.59 -}
20.60 -
20.61 -/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot'
20.62 - (flexpage offset). */
20.63 -
20.64 -long Pager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
20.65 -{
20.66 - offset_t file_offset = _start + offset;
20.67 - offset_t max_offset = _start + _size;
20.68 - Flexpage *flexpage = _mapper->get(file_offset, flags);
20.69 -
20.70 - /* Issue the flexpage via the IPC system. */
20.71 -
20.72 - long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, region);
20.73 -
20.74 - if (!err)
20.75 - err = complete_Dataspace_map(*region);
20.76 -
20.77 - /* After the flexpage is issued, it is queued for future reuse. */
20.78 -
20.79 - _mapper->queue(flexpage);
20.80 -
20.81 - if (err)
20.82 - return err;
20.83 -
20.84 - return IPC_MESSAGE_SENT;
20.85 -}
20.86 -
20.87 -/* Return the total size of the data. */
20.88 -
20.89 -offset_t Pager::get_data_size()
20.90 -{
20.91 - return _mapper->get_data_size();
20.92 -}
20.93 -
20.94 -// vim: tabstop=4 expandtab shiftwidth=4
21.1 --- a/pager.h Thu Apr 01 00:57:43 2021 +0200
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,43 +0,0 @@
21.4 -#pragma once
21.5 -
21.6 -#include <systypes/base.h>
21.7 -
21.8 -#include "page_mapper.h"
21.9 -#include "resource.h"
21.10 -
21.11 -
21.12 -
21.13 -/* A pager exposing a dataspace. */
21.14 -
21.15 -class Pager : public Resource
21.16 -{
21.17 -protected:
21.18 - offset_t _start, _size;
21.19 - PageMapper *_mapper;
21.20 - flags_t _flags;
21.21 -
21.22 -public:
21.23 - explicit Pager(PageMapper *mapper, flags_t flags);
21.24 -
21.25 - virtual void close();
21.26 -
21.27 - /* Paging methods. */
21.28 -
21.29 - virtual long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
21.30 -
21.31 - /* Limit methods. */
21.32 -
21.33 - offset_t get_data_size();
21.34 -
21.35 - /* File methods. */
21.36 -
21.37 - virtual long flush(offset_t populated_size, offset_t *size);
21.38 -
21.39 - virtual long resize(offset_t *size);
21.40 -
21.41 - /* Mapped file methods. */
21.42 -
21.43 - virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end);
21.44 -};
21.45 -
21.46 -// vim: tabstop=4 expandtab shiftwidth=4
22.1 --- a/resource.h Thu Apr 01 00:57:43 2021 +0200
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,56 +0,0 @@
22.4 -/*
22.5 - * Common resource classes and functions.
22.6 - *
22.7 - * Copyright (C) 2018, 2019, 2020 Paul Boddie <paul@boddie.org.uk>
22.8 - *
22.9 - * This program is free software; you can redistribute it and/or
22.10 - * modify it under the terms of the GNU General Public License as
22.11 - * published by the Free Software Foundation; either version 2 of
22.12 - * the License, or (at your option) any later version.
22.13 - *
22.14 - * This program is distributed in the hope that it will be useful,
22.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.17 - * GNU General Public License for more details.
22.18 - *
22.19 - * You should have received a copy of the GNU General Public License
22.20 - * along with this program; if not, write to the Free Software
22.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
22.22 - * Boston, MA 02110-1301, USA
22.23 - */
22.24 -
22.25 -#pragma once
22.26 -
22.27 -#include <ipc/server.h>
22.28 -
22.29 -
22.30 -
22.31 -/* A generic class for an object potentially needing to be closed after use. */
22.32 -
22.33 -class Resource
22.34 -{
22.35 -public:
22.36 - virtual ~Resource()
22.37 - {
22.38 - }
22.39 -
22.40 - /* Server details. */
22.41 -
22.42 - virtual int expected_items() = 0;
22.43 -
22.44 - virtual ipc_server_handler_type handler() = 0;
22.45 -
22.46 - virtual void *interface() = 0;
22.47 -
22.48 - /* Deallocation of resources. */
22.49 -
22.50 - virtual void close()
22.51 - {
22.52 - }
22.53 -
22.54 - /* Activation. */
22.55 -
22.56 - virtual void activate()
22.57 - {
22.58 - }
22.59 -};
23.1 --- a/simple_pager.cc Thu Apr 01 00:57:43 2021 +0200
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,62 +0,0 @@
23.4 -#include <l4/re/c/dataspace.h>
23.5 -
23.6 -#include "dataspace_server.h"
23.7 -#include "memory_incremental.h"
23.8 -#include "ipc.h"
23.9 -#include "simple_pager.h"
23.10 -
23.11 -
23.12 -
23.13 -SimplePager::SimplePager(Memory *memory)
23.14 -{
23.15 - if (memory == NULL)
23.16 - _memory = new MemoryIncremental();
23.17 - else
23.18 - _memory = memory;
23.19 -
23.20 - _region = _memory->region();
23.21 -}
23.22 -
23.23 -void SimplePager::close()
23.24 -{
23.25 - if (_region != NULL)
23.26 - {
23.27 - _memory->release(_region);
23.28 - _region = NULL;
23.29 - }
23.30 -}
23.31 -
23.32 -/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot'
23.33 - (flexpage offset). */
23.34 -
23.35 -long SimplePager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
23.36 -{
23.37 - Flexpage flexpage(_region);
23.38 -
23.39 - flexpage.reset(offset);
23.40 - flexpage.upgrade(flags);
23.41 -
23.42 - /* Send the flexpage explicitly. */
23.43 -
23.44 - long err = ipc_prepare_flexpage(&flexpage, offset, _region->size(), hot_spot, region);
23.45 -
23.46 - if (err)
23.47 - return err;
23.48 -
23.49 - err = complete_Dataspace_map(*region);
23.50 -
23.51 - if (err)
23.52 - return err;
23.53 -
23.54 - return IPC_MESSAGE_SENT;
23.55 -}
23.56 -
23.57 -long SimplePager::info(offset_t *size, flags_t *flags)
23.58 -{
23.59 - *size = _region->size();
23.60 - *flags = L4_FPAGE_RW;
23.61 -
23.62 - return L4_EOK;
23.63 -}
23.64 -
23.65 -// vim: tabstop=4 expandtab shiftwidth=4
24.1 --- a/simple_pager.h Thu Apr 01 00:57:43 2021 +0200
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,30 +0,0 @@
24.4 -#pragma once
24.5 -
24.6 -#include "dataspace_interface.h"
24.7 -#include "flexpage.h"
24.8 -#include "memory.h"
24.9 -#include "resource.h"
24.10 -
24.11 -
24.12 -
24.13 -/* A simple pager exposing a single memory region as a dataspace. */
24.14 -
24.15 -class SimplePager : public Dataspace, public Resource
24.16 -{
24.17 -protected:
24.18 - Memory *_memory;
24.19 - Region *_region;
24.20 -
24.21 -public:
24.22 - explicit SimplePager(Memory *memory=NULL);
24.23 -
24.24 - void close();
24.25 -
24.26 - /* Paging methods. */
24.27 -
24.28 - long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
24.29 -
24.30 - long info(offset_t *size, flags_t *flags);
24.31 -};
24.32 -
24.33 -// vim: tabstop=4 expandtab shiftwidth=4
25.1 --- a/types.h Thu Apr 01 00:57:43 2021 +0200
25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3 @@ -1,9 +0,0 @@
25.4 -#pragma once
25.5 -
25.6 -/* File identification. */
25.7 -
25.8 -typedef unsigned long fileid_t;
25.9 -
25.10 -#define FILEID_INVALID (~0UL)
25.11 -
25.12 -// vim: tabstop=4 expandtab shiftwidth=4