mirror of
https://github.com/drasko/codezero.git
synced 2026-04-30 07:31:30 +02:00
Pager works until end of init_physmem_secondary
This commit is contained in:
44
tasks/mm0/src/bootdesc.c
Normal file
44
tasks/mm0/src/bootdesc.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Reading of bootdesc forged at build time.
|
||||
*
|
||||
* Copyright (C) 2007 - 2009 Bahadir Balban
|
||||
*/
|
||||
|
||||
#include <bootdesc.h>
|
||||
#include <bootm.h>
|
||||
#include <init.h>
|
||||
#include <l4lib/arch/syslib.h>
|
||||
|
||||
extern unsigned long _end[];
|
||||
|
||||
void read_bootdesc(struct initdata *initdata)
|
||||
{
|
||||
int npages;
|
||||
struct bootdesc *bootdesc;
|
||||
|
||||
/*
|
||||
* End of the executable image is where bootdesc resides
|
||||
*/
|
||||
bootdesc = (struct bootdesc *)_end;
|
||||
|
||||
/* Check if bootdesc spans across pages, and how many */
|
||||
npages = __pfn((((unsigned long)bootdesc +
|
||||
bootdesc->desc_size)
|
||||
& ~PAGE_MASK) -
|
||||
((unsigned long)bootdesc & ~PAGE_MASK));
|
||||
|
||||
if (npages > 0)
|
||||
l4_map_helper(virt_to_phys((void *)page_align_up(_end)),
|
||||
PAGE_SIZE * npages);
|
||||
|
||||
/* Allocate bootdesc sized structure */
|
||||
initdata->bootdesc = alloc_bootmem(bootdesc->desc_size, 0);
|
||||
|
||||
/* Copy bootdesc to initdata */
|
||||
memcpy(initdata->bootdesc, bootdesc,
|
||||
bootdesc->desc_size);
|
||||
|
||||
if (npages > 0)
|
||||
l4_unmap_helper((void *)page_align_up(_end),
|
||||
PAGE_SIZE * npages);
|
||||
}
|
||||
62
tasks/mm0/src/bootm.c
Normal file
62
tasks/mm0/src/bootm.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Boot memory allocator
|
||||
*
|
||||
* Copyright (C) 2009 Bahadir Balban
|
||||
*/
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include <l4/types.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/lib/math.h>
|
||||
#include <l4/api/thread.h>
|
||||
#include <l4/api/kip.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* All memory allocated here is discarded after boot */
|
||||
|
||||
#define BOOTMEM_SIZE SZ_32K
|
||||
|
||||
SECTION(".init.bootmem") char bootmem[BOOTMEM_SIZE];
|
||||
SECTION(".init.stack") char stack[4096];
|
||||
// SECTION("init.data")
|
||||
|
||||
extern unsigned long __stack[]; /* Linker defined */
|
||||
|
||||
static unsigned long cursor = (unsigned long)&bootmem;
|
||||
|
||||
void *alloc_bootmem(int size, int alignment)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
/* If alignment is required */
|
||||
if (alignment) {
|
||||
/* And cursor is not aligned */
|
||||
if (!is_aligned(cursor, alignment))
|
||||
/* Align the cursor to alignment */
|
||||
cursor = align_up(cursor, alignment);
|
||||
/* Align to 4 byte by default */
|
||||
} else if (size >= 4) {
|
||||
/* And cursor is not aligned */
|
||||
if (!is_aligned(cursor, 4))
|
||||
/* Align the cursor to alignment */
|
||||
cursor = align_up(cursor, 4);
|
||||
}
|
||||
|
||||
/* Allocate from cursor */
|
||||
ptr = (void *)cursor;
|
||||
|
||||
/* Update cursor */
|
||||
cursor += size;
|
||||
|
||||
/* Check if cursor is passed bootmem area */
|
||||
if (cursor >= (unsigned long)&bootmem[BOOTMEM_SIZE]) {
|
||||
printk("Fatal: Insufficient boot memory.\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
62
tasks/mm0/src/capability.c
Normal file
62
tasks/mm0/src/capability.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Pager's capabilities for kernel resources
|
||||
*
|
||||
* Copyright (C) 2009 Bahadir Balban
|
||||
*/
|
||||
#include <bootm.h>
|
||||
#include <init.h>
|
||||
#include <capability.h>
|
||||
#include <l4/api/capability.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4/generic/cap-types.h> /* TODO: Move this to API */
|
||||
|
||||
extern struct cap_list capability_list;
|
||||
|
||||
__initdata static struct capability *caparray;
|
||||
|
||||
int read_kernel_capabilities(struct initdata *initdata)
|
||||
{
|
||||
int ncaps;
|
||||
int err;
|
||||
|
||||
/* Read number of capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_NCAPS, 0, &ncaps)) < 0) {
|
||||
printf("l4_capability_control() reading # of capabilities failed.\n"
|
||||
"Could not complete CAP_CONTROL_NCAPS request.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Allocate array of caps from boot memory */
|
||||
caparray = alloc_bootmem(sizeof(struct capability) * ncaps, 0);
|
||||
|
||||
/* Read all capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_READ_CAPS, 0, caparray)) < 0) {
|
||||
printf("l4_capability_control() reading of capabilities failed.\n"
|
||||
"Could not complete CAP_CONTROL_READ_CAPS request.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set up initdata pointer to important capabilities */
|
||||
initdata->bootcaps = caparray;
|
||||
for (int i = 0; i < ncaps; i++) {
|
||||
/*
|
||||
* TODO: There may be multiple physmem caps!
|
||||
* This really needs to be considered as multiple
|
||||
* membanks!!!
|
||||
*/
|
||||
if ((caparray[i].type & CAP_RTYPE_MASK)
|
||||
== CAP_RTYPE_PHYSMEM) {
|
||||
initdata->physmem = &caparray[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
printf("%s: Error, pager has no physmem capability defined.\n",
|
||||
__TASKNAME__);
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -19,10 +19,61 @@
|
||||
#include <test.h>
|
||||
#include <boot.h>
|
||||
#include <utcb.h>
|
||||
#include <bootm.h>
|
||||
|
||||
/* A separate list than the generic file list that keeps just the boot files */
|
||||
LINK_DECLARE(boot_file_list);
|
||||
|
||||
/* Kernel data acquired during initialisation */
|
||||
__initdata struct initdata initdata;
|
||||
|
||||
void print_bootdesc(struct bootdesc *bd)
|
||||
{
|
||||
for (int i = 0; i < bd->total_images; i++) {
|
||||
printf("Task Image: %d\n", i);
|
||||
printf("Name: %s\n", bd->images[i].name);
|
||||
printf("Start: 0x%x\n", bd->images[i].phys_start);
|
||||
printf("End: 0x%x\n", bd->images[i].phys_end);
|
||||
}
|
||||
}
|
||||
|
||||
void print_pfn_range(int pfn, int size)
|
||||
{
|
||||
unsigned int addr = pfn << PAGE_BITS;
|
||||
unsigned int end = (pfn + size) << PAGE_BITS;
|
||||
printf("Used: 0x%x - 0x%x\n", addr, end);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void print_page_map(struct page_bitmap *map)
|
||||
{
|
||||
unsigned int start_pfn = 0;
|
||||
unsigned int total_used = 0;
|
||||
int numpages = 0;
|
||||
|
||||
// printf("Page map: 0x%x-0x%x\n", map->pfn_start << PAGE_BITS, map->pfn_end << PAGE_BITS);
|
||||
for (int i = 0; i < (PHYSMEM_TOTAL_PAGES >> 5); i++) {
|
||||
for (int x = 0; x < WORD_BITS; x++) {
|
||||
if (map->map[i] & (1 << x)) { /* A used page found? */
|
||||
if (!start_pfn) /* First such page found? */
|
||||
start_pfn = (WORD_BITS * i) + x;
|
||||
total_used++;
|
||||
numpages++; /* Increase number of pages */
|
||||
} else { /* Either used pages ended or were never found */
|
||||
if (start_pfn) { /* We had a used page */
|
||||
/* Finished end of used range.
|
||||
* Print and reset. */
|
||||
//print_pfn_range(start_pfn, numpages);
|
||||
start_pfn = 0;
|
||||
numpages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%s: Pagemap: Total of %d used physical pages. %d Kbytes used.\n", __TASKNAME__, total_used, total_used << 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A specialised function for setting up the task environment of mm0.
|
||||
* Essentially all the memory regions are set up but a new task isn't
|
||||
@@ -160,7 +211,10 @@ int start_boot_tasks(struct initdata *initdata)
|
||||
void init_mm(struct initdata *initdata)
|
||||
{
|
||||
/* Initialise the page and bank descriptors */
|
||||
init_physmem(initdata, membank);
|
||||
init_physmem_primary(initdata);
|
||||
|
||||
init_physmem_secondary(initdata, membank);
|
||||
|
||||
// printf("%s: Initialised physmem.\n", __TASKNAME__);
|
||||
|
||||
/* Initialise the page allocator on first bank. */
|
||||
@@ -190,14 +244,14 @@ void init_mm(struct initdata *initdata)
|
||||
pager_address_pool_init();
|
||||
|
||||
// printf("%s: Initialised utcb address pool.\n", __TASKNAME__);
|
||||
|
||||
/* Give the kernel some memory to use for its allocators */
|
||||
l4_kmem_control(__pfn(alloc_page(__pfn(SZ_1MB))), __pfn(SZ_1MB), 1);
|
||||
}
|
||||
|
||||
void initialise(void)
|
||||
|
||||
void init_pager(void)
|
||||
{
|
||||
request_initdata(&initdata);
|
||||
read_kernel_capabilities(&initdata);
|
||||
|
||||
read_bootdesc(&initdata);
|
||||
|
||||
init_mm(&initdata);
|
||||
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Requesting system information from kernel during init.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <init.h>
|
||||
#include INC_API(kip.h)
|
||||
#include <lib/malloc.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
|
||||
/* Kernel data acquired during initialisation */
|
||||
struct initdata initdata;
|
||||
#define BOOTDESC_PREALLOC_SIZE 128
|
||||
static char bootdesc_memory[BOOTDESC_PREALLOC_SIZE]; /* 128 bytes */
|
||||
|
||||
void print_bootdesc(struct bootdesc *bd)
|
||||
{
|
||||
for (int i = 0; i < bd->total_images; i++) {
|
||||
printf("Task Image: %d\n", i);
|
||||
printf("Name: %s\n", bd->images[i].name);
|
||||
printf("Start: 0x%x\n", bd->images[i].phys_start);
|
||||
printf("End: 0x%x\n", bd->images[i].phys_end);
|
||||
}
|
||||
}
|
||||
|
||||
void print_pfn_range(int pfn, int size)
|
||||
{
|
||||
unsigned int addr = pfn << PAGE_BITS;
|
||||
unsigned int end = (pfn + size) << PAGE_BITS;
|
||||
printf("Used: 0x%x - 0x%x\n", addr, end);
|
||||
}
|
||||
|
||||
void print_page_map(struct page_bitmap *map)
|
||||
{
|
||||
unsigned int start_pfn = 0;
|
||||
unsigned int total_used = 0;
|
||||
int numpages = 0;
|
||||
|
||||
// printf("Page map: 0x%x-0x%x\n", map->pfn_start << PAGE_BITS, map->pfn_end << PAGE_BITS);
|
||||
for (int i = 0; i < (PHYSMEM_TOTAL_PAGES >> 5); i++) {
|
||||
for (int x = 0; x < WORD_BITS; x++) {
|
||||
if (map->map[i] & (1 << x)) { /* A used page found? */
|
||||
if (!start_pfn) /* First such page found? */
|
||||
start_pfn = (WORD_BITS * i) + x;
|
||||
total_used++;
|
||||
numpages++; /* Increase number of pages */
|
||||
} else { /* Either used pages ended or were never found */
|
||||
if (start_pfn) { /* We had a used page */
|
||||
/* Finished end of used range.
|
||||
* Print and reset. */
|
||||
//print_pfn_range(start_pfn, numpages);
|
||||
start_pfn = 0;
|
||||
numpages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%s: Pagemap: Total of %d used physical pages. %d Kbytes used.\n", __TASKNAME__, total_used, total_used << 2);
|
||||
}
|
||||
|
||||
|
||||
int request_initdata(struct initdata *initdata)
|
||||
{
|
||||
int err;
|
||||
int bootdesc_size;
|
||||
|
||||
/* Read all used physical page information in a bitmap. */
|
||||
if ((err = l4_kread(KDATA_PAGE_MAP, &initdata->page_map)) < 0) {
|
||||
printf("L4_kdata_read() call failed. Could not complete"
|
||||
"KDATA_PAGE_MAP request.\n");
|
||||
goto error;
|
||||
}
|
||||
print_page_map(&initdata->page_map);
|
||||
|
||||
/* Read the boot descriptor size */
|
||||
if ((err = l4_kread(KDATA_BOOTDESC_SIZE, &bootdesc_size)) < 0) {
|
||||
printf("L4_kdata_read() call failed. Could not complete"
|
||||
"KDATA_BOOTDESC_SIZE request.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bootdesc_size > BOOTDESC_PREALLOC_SIZE) {
|
||||
printf("Insufficient preallocated memory for bootdesc. "
|
||||
"Size too big.\n");
|
||||
goto error;
|
||||
}
|
||||
/* Get preallocated bootdesc memory */
|
||||
initdata->bootdesc = (struct bootdesc *)&bootdesc_memory;
|
||||
|
||||
/* Read the boot descriptor */
|
||||
if ((err = l4_kread(KDATA_BOOTDESC, initdata->bootdesc)) < 0) {
|
||||
printf("L4_kdata_read() call failed. Could not complete"
|
||||
"KDATA_BOOTDESC request.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
printf("FATAL: Inittask failed during initialisation. exiting.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#include <file.h>
|
||||
#include <user.h>
|
||||
|
||||
struct membank membank[1];
|
||||
struct page *page_array;
|
||||
|
||||
struct address_pool pager_vaddr_pool;
|
||||
|
||||
@@ -32,69 +30,6 @@ void *virt_to_phys(void *addr)
|
||||
return addr - INITTASK_OFFSET;
|
||||
}
|
||||
|
||||
/* Allocates page descriptors and initialises them using page_map information */
|
||||
void init_physmem(struct initdata *initdata, struct membank *membank)
|
||||
{
|
||||
struct page_bitmap *pmap = &initdata->page_map;
|
||||
int npages = pmap->pfn_end - pmap->pfn_start;
|
||||
|
||||
/* Allocation marks for the struct page array */
|
||||
int pg_npages, pg_spfn, pg_epfn;
|
||||
unsigned long ffree_addr;
|
||||
|
||||
/*
|
||||
* Means the page array won't map one to one to pfns. That's ok,
|
||||
* but we dont allow it for now.
|
||||
*/
|
||||
BUG_ON(pmap->pfn_start);
|
||||
|
||||
membank[0].start = __pfn_to_addr(pmap->pfn_start);
|
||||
membank[0].end = __pfn_to_addr(pmap->pfn_end);
|
||||
|
||||
/* First find the first free page after last used page */
|
||||
for (int i = 0; i < npages; i++)
|
||||
if ((pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].free = (i + 1) * PAGE_SIZE;
|
||||
BUG_ON(membank[0].free >= membank[0].end);
|
||||
|
||||
/*
|
||||
* One struct page for every physical page. Calculate how many pages
|
||||
* needed for page structs, start and end pfn marks.
|
||||
*/
|
||||
pg_npages = __pfn((sizeof(struct page) * npages));
|
||||
|
||||
/* These are relative pfn offsets to the start of the memory bank */
|
||||
pg_spfn = __pfn(membank[0].free) - __pfn(membank[0].start);
|
||||
pg_epfn = pg_spfn + pg_npages;
|
||||
|
||||
/* Use free pages from the bank as the space for struct page array */
|
||||
membank[0].page_array = l4_map_helper((void *)membank[0].free,
|
||||
pg_npages);
|
||||
/* Update free memory left */
|
||||
membank[0].free += pg_npages * PAGE_SIZE;
|
||||
|
||||
/* Update page bitmap for the pages used for the page array */
|
||||
for (int i = pg_spfn; i < pg_epfn; i++)
|
||||
pmap->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
|
||||
/* Initialise the page array */
|
||||
for (int i = 0; i < npages; i++) {
|
||||
link_init(&membank[0].page_array[i].list);
|
||||
|
||||
/* Set use counts for pages the kernel has already used up */
|
||||
if (!(pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].page_array[i].refcnt = -1;
|
||||
else /* Last page used +1 is free */
|
||||
ffree_addr = (i + 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* First free address must come up the same for both */
|
||||
BUG_ON(ffree_addr != membank[0].free);
|
||||
|
||||
/* Set global page array to this bank's array */
|
||||
page_array = membank[0].page_array;
|
||||
}
|
||||
|
||||
/* Maps a page from a vm_file to the pager's address space */
|
||||
void *pager_map_page(struct vm_file *f, unsigned long page_offset)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <globals.h>
|
||||
#include <file.h>
|
||||
#include <init.h>
|
||||
#include INC_ARCH(bootdesc.h)
|
||||
#include <l4/api/errno.h>
|
||||
|
||||
struct page *page_init(struct page *page)
|
||||
|
||||
166
tasks/mm0/src/physmem.c
Normal file
166
tasks/mm0/src/physmem.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Global physical memory descriptions.
|
||||
*
|
||||
* Copyright (C) 2007 - 2009 Bahadir Balban
|
||||
*/
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include <l4/types.h>
|
||||
#include <l4/lib/list.h>
|
||||
#include <l4/lib/math.h>
|
||||
#include <l4/api/thread.h>
|
||||
#include <l4/api/kip.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <stdio.h>
|
||||
#include <init.h>
|
||||
#include <physmem.h>
|
||||
|
||||
struct page_bitmap page_map; /* Bitmap of used/unused pages at bootup */
|
||||
struct memdesc physmem; /* Initial, primitive memory descriptor */
|
||||
struct membank membank[1]; /* The memory bank */
|
||||
struct page *page_array; /* The physical page array based on mem bank */
|
||||
|
||||
|
||||
static void init_page_map(unsigned long pfn_start, unsigned long pfn_end)
|
||||
{
|
||||
page_map.pfn_start = pfn_start;
|
||||
page_map.pfn_end = pfn_end;
|
||||
set_page_map(&page_map, pfn_start, pfn_end - pfn_start, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Marks pages in the global page_map as used or unused.
|
||||
*
|
||||
* @start = start page address to set, inclusive.
|
||||
* @numpages = number of pages to set.
|
||||
*/
|
||||
int set_page_map(struct page_bitmap *page_map, unsigned long pfn_start,
|
||||
int numpages, int val)
|
||||
{
|
||||
unsigned long pfn_end = pfn_start + numpages;
|
||||
unsigned long pfn_err = 0;
|
||||
|
||||
if (page_map->pfn_start > pfn_start || page_map->pfn_end < pfn_start) {
|
||||
pfn_err = pfn_start;
|
||||
goto error;
|
||||
}
|
||||
if (page_map->pfn_end < pfn_end || page_map->pfn_start > pfn_end) {
|
||||
pfn_err = pfn_end;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (val)
|
||||
for (int i = pfn_start; i < pfn_end; i++)
|
||||
page_map->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
else
|
||||
for (int i = pfn_start; i < pfn_end; i++)
|
||||
page_map->map[BITWISE_GETWORD(i)] &= ~BITWISE_GETBIT(i);
|
||||
return 0;
|
||||
error:
|
||||
BUG_MSG("Given page area is out of system page_map range: 0x%lx\n",
|
||||
pfn_err << PAGE_BITS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocates page descriptors and initialises them using page_map information */
|
||||
void init_physmem_secondary(struct initdata *initdata, struct membank *membank)
|
||||
{
|
||||
struct page_bitmap *pmap = initdata->page_map;
|
||||
int npages = pmap->pfn_end - pmap->pfn_start;
|
||||
|
||||
/* Allocation marks for the struct page array; npages, start, end */
|
||||
int pg_npages, pg_spfn, pg_epfn;
|
||||
unsigned long ffree_addr;
|
||||
|
||||
/*
|
||||
* Means the page array won't map one to one to pfns. That's ok,
|
||||
* but we dont allow it for now.
|
||||
*/
|
||||
// BUG_ON(pmap->pfn_start);
|
||||
|
||||
membank[0].start = __pfn_to_addr(pmap->pfn_start);
|
||||
membank[0].end = __pfn_to_addr(pmap->pfn_end);
|
||||
|
||||
/* First find the first free page after last used page */
|
||||
for (int i = 0; i < npages; i++)
|
||||
if ((pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].free = (i + 1) * PAGE_SIZE;
|
||||
BUG_ON(membank[0].free >= membank[0].end);
|
||||
|
||||
/*
|
||||
* One struct page for every physical page. Calculate how many pages
|
||||
* needed for page structs, start and end pfn marks.
|
||||
*/
|
||||
pg_npages = __pfn(page_align_up((sizeof(struct page) * npages)));
|
||||
|
||||
/* These are relative pfn offsets to the start of the memory bank */
|
||||
|
||||
/* FIXME:
|
||||
* 1.) These values were only right when membank started from pfn 0.
|
||||
* 2.) Use set_page_map to set page map below instead of manually.
|
||||
*/
|
||||
pg_spfn = __pfn(membank[0].free);
|
||||
pg_epfn = pg_spfn + pg_npages;
|
||||
|
||||
/* Use free pages from the bank as the space for struct page array */
|
||||
membank[0].page_array = l4_map_helper((void *)membank[0].free,
|
||||
pg_npages);
|
||||
/* Update free memory left */
|
||||
membank[0].free += pg_npages * PAGE_SIZE;
|
||||
|
||||
/* Update page bitmap for the pages used for the page array */
|
||||
for (int i = pg_spfn; i < pg_epfn; i++)
|
||||
pmap->map[BITWISE_GETWORD(i)] |= BITWISE_GETBIT(i);
|
||||
|
||||
/* Initialise the page array */
|
||||
for (int i = 0; i < npages; i++) {
|
||||
link_init(&membank[0].page_array[i].list);
|
||||
|
||||
/* Set use counts for pages the kernel has already used up */
|
||||
if (!(pmap->map[BITWISE_GETWORD(i)] & BITWISE_GETBIT(i)))
|
||||
membank[0].page_array[i].refcnt = -1;
|
||||
else /* Last page used +1 is free */
|
||||
ffree_addr = (i + 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* First free address must come up the same for both */
|
||||
BUG_ON(ffree_addr != membank[0].free);
|
||||
|
||||
/* Set global page array to this bank's array */
|
||||
page_array = membank[0].page_array;
|
||||
}
|
||||
|
||||
|
||||
/* Fills in the physmem structure with free physical memory information */
|
||||
void init_physmem_primary(struct initdata *initdata)
|
||||
{
|
||||
unsigned long pfn_start, pfn_end, pfn_images_end = 0;
|
||||
struct bootdesc *bootdesc = initdata->bootdesc;
|
||||
|
||||
/* Initialise page map from physmem capability */
|
||||
init_page_map(initdata->physmem->start,
|
||||
initdata->physmem->end);
|
||||
|
||||
/* Set initdata pointer to initialized page map */
|
||||
initdata->page_map = &page_map;
|
||||
|
||||
/* Mark pager and other boot task areas as used */
|
||||
for (int i = 0; i < bootdesc->total_images; i++) {
|
||||
pfn_start = __pfn(page_align_up(bootdesc->images[i].phys_start));
|
||||
pfn_end = __pfn(page_align_up(bootdesc->images[i].phys_end));
|
||||
if (pfn_end > pfn_images_end)
|
||||
pfn_images_end = pfn_end;
|
||||
set_page_map(&page_map, pfn_start, pfn_end - pfn_start, 1);
|
||||
}
|
||||
|
||||
physmem.start = initdata->physmem->start;
|
||||
physmem.end = initdata->physmem->end;
|
||||
|
||||
physmem.free_cur = pfn_images_end;
|
||||
physmem.free_end = physmem.end;
|
||||
physmem.numpages = __pfn(physmem.end - physmem.start);
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* TODO: This is to be used when moving mm0's temporary
|
||||
* stack to a proper place. It's unused for now.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <l4/config.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/types.h>
|
||||
#include INC_GLUE(memlayout.h)
|
||||
#include <string.h>
|
||||
|
||||
/* The initial temporary stack used until memory is set up */
|
||||
__attribute__ ((section("init.stack"))) char stack[4096];
|
||||
extern unsigned long __stack[]; /* Linker defined */
|
||||
|
||||
/* Moves from temporary stack to where it should be in actual. */
|
||||
void move_stack()
|
||||
{
|
||||
register unsigned int sp asm("sp");
|
||||
register unsigned int fp asm("r11");
|
||||
|
||||
unsigned int stack_offset = (unsigned long)__stack - sp;
|
||||
unsigned int frame_offset = (unsigned long)__stack - fp;
|
||||
|
||||
/* Copy current stack into new stack. NOTE: This might demand-page
|
||||
* the new stack, but maybe that won't work. */
|
||||
memcpy((void *)USER_AREA_END, __stack, stack_offset);
|
||||
sp = USER_AREA_END - stack_offset;
|
||||
fp = USER_AREA_END - frame_offset;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user