1.1 --- a/libexec/lib/src/pager.cc Sun Jun 12 18:04:17 2022 +0200
1.2 +++ b/libexec/lib/src/pager.cc Sun Jun 12 18:56:25 2022 +0200
1.3 @@ -1,5 +1,5 @@
1.4 /*
1.5 - * A system pager implementation.
1.6 + * A system pager interface.
1.7 *
1.8 * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 @@ -19,236 +19,14 @@
1.11 * Boston, MA 02110-1301, USA
1.12 */
1.13
1.14 -#include <l4/re/env.h>
1.15 -#include <l4/sys/err.h>
1.16 -#include <l4/util/util.h>
1.17 -
1.18 -#include <ipc/mem_ipc.h>
1.19 -#include <mem/memory_utils.h>
1.20 -
1.21 -#include <stdio.h>
1.22 -#include <string.h>
1.23 -
1.24 #include "pager.h"
1.25 -#include "pager_object_server.h"
1.26
1.27
1.28
1.29 -/* A simple system pager also acting as a region mapper. */
1.30 -
1.31 -/* Add a region to the pager. */
1.32 -
1.33 -void ExecPager::add(MappedRegion region)
1.34 -{
1.35 - _regions[region.map_start] = region;
1.36 -}
1.37 -
1.38 -/* Handle a general exception. */
1.39 -
1.40 -long ExecPager::exception(l4_exc_regs_t regs, l4_snd_fpage_t *region)
1.41 -{
1.42 - (void) region;
1.43 -
1.44 - printf("exception(...) -> pfa = %lx, pc = %lx\n", l4_utcb_exc_pfa(®s), l4_utcb_exc_pc(®s));
1.45 -
1.46 - printf("r15 = %lx\n", regs.r15);
1.47 - printf("r14 = %lx\n", regs.r14);
1.48 - printf("r13 = %lx\n", regs.r13);
1.49 - printf("r12 = %lx\n", regs.r12);
1.50 - printf("r11 = %lx\n", regs.r11);
1.51 - printf("r10 = %lx\n", regs.r10);
1.52 - printf("r9 = %lx\n", regs.r9);
1.53 - printf("r8 = %lx\n", regs.r8);
1.54 - printf("rdi = %lx\n", regs.rdi);
1.55 - printf("rsi = %lx\n", regs.rsi);
1.56 - printf("rbp = %lx\n", regs.rbp);
1.57 - printf("pfa = %lx\n", regs.pfa);
1.58 - printf("rbx = %lx\n", regs.rbx);
1.59 - printf("rdx = %lx\n", regs.rdx);
1.60 - printf("rcx = %lx\n", regs.rcx);
1.61 - printf("rax = %lx\n", regs.rax);
1.62 - printf("trapno = %lx\n", regs.trapno);
1.63 - printf("err = %lx\n", regs.err);
1.64 - printf("ip = %lx\n", regs.ip);
1.65 - printf("flags = %lx\n", regs.flags);
1.66 - printf("sp = %lx\n", regs.sp);
1.67 - printf("ss = %lx\n", regs.ss);
1.68 - printf("fs_base = %lx\n", regs.fs_base);
1.69 - printf("gs_base = %lx\n", regs.gs_base);
1.70 -
1.71 - return L4_EOK;
1.72 -}
1.73 -
1.74 -#define DEBUG 0
1.75 -
1.76 -/* Handle a page fault using any configured regions. */
1.77 -
1.78 -long ExecPager::page_fault(l4_umword_t pfa, l4_umword_t pc, l4_snd_fpage_t *region)
1.79 -{
1.80 - l4_umword_t addr = pfa & ~7UL, flags = pfa & 7;
1.81 -
1.82 -#if DEBUG
1.83 - printf("page_fault(%lx, %lx) -> %lx (%lx) -> ", pfa, pc, addr, flags);
1.84 -#endif
1.85 -
1.86 - MappedRegions::iterator it = _regions.upper_bound(addr);
1.87 -
1.88 - if (it != _regions.begin())
1.89 - it--;
1.90 - else
1.91 - {
1.92 - printf("not mapped!\n");
1.93 - return -L4_ENOMEM;
1.94 - }
1.95 -
1.96 - MappedRegion &r = it->second;
1.97 -
1.98 - if ((addr >= r.map_start) && (addr < r.map_start + r.size))
1.99 - {
1.100 - l4_addr_t page_addr = trunc(addr, L4_PAGESIZE);
1.101 -
1.102 - region->fpage = l4_fpage(r.start + (page_addr - r.map_start), L4_PAGESHIFT, r.flags);
1.103 - region->snd_base = page_addr;
1.104 -
1.105 -#if DEBUG
1.106 - printf("%lx...%lx from %lx...%lx offset %lx size %d rights %x\n",
1.107 - r.map_start, region->snd_base,
1.108 - r.start, l4_fpage_memaddr(region->fpage),
1.109 - addr - r.map_start,
1.110 - l4_fpage_size(region->fpage),
1.111 - l4_fpage_rights(region->fpage));
1.112 -
1.113 - printf("%lx -> ", addr);
1.114 -
1.115 - for (unsigned int i = 0; i < sizeof(l4_umword_t); i++)
1.116 - printf("%02x", *((unsigned char *)(r.start + (addr - r.map_start) + i)));
1.117 -
1.118 - printf("\n");
1.119 -#endif
1.120 -
1.121 - if (r.flags & L4RE_RM_F_W)
1.122 - l4_touch_rw((const void *) (r.start + (page_addr - r.map_start)), L4_PAGESIZE);
1.123 - else
1.124 - l4_touch_ro((const void *) (r.start + (page_addr - r.map_start)), L4_PAGESIZE);
1.125 -
1.126 - return L4_EOK;
1.127 - }
1.128 -
1.129 -#if DEBUG
1.130 - printf("not mapped!\n");
1.131 -#endif
1.132 -
1.133 - return -L4_ENOMEM;
1.134 -}
1.135 +/* Necessary virtual destructor. */
1.136
1.137 -/* Attach a region for provision when page faults occur. This is required in
1.138 - the initialisation of a program by the C library which requires a region
1.139 - mapper. */
1.140 -
1.141 -long ExecPager::attach(address_t *start, offset_t size, map_flags_t flags,
1.142 - l4_cap_idx_t ds, address_t offset, unsigned char align)
1.143 +ExecPager::~ExecPager()
1.144 {
1.145 -#if DEBUG
1.146 - printf("attach(%lx, %ld, %lx, ..., %lx, %d)\n", *start, size, flags, offset, align);
1.147 -#endif
1.148 -
1.149 - if (align < L4_PAGESHIFT)
1.150 - align = L4_PAGESHIFT;
1.151 -
1.152 - offset_t increment = 1UL << align;
1.153 - offset_t region_size = round(size, increment);
1.154 -
1.155 - /* Either attempt to find an address for the specified region, starting from
1.156 - any indicated address. */
1.157 -
1.158 - if (flags & L4RE_RM_F_SEARCH_ADDR)
1.159 - {
1.160 - address_t region_start = trunc(*start, increment);
1.161 - MappedRegions::iterator it = _regions.upper_bound(*start);
1.162 -
1.163 - if (!region_start)
1.164 - region_start += increment;
1.165 -
1.166 -#if DEBUG
1.167 - printf("-> search from %lx -> %lx...\n", *start, region_start);
1.168 -#endif
1.169 -
1.170 - /* Before last known region. */
1.171 -
1.172 - while (it != _regions.end())
1.173 - {
1.174 - MappedRegions::iterator next = it;
1.175 - MappedRegion &r = it->second;
1.176 - address_t start_limit;
1.177 - address_t end_limit = r.map_start;
1.178 -
1.179 - /* Consider any preceding region. If no such region exists, choose an
1.180 - address at the start of memory. */
1.181 -
1.182 - if (it == _regions.begin())
1.183 - start_limit = L4_PAGESIZE;
1.184 - else
1.185 - {
1.186 - it--;
1.187 - MappedRegion &pr = it->second;
1.188 - start_limit = pr.map_start + pr.size;
1.189 - it = next;
1.190 - }
1.191 -
1.192 - /* Test against the limits. */
1.193 -
1.194 - if (region_start < start_limit)
1.195 - region_start = round(start_limit, increment);
1.196 -
1.197 - /* Investigate subsequent regions if not enough space exists between the
1.198 - preceding region (or start of memory) and the current region. */
1.199 -
1.200 - if ((region_start + region_size) > end_limit)
1.201 - {
1.202 - it++;
1.203 - if (it == _regions.end())
1.204 - return -L4_ENOMEM;
1.205 - }
1.206 - else
1.207 - break;
1.208 - }
1.209 -
1.210 - /* Attach the provided dataspace.
1.211 - NOTE: This is only done in this implementation to support the paging
1.212 - mechanism. In a region mapper residing within the actual task, the
1.213 - dataspace's map operation would be invoked to obtain mappings. */
1.214 -
1.215 - l4_addr_t ds_start;
1.216 -
1.217 - long err = ipc_attach_dataspace(ds, size, (void **) &ds_start);
1.218 -
1.219 - if (err)
1.220 - return err;
1.221 -
1.222 - l4_touch_rw((const void *) ds_start, size);
1.223 -
1.224 -#if DEBUG
1.225 - printf("-> added region for %lx size %ld (%d)\n", region_start, region_size, page_order(region_size));
1.226 -#endif
1.227 -
1.228 - add(MappedRegion(ds_start, region_size, flags & L4RE_DS_F_RIGHTS_MASK, region_start));
1.229 -
1.230 - *start = region_start;
1.231 - return L4_EOK;
1.232 - }
1.233 -
1.234 - /* Or attempt to add the specified region at a specific address. */
1.235 -
1.236 - else
1.237 - {
1.238 - // NOTE: To be implemented.
1.239 -
1.240 -#if DEBUG
1.241 - printf("-> region of size %ld (%d) not added!\n", region_size, page_order(region_size));
1.242 -#endif
1.243 -
1.244 - return -L4_ENOMEM;
1.245 - }
1.246 }
1.247
1.248 /* vim: tabstop=2 expandtab shiftwidth=2