1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Makefile Tue Jan 19 23:26:49 2021 +0100
1.3 @@ -0,0 +1,41 @@
1.4 +PKGDIR ?= .
1.5 +L4DIR ?= $(PKGDIR)/../..
1.6 +
1.7 +TARGET = dstest_client dstest_server
1.8 +MODE = shared
1.9 +
1.10 +# Locations for interface input and generated output.
1.11 +
1.12 +IDL_DIR = $(L4DIR)/pkg/libsystypes/idl
1.13 +IDL_MK_DIR = $(L4DIR)/idl4re/mk
1.14 +IDL_BUILD_DIR = .
1.15 +IDL_EXPORT_DIR = .
1.16 +
1.17 +include $(IDL_MK_DIR)/idl.mk
1.18 +
1.19 +# Individual interfaces.
1.20 +
1.21 +SERVER_INTERFACES_CC = dataspace
1.22 +
1.23 +# Generated and plain source files.
1.24 +
1.25 +SERVER_INTERFACES_SRC_CC = $(call interfaces_to_server_cc,$(SERVER_INTERFACES_CC))
1.26 +
1.27 +PLAIN_SRC_CC = dstest_server.cc flexpage.cc memory_utils.cc region.cc
1.28 +
1.29 +# Normal definitions.
1.30 +
1.31 +SRC_CC_dstest_client = dstest_client.cc
1.32 +
1.33 +SRC_CC_dstest_server = \
1.34 + $(SERVER_INTERFACES_SRC_CC) \
1.35 + $(PLAIN_SRC_CC)
1.36 +
1.37 +REQUIRES_LIBS = l4re_c-util libipc libstdc++
1.38 +
1.39 +PRIVATE_INCDIR = $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
1.40 +
1.41 +include $(L4DIR)/mk/prog.mk
1.42 +include $(IDL_MK_DIR)/interface_rules.mk
1.43 +
1.44 +$(PLAIN_SRC_CC): $(SERVER_INTERFACES_SRC_CC)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/conf/dstest.cfg Tue Jan 19 23:26:49 2021 +0100
2.3 @@ -0,0 +1,23 @@
2.4 +-- vim:set ft=lua:
2.5 +
2.6 +local L4 = require("L4");
2.7 +
2.8 +local l = L4.default_loader;
2.9 +
2.10 +local server = l:new_channel();
2.11 +
2.12 +l:start({
2.13 + caps = {
2.14 + server = server:svr(),
2.15 + },
2.16 + log = { "server", "r" },
2.17 + },
2.18 + "rom/dstest_server");
2.19 +
2.20 +l:start({
2.21 + caps = {
2.22 + server = server,
2.23 + },
2.24 + log = { "client", "g" },
2.25 + },
2.26 + "rom/dstest_client");
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/conf/dstest.list Tue Jan 19 23:26:49 2021 +0100
3.3 @@ -0,0 +1,25 @@
3.4 +entry dstest
3.5 +roottask moe rom/dstest.cfg
3.6 +module dstest.cfg
3.7 +module l4re
3.8 +module ned
3.9 +module dstest_client
3.10 +module dstest_server
3.11 +module lib4re-c.so
3.12 +module lib4re-c-util.so
3.13 +module lib4re.so
3.14 +module lib4re-util.so
3.15 +module libc_be_l4refile.so
3.16 +module libc_be_l4re.so
3.17 +module libc_be_socket_noop.so
3.18 +module libc_support_misc.so
3.19 +module libdl.so
3.20 +module libipc.so
3.21 +module libl4sys-direct.so
3.22 +module libl4sys.so
3.23 +module libl4util.so
3.24 +module libld-l4.so
3.25 +module libpthread.so
3.26 +module libstdc++.so
3.27 +module libsupc++.so
3.28 +module libuc_c.so
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/dstest_client.cc Tue Jan 19 23:26:49 2021 +0100
4.3 @@ -0,0 +1,59 @@
4.4 +/*
4.5 + * Test dataspace operations.
4.6 + *
4.7 + * Copyright (C) 2020, 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 <l4/re/env.h>
4.26 +#include <l4/sys/err.h>
4.27 +
4.28 +#include <stdio.h>
4.29 +#include <string.h>
4.30 +#include <stdlib.h>
4.31 +
4.32 +#include <ipc/mem_ipc.h>
4.33 +
4.34 +
4.35 +
4.36 +int main(void)
4.37 +{
4.38 + l4_cap_idx_t server = l4re_env_get_cap("server");
4.39 +
4.40 + /* Some memory to be mapped. */
4.41 +
4.42 + char *memory;
4.43 + unsigned long size = 40960;
4.44 + long err = ipc_attach_dataspace(server, size, (void **) &memory);
4.45 +
4.46 + if (err)
4.47 + {
4.48 + printf("Could not map memory: %s\n", l4sys_errtostr(err));
4.49 + return 1;
4.50 + }
4.51 +
4.52 + printf("Mapped memory at %p\n", memory);
4.53 +
4.54 + for (unsigned long offset = 0; offset < size; offset += 1024)
4.55 + {
4.56 + printf("10 bytes from %p...\n", (memory + offset));
4.57 + fwrite((memory + offset), sizeof(char), 10, stdout);
4.58 + fputs("\n", stdout);
4.59 + }
4.60 +
4.61 + return 0;
4.62 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/dstest_server.cc Tue Jan 19 23:26:49 2021 +0100
5.3 @@ -0,0 +1,125 @@
5.4 +/*
5.5 + * Test dataspace operations.
5.6 + *
5.7 + * Copyright (C) 2020 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/re/env.h>
5.26 +#include <l4/sys/err.h>
5.27 +
5.28 +#include <stdio.h>
5.29 +#include <string.h>
5.30 +#include <stdlib.h>
5.31 +
5.32 +#include <ipc/server.h>
5.33 +
5.34 +#include "dataspace_server.h"
5.35 +#include "flexpage.h"
5.36 +
5.37 +
5.38 +
5.39 +/* Component interface. */
5.40 +
5.41 +class DataspaceServer : public Dataspace
5.42 +{
5.43 +protected:
5.44 + Region *_region;
5.45 + offset_t _start, _size;
5.46 +
5.47 +public:
5.48 + explicit DataspaceServer(char *addr, offset_t size)
5.49 + {
5.50 + _region = new Region((offset_t) addr, (offset_t) addr + size);
5.51 + _start = 0;
5.52 + _size = size;
5.53 +
5.54 + offset_t i;
5.55 + int j;
5.56 +
5.57 + for (i = 0, j = 0; i < size; i += PAGE_SIZE, j++)
5.58 + memset((void *) (addr + i), (int) 'a' + j, PAGE_SIZE);
5.59 + }
5.60 +
5.61 + virtual long map(unsigned long offset, l4_addr_t hot_spot, unsigned long flags, l4_snd_fpage_t *region)
5.62 + {
5.63 + Flexpage flexpage(_region);
5.64 + offset_t max_offset = _start + _size;
5.65 +
5.66 + printf("map(%ld, %lx, %lx, ...)\n", offset, hot_spot, flags);
5.67 +
5.68 + flexpage.reset(_start + offset);
5.69 +
5.70 + SendFlexpage send_flexpage = flexpage.to_send(offset, hot_spot, max_offset);
5.71 +
5.72 + printf("send %lx -> %lx -> {%lx, %d}\n", _region->start, flexpage.base_addr, send_flexpage.base_addr, send_flexpage.order);
5.73 +
5.74 + /* Send the flexpage explicitly. */
5.75 +
5.76 + region->fpage = l4_fpage(send_flexpage.base_addr, send_flexpage.order,
5.77 + (flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW
5.78 + : L4_FPAGE_RO);
5.79 + region->snd_base = hot_spot;
5.80 +
5.81 + long err = complete_Dataspace_map(*region);
5.82 +
5.83 + if (err)
5.84 + return err;
5.85 +
5.86 + return IPC_MESSAGE_SENT;
5.87 + }
5.88 +};
5.89 +
5.90 +
5.91 +
5.92 +int main(void)
5.93 +{
5.94 + /* Some memory. */
5.95 +
5.96 + char *memory;
5.97 +
5.98 + if (posix_memalign((void **) &memory, 40960, 40960))
5.99 + {
5.100 + printf("Could not allocate memory.\n");
5.101 + return 1;
5.102 + }
5.103 +
5.104 + /* Dataspace encapsulation. */
5.105 +
5.106 + DataspaceServer obj(memory, 40960);
5.107 +
5.108 + /* Server capability. */
5.109 +
5.110 + l4_cap_idx_t server;
5.111 +
5.112 + /* Register a server associating it with the given object. */
5.113 +
5.114 + long err = ipc_server_bind("server", (l4_umword_t) &obj, &server);
5.115 +
5.116 + if (err)
5.117 + {
5.118 + printf("Could not bind server: %s\n", l4sys_errtostr(err));
5.119 + return 1;
5.120 + }
5.121 +
5.122 + /* Wait for messages, dispatching to the handler. */
5.123 +
5.124 + ipc_server_loop(Dataspace_expected_items, &obj,
5.125 + (ipc_server_handler_type) handle_Dataspace);
5.126 +
5.127 + return 0;
5.128 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/flexpage.cc Tue Jan 19 23:26:49 2021 +0100
6.3 @@ -0,0 +1,140 @@
6.4 +#include <algorithm>
6.5 +#include <stdio.h>
6.6 +
6.7 +#include "flexpage.h"
6.8 +
6.9 +
6.10 +
6.11 +/* Reset the flexpage using 'offset', being the file offset. */
6.12 +
6.13 +void Flexpage::reset(offset_t offset)
6.14 +{
6.15 + _counter = 0;
6.16 +
6.17 + /* By definition (see "Flexible-Sized Page Objects - Object-Orientation
6.18 + in Operation Systems"), flexpages are aligned to multiples of their
6.19 + size.
6.20 +
6.21 + The size of the flexpage depends on the amount of space around the
6.22 + accessed page. It cannot exceed the size of the memory region. */
6.23 +
6.24 + size = max_multiple(region->start, region->end, PAGE_SIZE);
6.25 +
6.26 + /* The base address of the flexpage is computed from the region start
6.27 + and flexpage size. It will be no lower than the region start.
6.28 +
6.29 + Sent flexpages may use higher bases due to receive window constraints,
6.30 + these being communicated by the "hot spot". */
6.31 +
6.32 + base_addr = round(region->start, size);
6.33 +
6.34 + /* Get the file offset for the base of the flexpage. This will be a
6.35 + multiple of the flexpage size for alignment purposes. */
6.36 +
6.37 + base_offset = trunc(offset, size);
6.38 +
6.39 + /* The page being accessed is relative to the base.
6.40 + (This is transient information recording the initialising access
6.41 + details.) */
6.42 +
6.43 + page_offset = trunc(offset - base_offset, PAGE_SIZE);
6.44 + page_addr = base_addr + page_offset;
6.45 +}
6.46 +
6.47 +bool Flexpage::decrement()
6.48 +{
6.49 + if (_counter)
6.50 + {
6.51 + _counter--;
6.52 + return _counter == 0;
6.53 + }
6.54 + else
6.55 + return 0;
6.56 +}
6.57 +
6.58 +void Flexpage::increment()
6.59 +{
6.60 + _counter++;
6.61 +}
6.62 +
6.63 +void Flexpage::invalidate()
6.64 +{
6.65 + _counter = 0;
6.66 +}
6.67 +
6.68 +bool Flexpage::valid()
6.69 +{
6.70 + return _counter != 0;
6.71 +}
6.72 +
6.73 +/* Return whether the flexpage supports the given file 'position'. */
6.74 +
6.75 +bool Flexpage::supports_position(offset_t position)
6.76 +{
6.77 + return (base_offset <= position) && (position < (base_offset + size));
6.78 +}
6.79 +
6.80 +/* Return a "send" flexpage for an access to 'offset' by positioning it relative
6.81 + to 'hot_spot' for the receive flexpage window. */
6.82 +
6.83 +SendFlexpage Flexpage::to_send(offset_t offset, offset_t hot_spot, offset_t max_offset)
6.84 +{
6.85 + /* The dataspace offset of the flexpage base is a multiple of the flexpage
6.86 + size. */
6.87 +
6.88 + offset_t receive_base_offset = trunc(offset, size);
6.89 +
6.90 + /* The offset of the accessed page within the flexpage is constrained by the
6.91 + current flexpage size. */
6.92 +
6.93 + offset_t page_offset = trunc(offset - receive_base_offset, PAGE_SIZE);
6.94 +
6.95 + /* The receive flexpage offset (hot spot) must be constrained to the
6.96 + flexpage, both the size and the start. */
6.97 +
6.98 + offset_t receive_size;
6.99 +
6.100 + if (max_offset)
6.101 + receive_size = std::min(size, max_offset - receive_base_offset);
6.102 + else
6.103 + receive_size = size;
6.104 +
6.105 + offset_t receive_page_offset = hot_spot % receive_size;
6.106 +
6.107 + while ((receive_size > PAGE_SIZE) && (receive_page_offset != page_offset))
6.108 + {
6.109 + receive_size /= 2;
6.110 + receive_page_offset = hot_spot % receive_size;
6.111 + }
6.112 +
6.113 + /* The flexpage base address is adjusted using the difference in page
6.114 + offsets. Where the receive flexpage offset is constained further, the
6.115 + base address will be raised to become closer to the accessed page. */
6.116 +
6.117 + offset_t adjustment = page_offset - receive_page_offset;
6.118 +
6.119 + return SendFlexpage(base_addr + adjustment, page_order(receive_size));
6.120 +}
6.121 +
6.122 +/* Return a representation of the flexpage for unmapping. */
6.123 +
6.124 +SendFlexpage Flexpage::to_unmap()
6.125 +{
6.126 + return SendFlexpage(base_addr, page_order(size));
6.127 +}
6.128 +
6.129 +/* Debugging methods. */
6.130 +
6.131 +void Flexpage::show(std::ostringstream &buffer)
6.132 +{
6.133 + char buf[256];
6.134 +
6.135 + snprintf(buf, 256, "Flexpage(base_offset=0x%lx/%ld, "
6.136 + "base_addr=0x%lx, size=0x%lx/%ld)",
6.137 + base_offset, base_offset, base_addr,
6.138 + size, size);
6.139 +
6.140 + buffer << buf;
6.141 +}
6.142 +
6.143 +// vim: tabstop=4 expandtab shiftwidth=4
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/flexpage.h Tue Jan 19 23:26:49 2021 +0100
7.3 @@ -0,0 +1,57 @@
7.4 +#pragma once
7.5 +
7.6 +#include <sstream>
7.7 +
7.8 +#include "memory_utils.h"
7.9 +#include "region.h"
7.10 +#include "send_flexpage.h"
7.11 +
7.12 +
7.13 +
7.14 +/* A flexpage abstraction. */
7.15 +
7.16 +class Flexpage
7.17 +{
7.18 +protected:
7.19 + unsigned int _counter;
7.20 +
7.21 +public:
7.22 + Region *region;
7.23 +
7.24 + /* General flexpage characteristics. */
7.25 +
7.26 + offset_t base_addr, size;
7.27 + offset_t base_offset;
7.28 +
7.29 + /* Transient debugging information. */
7.30 +
7.31 + offset_t page_addr, page_offset;
7.32 +
7.33 + /* Associate a flexpage with a memory 'region'. */
7.34 +
7.35 + explicit Flexpage(Region *region) : region(region)
7.36 + {
7.37 + }
7.38 +
7.39 + void reset(offset_t offset);
7.40 +
7.41 + bool decrement();
7.42 +
7.43 + void increment();
7.44 +
7.45 + void invalidate();
7.46 +
7.47 + bool valid();
7.48 +
7.49 + bool supports_position(offset_t position);
7.50 +
7.51 + SendFlexpage to_send(offset_t offset, offset_t hot_spot, offset_t max_offset=0);
7.52 +
7.53 + SendFlexpage to_unmap();
7.54 +
7.55 + /* Debugging methods. */
7.56 +
7.57 + void show(std::ostringstream &buffer);
7.58 +};
7.59 +
7.60 +// vim: tabstop=4 expandtab shiftwidth=4
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/memory_utils.cc Tue Jan 19 23:26:49 2021 +0100
8.3 @@ -0,0 +1,111 @@
8.4 +#include "memory_utils.h"
8.5 +
8.6 +
8.7 +
8.8 +/* Return page 'n' for the configured page size. */
8.9 +
8.10 +offset_t page(unsigned int n)
8.11 +{
8.12 + return PAGE_SIZE * n;
8.13 +}
8.14 +
8.15 +/* Return the order of 'size', where 2 ** order yields the size. */
8.16 +
8.17 +unsigned int page_order(offset_t size)
8.18 +{
8.19 + /* Count zeros from the left, stopping at the first set bit, using the width
8.20 + of the size value (in bits, starting with the width in bytes) to
8.21 + calculate the position of this bit and thus the order of the value. */
8.22 +
8.23 + return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size);
8.24 +}
8.25 +
8.26 +/* Return 'value' rounded up to the nearest 'increment'. */
8.27 +
8.28 +offset_t round(offset_t value, offset_t increment)
8.29 +{
8.30 + return trunc(value + increment - 1, increment);
8.31 +}
8.32 +
8.33 +/* Return 'value' rounded up to the nearest multiple of 'increment'. */
8.34 +
8.35 +offset_t round_multiple(offset_t value, offset_t increment)
8.36 +{
8.37 + offset_t last = increment;
8.38 +
8.39 + while (1)
8.40 + {
8.41 + if (value < increment)
8.42 + return round(value, last);
8.43 +
8.44 + last = increment;
8.45 + increment *= 2;
8.46 + }
8.47 +}
8.48 +
8.49 +/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */
8.50 +
8.51 +offset_t trunc(offset_t value, offset_t increment)
8.52 +{
8.53 + return (value / increment) * increment;
8.54 +}
8.55 +
8.56 +/* Return 'value' rounded down (or truncated) to the nearest multiple of
8.57 + 'increment'. */
8.58 +
8.59 +offset_t trunc_multiple(offset_t value, offset_t increment)
8.60 +{
8.61 + offset_t last = increment;
8.62 +
8.63 + while (1)
8.64 + {
8.65 + if (value < increment)
8.66 + return trunc(value, last);
8.67 +
8.68 + last = increment;
8.69 + increment *= 2;
8.70 + }
8.71 +}
8.72 +
8.73 +/* Find the maximum size aligned region within the region from 'start' to (but
8.74 + not including) 'end', with the given initial 'increment'. */
8.75 +
8.76 +offset_t max_multiple(offset_t start, offset_t end, offset_t increment)
8.77 +{
8.78 + /* The largest possible aligned region is derived from the region size. */
8.79 +
8.80 + offset_t size = trunc_multiple(end - start, increment);
8.81 +
8.82 + /* Apply the alignment to the start. */
8.83 +
8.84 + offset_t aligned = round(start, size);
8.85 +
8.86 + /* If the region is aligned, return the size. */
8.87 +
8.88 + if (aligned == start)
8.89 + return size;
8.90 +
8.91 + /* If the region is not aligned to the current size, recalculate the aligned
8.92 + size. */
8.93 +
8.94 + offset_t aligned_size;
8.95 +
8.96 + do
8.97 + {
8.98 + aligned_size = trunc_multiple(end - aligned, increment);
8.99 + size /= 2;
8.100 +
8.101 + /* Determine whether a smaller alignment could yield a larger aligned
8.102 + size. */
8.103 +
8.104 + if (aligned_size >= size)
8.105 + return aligned_size;
8.106 +
8.107 + aligned = round(start, size);
8.108 + }
8.109 + while (aligned > start);
8.110 +
8.111 + return aligned_size;
8.112 +}
8.113 +
8.114 +// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/memory_utils.h Tue Jan 19 23:26:49 2021 +0100
9.3 @@ -0,0 +1,25 @@
9.4 +#pragma once
9.5 +
9.6 +#include "types.h"
9.7 +
9.8 +#define PAGE_SIZE 4096
9.9 +
9.10 +
9.11 +
9.12 +/* Address arithmetic. */
9.13 +
9.14 +offset_t page(unsigned int n);
9.15 +
9.16 +unsigned int page_order(offset_t size);
9.17 +
9.18 +offset_t round(offset_t value, offset_t increment);
9.19 +
9.20 +offset_t round_multiple(offset_t value, offset_t increment);
9.21 +
9.22 +offset_t trunc(offset_t value, offset_t increment);
9.23 +
9.24 +offset_t trunc_multiple(offset_t value, offset_t increment);
9.25 +
9.26 +offset_t max_multiple(offset_t start, offset_t end, offset_t increment);
9.27 +
9.28 +// vim: tabstop=4 expandtab shiftwidth=4
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/region.cc Tue Jan 19 23:26:49 2021 +0100
10.3 @@ -0,0 +1,90 @@
10.4 +#include <stdio.h>
10.5 +#include <string.h>
10.6 +#include <stdlib.h>
10.7 +
10.8 +#include "region.h"
10.9 +
10.10 +
10.11 +
10.12 +/* Initialise region state, indicating the size, file and position. */
10.13 +
10.14 +RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos)
10.15 +: size(size), fileid(fileid), filepos(filepos)
10.16 +{
10.17 +}
10.18 +
10.19 +void RegionState::fill(fileid_t fileid, offset_t filepos)
10.20 +{
10.21 + this->fileid = fileid;
10.22 + this->filepos = filepos;
10.23 +}
10.24 +
10.25 +void RegionState::show(std::ostringstream &buffer)
10.26 +{
10.27 + char buf[64];
10.28 +
10.29 + snprintf(buf, 64, "{%3ld:%6ld}", fileid, filepos);
10.30 +
10.31 + buffer << buf;
10.32 +}
10.33 +
10.34 +
10.35 +
10.36 +/* Initialise a region having the given 'start' and 'end' addresses, with the
10.37 + 'end' being one location beyond the last address in the region. */
10.38 +
10.39 +Region::Region(offset_t start, offset_t end)
10.40 +: start(start), end(end), state(end - start)
10.41 +{
10.42 + /* Content state. */
10.43 +
10.44 + memset((void *) start, 0, end - start);
10.45 +}
10.46 +
10.47 +Region::~Region()
10.48 +{
10.49 + free((void *) start);
10.50 +}
10.51 +
10.52 +offset_t Region::size()
10.53 +{
10.54 + return end - start;
10.55 +}
10.56 +
10.57 +/* Debugging methods. */
10.58 +
10.59 +int Region::compare(Region *other)
10.60 +{
10.61 + if (start < other->start)
10.62 + return -1;
10.63 + else if (start > other->start)
10.64 + return 1;
10.65 + else
10.66 + return 0;
10.67 +}
10.68 +
10.69 +void Region::fill(fileid_t fileid, offset_t filepos)
10.70 +{
10.71 + state.fill(fileid, filepos);
10.72 +}
10.73 +
10.74 +void Region::flush()
10.75 +{
10.76 +}
10.77 +
10.78 +/* Simulation methods. */
10.79 +
10.80 +char *Region::read(offset_t offset)
10.81 +{
10.82 + return (char *) start + offset;
10.83 +}
10.84 +
10.85 +void Region::write(const char *data, offset_t offset)
10.86 +{
10.87 + size_t length = strlen(data);
10.88 +
10.89 + if (offset + length < size())
10.90 + memcpy((void *) (start + offset), data, length + 1);
10.91 +}
10.92 +
10.93 +// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/send_flexpage.h Tue Jan 19 23:26:49 2021 +0100
12.3 @@ -0,0 +1,19 @@
12.4 +#pragma once
12.5 +
12.6 +#include "types.h"
12.7 +
12.8 +/* A "send" flexpage abstraction. */
12.9 +
12.10 +class SendFlexpage
12.11 +{
12.12 +public:
12.13 + offset_t base_addr;
12.14 + unsigned int order;
12.15 +
12.16 + explicit SendFlexpage(offset_t base_addr, unsigned int order)
12.17 + : base_addr(base_addr), order(order)
12.18 + {
12.19 + }
12.20 +};
12.21 +
12.22 +// vim: tabstop=4 expandtab shiftwidth=4
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/types.h Tue Jan 19 23:26:49 2021 +0100
13.3 @@ -0,0 +1,13 @@
13.4 +#pragma once
13.5 +
13.6 +/* File identification. */
13.7 +
13.8 +typedef unsigned long fileid_t;
13.9 +
13.10 +#define FILEID_INVALID (~0UL)
13.11 +
13.12 +/* File and memory region offsets. */
13.13 +
13.14 +typedef unsigned long offset_t;
13.15 +
13.16 +// vim: tabstop=4 expandtab shiftwidth=4