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