2020-06-15 14:18:57 +00:00
|
|
|
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
2021-02-24 04:23:19 +00:00
|
|
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
2020-06-15 14:18:57 +00:00
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
|
|
|
|
│ any purpose with or without fee is hereby granted, provided that the │
|
|
|
|
|
│ above copyright notice and this permission notice appear in all copies. │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
|
|
|
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
|
|
|
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
|
|
|
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
|
|
|
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
|
|
|
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
|
|
|
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
|
|
|
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
╠──────────────────────────────────────────────────────────────────────────────╣
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
|
|
|
|
|
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
|
|
|
|
|
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
|
|
|
|
|
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
|
2021-02-24 04:23:19 +00:00
|
|
|
|
│ αcτµαlly pδrταblε εxεcµταblε § no-frills virtual memory management │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
2021-02-24 04:23:19 +00:00
|
|
|
|
#include "ape/relocations.h"
|
2022-12-18 01:51:20 +00:00
|
|
|
|
#include "libc/assert.h"
|
2021-02-24 04:23:19 +00:00
|
|
|
|
#include "libc/elf/def.h"
|
|
|
|
|
#include "libc/elf/struct/phdr.h"
|
2021-03-01 07:42:35 +00:00
|
|
|
|
#include "libc/macros.internal.h"
|
2021-02-24 04:23:19 +00:00
|
|
|
|
#include "libc/nexgen32e/uart.internal.h"
|
|
|
|
|
#include "libc/runtime/e820.internal.h"
|
|
|
|
|
#include "libc/runtime/metalprintf.internal.h"
|
|
|
|
|
#include "libc/runtime/pc.internal.h"
|
|
|
|
|
#include "libc/runtime/runtime.h"
|
2023-05-02 02:43:59 +00:00
|
|
|
|
#ifdef __x86_64__
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2022-12-18 01:51:20 +00:00
|
|
|
|
#define INVERT(x) (BANE + PHYSICAL(x))
|
2023-04-27 03:45:01 +00:00
|
|
|
|
#define NOPAGE ((uint64_t)-1)
|
2022-12-18 01:51:20 +00:00
|
|
|
|
|
|
|
|
|
struct ReclaimedPage {
|
|
|
|
|
uint64_t next;
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/**
|
2021-02-24 04:23:19 +00:00
|
|
|
|
* Allocates new page of physical memory.
|
2020-06-15 14:18:57 +00:00
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan texthead uint64_t __new_page(struct mman *mm) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
uint64_t p = mm->frp;
|
|
|
|
|
if (p != NOPAGE) {
|
|
|
|
|
uint64_t q;
|
|
|
|
|
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p);
|
2023-07-26 20:54:49 +00:00
|
|
|
|
unassert(p == (p & PAGE_TA));
|
2022-12-18 01:51:20 +00:00
|
|
|
|
q = rp->next;
|
2023-07-26 20:54:49 +00:00
|
|
|
|
unassert(q == (q & PAGE_TA) || q == NOPAGE);
|
2022-12-18 01:51:20 +00:00
|
|
|
|
mm->frp = q;
|
|
|
|
|
return p;
|
|
|
|
|
}
|
2021-02-24 04:23:19 +00:00
|
|
|
|
if (mm->pdpi == mm->e820n) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
while (mm->pdp >= mm->e820[mm->pdpi].addr + mm->e820[mm->pdpi].size) {
|
|
|
|
|
if (++mm->pdpi == mm->e820n) return 0;
|
2022-12-18 01:51:20 +00:00
|
|
|
|
mm->pdp = MAX(mm->pdp, mm->e820[mm->pdpi].addr);
|
2021-02-24 04:23:19 +00:00
|
|
|
|
}
|
|
|
|
|
p = mm->pdp;
|
|
|
|
|
mm->pdp += 4096;
|
|
|
|
|
return p;
|
|
|
|
|
}
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2021-02-24 04:23:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns pointer to page table entry for page at virtual address.
|
|
|
|
|
* Additional page tables are allocated if needed as a side-effect.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan textreal uint64_t *__get_virtual(struct mman *mm, uint64_t *t,
|
|
|
|
|
int64_t vaddr, bool maketables) {
|
2021-02-24 04:23:19 +00:00
|
|
|
|
uint64_t *e, p;
|
|
|
|
|
unsigned char h;
|
|
|
|
|
for (h = 39;; h -= 9) {
|
|
|
|
|
e = t + ((vaddr >> h) & 511);
|
|
|
|
|
if (h == 12) return e;
|
2022-10-12 18:07:11 +00:00
|
|
|
|
if (!(*e & (PAGE_V | PAGE_RSRV))) {
|
2021-02-24 04:23:19 +00:00
|
|
|
|
if (!maketables) return NULL;
|
|
|
|
|
if (!(p = __new_page(mm))) return NULL;
|
2022-09-13 09:01:49 +00:00
|
|
|
|
__clear_page(BANE + p);
|
2021-02-24 04:23:19 +00:00
|
|
|
|
*e = p | PAGE_V | PAGE_RW;
|
|
|
|
|
}
|
|
|
|
|
t = (uint64_t *)(BANE + (*e & PAGE_TA));
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2021-02-24 04:23:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sorts, rounds, and filters BIOS memory map.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
static dontasan textreal void __normalize_e820(struct mman *mm, uint64_t top) {
|
2021-02-24 04:23:19 +00:00
|
|
|
|
uint64_t a, b;
|
|
|
|
|
uint64_t x, y;
|
|
|
|
|
unsigned i, j, n;
|
|
|
|
|
for (n = i = 0; mm->e820[i].size; ++i) {
|
|
|
|
|
mm->e820[n] = mm->e820[i];
|
|
|
|
|
x = mm->e820[n].addr;
|
|
|
|
|
y = mm->e820[n].addr + mm->e820[n].size;
|
|
|
|
|
a = ROUNDUP(x, 4096);
|
2022-09-16 04:09:29 +00:00
|
|
|
|
b = ROUNDDOWN(y, 4096);
|
|
|
|
|
if (b > a && mm->e820[i].type == kMemoryUsable) {
|
|
|
|
|
b -= a;
|
2021-02-24 04:23:19 +00:00
|
|
|
|
mm->e820[n].addr = a;
|
|
|
|
|
mm->e820[n].size = b;
|
|
|
|
|
++n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (i = 1; i < n; ++i) {
|
|
|
|
|
for (j = i; j > 0 && mm->e820[i].addr < mm->e820[j - 1].addr; --j) {
|
|
|
|
|
mm->e820[j] = mm->e820[j - 1];
|
|
|
|
|
}
|
|
|
|
|
mm->e820[j] = mm->e820[i];
|
|
|
|
|
}
|
2022-12-18 01:51:20 +00:00
|
|
|
|
top = ROUNDUP(top, 4096);
|
|
|
|
|
mm->pdp = MAX(top, mm->e820[0].addr);
|
2021-02-24 04:23:19 +00:00
|
|
|
|
mm->pdpi = 0;
|
|
|
|
|
mm->e820n = n;
|
2022-12-18 01:51:20 +00:00
|
|
|
|
mm->frp = NOPAGE;
|
2021-02-24 04:23:19 +00:00
|
|
|
|
}
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2022-10-02 08:50:16 +00:00
|
|
|
|
/**
|
|
|
|
|
* Identity maps an area of physical memory to its negative address.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan textreal uint64_t *__invert_memory_area(struct mman *mm,
|
|
|
|
|
uint64_t *pml4t, uint64_t ps,
|
|
|
|
|
uint64_t size,
|
|
|
|
|
uint64_t pte_flags) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
uint64_t pe = ps + size, p, *m = NULL;
|
2022-10-02 08:50:16 +00:00
|
|
|
|
ps = ROUNDDOWN(ps, 4096);
|
|
|
|
|
pe = ROUNDUP(pe, 4096);
|
|
|
|
|
for (p = ps; p != pe; p += 4096) {
|
|
|
|
|
m = __get_virtual(mm, pml4t, BANE + p, true);
|
2022-10-12 18:07:11 +00:00
|
|
|
|
if (m && !(*m & (PAGE_V | PAGE_RSRV))) {
|
|
|
|
|
*m = p | PAGE_V | PAGE_RSRV | pte_flags;
|
2022-10-02 08:50:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-18 01:51:20 +00:00
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Increments the reference count for a page of physical memory.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan void __ref_page(struct mman *mm, uint64_t *pml4t, uint64_t p) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
uint64_t *m, e;
|
|
|
|
|
m = __invert_memory_area(mm, pml4t, p, 4096, PAGE_RW | PAGE_XD);
|
|
|
|
|
if (m) {
|
|
|
|
|
e = *m;
|
|
|
|
|
if ((e & PAGE_REFC) != PAGE_REFC) {
|
|
|
|
|
e += PAGE_1REF;
|
|
|
|
|
*m = e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Increments the reference counts for an area of physical memory.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan void __ref_pages(struct mman *mm, uint64_t *pml4t, uint64_t ps,
|
|
|
|
|
uint64_t size) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
uint64_t p = ROUNDDOWN(ps, 4096), e = ROUNDUP(ps + size, 4096);
|
|
|
|
|
while (p != e) {
|
|
|
|
|
__ref_page(mm, pml4t, p);
|
|
|
|
|
p += 4096;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reclaims a page of physical memory for later use.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
static dontasan void __reclaim_page(struct mman *mm, uint64_t p) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p);
|
2023-07-26 20:54:49 +00:00
|
|
|
|
unassert(p == (p & PAGE_TA));
|
2022-12-18 01:51:20 +00:00
|
|
|
|
rp->next = mm->frp;
|
|
|
|
|
mm->frp = p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Decrements the reference count for a page of physical memory. Frees the
|
|
|
|
|
* page if there are no virtual addresses (excluding the negative space)
|
|
|
|
|
* referring to it.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan void __unref_page(struct mman *mm, uint64_t *pml4t, uint64_t p) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
uint64_t *m, e;
|
|
|
|
|
m = __invert_memory_area(mm, pml4t, p, 4096, PAGE_RW | PAGE_XD);
|
|
|
|
|
if (m) {
|
|
|
|
|
e = *m;
|
|
|
|
|
if ((e & PAGE_REFC) != PAGE_REFC) {
|
|
|
|
|
e -= PAGE_1REF;
|
|
|
|
|
*m = e;
|
|
|
|
|
if ((e & PAGE_REFC) == 0) __reclaim_page(mm, p);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-02 08:50:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 04:23:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Identity maps all usable physical memory to its negative address.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
static dontasan textreal void __invert_memory(struct mman *mm,
|
|
|
|
|
uint64_t *pml4t) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
uint64_t i;
|
2021-02-24 04:23:19 +00:00
|
|
|
|
for (i = 0; i < mm->e820n; ++i) {
|
2022-10-02 08:50:16 +00:00
|
|
|
|
uint64_t ps = mm->e820[i].addr, size = mm->e820[i].size;
|
|
|
|
|
/* ape/ape.S has already mapped the first 2 MiB of physical memory. */
|
2022-11-02 05:36:03 +00:00
|
|
|
|
if (ps < 0x200000 && ps + size <= 0x200000) continue;
|
2022-10-12 18:07:11 +00:00
|
|
|
|
__invert_memory_area(mm, pml4t, ps, size, PAGE_RW | PAGE_XD);
|
2021-02-24 04:23:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-18 09:54:55 +00:00
|
|
|
|
/**
|
|
|
|
|
* Exports information about the offset of a field within a structure type,
|
|
|
|
|
* so that assembly language routines can use it. This macro can be invoked
|
|
|
|
|
* from inside a function whose code is known to be emitted.
|
|
|
|
|
*/
|
2022-11-02 05:36:03 +00:00
|
|
|
|
#define export_offsetof(type, member) \
|
|
|
|
|
do { \
|
|
|
|
|
asm volatile(".globl \"" #type "::" #member "\"\n\t" \
|
|
|
|
|
".set \"" #type "::" #member "\",%c0" \
|
|
|
|
|
: /* no outputs */ \
|
|
|
|
|
: "i"(offsetof(type, member))); \
|
|
|
|
|
} while (0)
|
2022-09-18 09:54:55 +00:00
|
|
|
|
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan textreal void __setup_mman(struct mman *mm, uint64_t *pml4t,
|
|
|
|
|
uint64_t top) {
|
2022-09-18 09:54:55 +00:00
|
|
|
|
export_offsetof(struct mman, pc_drive_base_table);
|
|
|
|
|
export_offsetof(struct mman, pc_drive_last_sector);
|
|
|
|
|
export_offsetof(struct mman, pc_drive_last_head);
|
2022-12-18 01:51:20 +00:00
|
|
|
|
export_offsetof(struct mman, pc_drive);
|
2022-09-18 09:54:55 +00:00
|
|
|
|
export_offsetof(struct mman, e820);
|
|
|
|
|
export_offsetof(struct mman, e820_end);
|
|
|
|
|
export_offsetof(struct mman, bad_idt);
|
2022-12-18 01:51:20 +00:00
|
|
|
|
export_offsetof(struct mman, pc_drive_next_sector);
|
|
|
|
|
export_offsetof(struct mman, pc_drive_next_cylinder);
|
|
|
|
|
export_offsetof(struct mman, pc_drive_next_head);
|
2022-10-02 08:50:16 +00:00
|
|
|
|
export_offsetof(struct mman, pc_video_type);
|
|
|
|
|
export_offsetof(struct mman, pc_video_stride);
|
|
|
|
|
export_offsetof(struct mman, pc_video_width);
|
|
|
|
|
export_offsetof(struct mman, pc_video_height);
|
|
|
|
|
export_offsetof(struct mman, pc_video_framebuffer);
|
|
|
|
|
export_offsetof(struct mman, pc_video_framebuffer_size);
|
2022-10-06 12:36:15 +00:00
|
|
|
|
export_offsetof(struct mman, pc_video_curs_info);
|
|
|
|
|
export_offsetof(struct mman, pc_video_char_height);
|
2022-12-18 01:51:20 +00:00
|
|
|
|
__normalize_e820(mm, top);
|
2021-02-24 04:23:19 +00:00
|
|
|
|
__invert_memory(mm, pml4t);
|
|
|
|
|
}
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2021-02-24 04:23:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Maps APE-defined ELF program headers into memory and clears BSS.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan textreal void __map_phdrs(struct mman *mm, uint64_t *pml4t, uint64_t b,
|
|
|
|
|
uint64_t top) {
|
2023-09-02 03:49:13 +00:00
|
|
|
|
uint64_t i, f, v, m;
|
2021-02-24 04:23:19 +00:00
|
|
|
|
struct Elf64_Phdr *p;
|
|
|
|
|
extern char ape_phdrs[] __attribute__((__weak__));
|
|
|
|
|
extern char ape_phdrs_end[] __attribute__((__weak__));
|
2022-12-18 01:51:20 +00:00
|
|
|
|
__setup_mman(mm, pml4t, top);
|
|
|
|
|
for (p = (struct Elf64_Phdr *)INVERT(ape_phdrs), m = 0;
|
|
|
|
|
p < (struct Elf64_Phdr *)INVERT(ape_phdrs_end); ++p) {
|
2021-02-24 04:23:19 +00:00
|
|
|
|
if (p->p_type == PT_LOAD || p->p_type == PT_GNU_STACK) {
|
2022-10-12 18:07:11 +00:00
|
|
|
|
f = PAGE_RSRV | PAGE_U;
|
|
|
|
|
if (p->p_flags & PF_W)
|
|
|
|
|
f |= PAGE_V | PAGE_RW;
|
|
|
|
|
else if (p->p_flags & (PF_R | PF_X))
|
|
|
|
|
f |= PAGE_V;
|
|
|
|
|
if (!(p->p_flags & PF_X)) f |= PAGE_XD;
|
2021-02-24 04:23:19 +00:00
|
|
|
|
for (i = 0; i < p->p_memsz; i += 4096) {
|
|
|
|
|
if (i < p->p_filesz) {
|
|
|
|
|
v = b + p->p_offset + i;
|
|
|
|
|
m = MAX(m, v);
|
|
|
|
|
} else {
|
2022-09-13 09:01:49 +00:00
|
|
|
|
v = __clear_page(BANE + __new_page(mm));
|
2021-02-24 04:23:19 +00:00
|
|
|
|
}
|
|
|
|
|
*__get_virtual(mm, pml4t, p->p_vaddr + i, true) = (v & PAGE_TA) | f;
|
2022-12-18 01:51:20 +00:00
|
|
|
|
__ref_page(mm, pml4t, v & PAGE_TA);
|
2021-02-24 04:23:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mm->pdp = MAX(mm->pdp, m);
|
|
|
|
|
}
|
2022-12-18 01:51:20 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reclaims memory pages which were used at boot time but which can now be
|
|
|
|
|
* made available for the application.
|
|
|
|
|
*/
|
2023-07-26 20:54:49 +00:00
|
|
|
|
dontasan textreal void __reclaim_boot_pages(struct mman *mm,
|
|
|
|
|
uint64_t skip_start,
|
|
|
|
|
uint64_t skip_end) {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
uint64_t p = mm->frp, q = IMAGE_BASE_REAL, i, n = mm->e820n, b, e;
|
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
|
|
b = mm->e820[i].addr;
|
|
|
|
|
if (b >= IMAGE_BASE_PHYSICAL) break;
|
|
|
|
|
e = MIN(IMAGE_BASE_PHYSICAL, b + mm->e820[i].size);
|
|
|
|
|
q = MAX(IMAGE_BASE_REAL, b);
|
|
|
|
|
while (q < e) {
|
|
|
|
|
struct ReclaimedPage *rp;
|
|
|
|
|
if (q == skip_start) {
|
|
|
|
|
q = skip_end;
|
|
|
|
|
if (q >= e) break;
|
|
|
|
|
}
|
|
|
|
|
rp = (struct ReclaimedPage *)(BANE + q);
|
|
|
|
|
rp->next = p;
|
|
|
|
|
p = q;
|
|
|
|
|
q += 4096;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mm->frp = p;
|
|
|
|
|
}
|
2023-05-02 02:43:59 +00:00
|
|
|
|
|
|
|
|
|
#endif /* __x86_64__ */
|