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