From 02a3f1ac9185884a113d96a360721868066b600f Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sun, 9 Aug 2009 17:22:13 +0300 Subject: [PATCH] Pager works until end of init_physmem_secondary --- include/l4/api/capability.h | 4 + include/l4/generic/physmem.h | 45 ----- include/l4/generic/tcb.h | 6 + include/l4/glue/arm/memory.h | 1 - src/api/capability.c | 95 ++++++---- src/arch/arm/SConscript | 2 +- src/arch/arm/bootdesc.c | 46 ----- src/generic/SConscript | 2 +- src/generic/container.c | 25 ++- src/generic/physmem.c | 93 ---------- src/glue/arm/init.c | 2 - src/glue/arm/memory.c | 1 - tasks/fs0/include/kdata.h | 24 --- tasks/fs0/main.c | 1 - tasks/fs0/src/init.c | 3 +- tasks/fs0/src/kdata.c | 63 ------- .../arch/arm => tasks/mm0/include}/bootdesc.h | 8 +- tasks/mm0/include/bootm.h | 9 + tasks/mm0/include/capability.h | 41 +++++ tasks/mm0/include/init.h | 13 +- tasks/mm0/include/linker.lds | 19 +- tasks/mm0/include/memory.h | 9 +- tasks/mm0/include/physmem.h | 45 +++++ tasks/mm0/main.c | 2 +- tasks/mm0/src/bootdesc.c | 44 +++++ tasks/mm0/src/bootm.c | 62 +++++++ tasks/mm0/src/capability.c | 62 +++++++ tasks/mm0/src/init.c | 66 ++++++- tasks/mm0/src/kdata.c | 105 ----------- tasks/mm0/src/memory.c | 65 ------- tasks/mm0/src/pagers.c | 1 - tasks/mm0/src/physmem.c | 166 ++++++++++++++++++ tasks/mm0/src/stack.c | 33 ---- 33 files changed, 607 insertions(+), 556 deletions(-) delete mode 100644 include/l4/generic/physmem.h delete mode 100644 src/arch/arm/bootdesc.c delete mode 100644 src/generic/physmem.c delete mode 100644 tasks/fs0/include/kdata.h delete mode 100644 tasks/fs0/src/kdata.c rename {include/l4/arch/arm => tasks/mm0/include}/bootdesc.h (76%) create mode 100644 tasks/mm0/include/bootm.h create mode 100644 tasks/mm0/include/capability.h create mode 100644 tasks/mm0/include/physmem.h create mode 100644 tasks/mm0/src/bootdesc.c create mode 100644 tasks/mm0/src/bootm.c create mode 100644 tasks/mm0/src/capability.c delete mode 100644 tasks/mm0/src/kdata.c create mode 100644 tasks/mm0/src/physmem.c delete mode 100644 tasks/mm0/src/stack.c diff --git a/include/l4/api/capability.h b/include/l4/api/capability.h index 636d3f3..ba1933a 100644 --- a/include/l4/api/capability.h +++ b/include/l4/api/capability.h @@ -6,4 +6,8 @@ #ifndef __API_CAPABILITY_H__ #define __API_CAPABILITY_H__ +/* Capability syscall request types */ +#define CAP_CONTROL_NCAPS 0 +#define CAP_CONTROL_READ_CAPS 1 + #endif /* __API_CAPABILITY_H__ */ diff --git a/include/l4/generic/physmem.h b/include/l4/generic/physmem.h deleted file mode 100644 index 9a4b9c3..0000000 --- a/include/l4/generic/physmem.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Boot time memory initialisation and memory allocator interface. - * - * Copyright (C) 2007 Bahadir Balban - * - */ -#ifndef __GENERIC_PHYSMEM_H__ -#define __GENERIC_PHYSMEM_H__ - -#include -#include INC_PLAT(offsets.h) -#include INC_GLUE(memory.h) - -#define PHYSMEM_TOTAL_PAGES ((PHYS_MEM_END - PHYS_MEM_START) >> PAGE_BITS) - -/* A compact memory descriptor to determine used/unused pages in the system */ -struct page_bitmap { - unsigned long pfn_start; - unsigned long pfn_end; - unsigned int map[PHYSMEM_TOTAL_PAGES >> 5]; -}; - -/* Describes a portion of physical memory. */ -struct memdesc { - unsigned int start; - unsigned int end; - unsigned int free_cur; - unsigned int free_end; - unsigned int numpages; -}; - -#if defined(__KERNEL__) -/* Describes bitmap of used/unused state for all physical pages */ -extern struct page_bitmap page_map; -extern struct memdesc physmem; -#endif - -/* Sets the global page map as used/unused. Aligns input when needed. */ -int set_page_map(unsigned long start, int numpages, int val); - -/* Memory allocator interface */ -void physmem_init(void); -void memory_init(void); - -#endif /* __GENERIC_PHYSMEM_H__ */ diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index ea7e732..cba971c 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include INC_GLUE(memory.h) #include INC_GLUE(syscall.h) @@ -98,6 +99,11 @@ struct ktcb { /* Container */ struct container *container; + struct pager *pager; + + /* Capability list */ + struct cap_list *cap_list_ptr; + struct cap_list cap_list; /* Fields for ipc rendezvous */ struct waitqueue_head wqh_recv; diff --git a/include/l4/glue/arm/memory.h b/include/l4/glue/arm/memory.h index bb403c6..04636f8 100644 --- a/include/l4/glue/arm/memory.h +++ b/include/l4/glue/arm/memory.h @@ -7,7 +7,6 @@ #ifndef __GLUE_ARM_MEMORY_H__ #define __GLUE_ARM_MEMORY_H__ -#include INC_ARCH(bootdesc.h) /* Definition of last loaded svc image address */ #include INC_GLUE(memlayout.h) /* Important generic definitions */ #include INC_SUBARCH(mm.h) diff --git a/src/api/capability.c b/src/api/capability.c index ecac1d7..0ee2b43 100644 --- a/src/api/capability.c +++ b/src/api/capability.c @@ -8,50 +8,79 @@ */ #include -#include -#include -#include +#include +#include #include #include INC_API(syscall.h) - -/* Error-checked kernel data request call */ -int __sys_capability_control(unsigned int req, unsigned int flags, void *userbuf) +int task_read_capabilities(void *userbuf) { - int err = 0; -#if 0 + int copy_size, copy_offset = 0; + struct capability *cap; + int err; + + /* + * Currently only pagers can + * read their own capabilities + */ + if (current != current->pager->tcb) + return -EPERM; + + /* Determine size of pager capabilities */ + copy_size = current->cap_list_ptr->ncaps * sizeof(*cap); + + /* Validate user buffer for this copy size */ + if ((err = check_access((unsigned long)userbuf, copy_size, + MAP_USR_RW_FLAGS, 1)) < 0) + return err; + + /* Copy capabilities from list to buffer */ + list_foreach_struct(cap, + ¤t->cap_list_ptr->caps, + list) { + memcpy(userbuf + copy_offset, cap, sizeof(*cap)); + copy_offset += sizeof(*cap); + } + + return 0; +} + +/* + * Read, manipulate capabilities. Currently only capability read support. + */ +int sys_capability_control(unsigned int req, unsigned int flags, void *userbuf) +{ + int err; + switch(req) { - case KDATA_PAGE_MAP: - // printk("Handling KDATA_PAGE_MAP request.\n"); - if (check_access(vaddr, sizeof(page_map), MAP_USR_RW_FLAGS, 1) < 0) - return -EINVAL; - memcpy(dest, &page_map, sizeof(page_map)); + /* Return number of capabilities the thread has */ + case CAP_CONTROL_NCAPS: + if (current != current->pager->tcb) + return -EPERM; + + if ((err = check_access((unsigned long)userbuf, sizeof(int), + MAP_USR_RW_FLAGS, 1)) < 0) + return err; + + /* Copy ncaps value */ + *((int *)userbuf) = current->cap_list_ptr->ncaps; break; - case KDATA_BOOTDESC: - // printk("Handling KDATA_BOOTDESC request.\n"); - if (check_access(vaddr, bootdesc->desc_size, MAP_USR_RW_FLAGS, 1) < 0) - return -EINVAL; - memcpy(dest, bootdesc, bootdesc->desc_size); - break; - case KDATA_BOOTDESC_SIZE: - // printk("Handling KDATA_BOOTDESC_SIZE request.\n"); - if (check_access(vaddr, sizeof(unsigned int), MAP_USR_RW_FLAGS, 1) < 0) - return -EINVAL; - *(unsigned int *)dest = bootdesc->desc_size; + + /* Return all capabilities as an array of capabilities */ + case CAP_CONTROL_READ_CAPS: + err = task_read_capabilities(userbuf); break; default: - printk("Unsupported kernel data request.\n"); - err = -1; + /* Invalid request id */ + return -EINVAL; } -#endif - return err; - + return 0; } -int sys_capability_control(unsigned int req, unsigned int flags, void *userbuf) -{ - return __sys_capability_control(req, flags, userbuf); -} + + + + diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 3d752ed..57bc74f 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -4,7 +4,7 @@ Import('env') # The set of source files associated with this SConscript file. -src_local = ['head.S', 'vectors.S', 'syscall.S', 'exception.c', 'bootdesc.c'] +src_local = ['head.S', 'vectors.S', 'syscall.S', 'exception.c'] obj = env.Object(src_local) Return('obj') diff --git a/src/arch/arm/bootdesc.c b/src/arch/arm/bootdesc.c deleted file mode 100644 index c568deb..0000000 --- a/src/arch/arm/bootdesc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Reading of bootdesc forged at build time. - * - * Copyright (C) 2007 Bahadir Balban - */ - -#include -#include -#include -#include INC_ARCH(linker.h) -#include INC_ARCH(bootdesc.h) -#include INC_GLUE(memory.h) -#include INC_PLAT(printascii.h) -#include INC_SUBARCH(mm.h) - -struct bootdesc *bootdesc; - -#if 0 -void copy_bootdesc() -{ - struct bootdesc *new = kzalloc(bootdesc->desc_size); - - memcpy(new, bootdesc, bootdesc->desc_size); - remove_mapping((unsigned long)bootdesc); - bootdesc = new; -} - -void read_bootdesc(void) -{ - /* - * End of the kernel image is where bootdesc resides. Note this is - * not added to the page_map because it's meant to be discarded. - */ -// add_mapping(virt_to_phys(_end), (unsigned long)_end, PAGE_SIZE, -// MAP_USR_DEFAULT_FLAGS); - - /* Get original bootdesc */ - bootdesc = (struct bootdesc *)_end; - - /* Determine end of physical memory used by loaded images. */ - for (int i = 0; i < bootdesc->total_images; i++) - if (bootdesc->images[i].phys_end > __svc_images_end) - __svc_images_end = bootdesc->images[i].phys_end; -} - -#endif diff --git a/src/generic/SConscript b/src/generic/SConscript index ebb9255..826baca 100644 --- a/src/generic/SConscript +++ b/src/generic/SConscript @@ -4,7 +4,7 @@ Import('env') # The set of source files associated with this SConscript file. -src_local = ['physmem.c', 'irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'space.c', 'bootm.c', 'resource.c', 'container.c', 'capability.c'] +src_local = ['irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'space.c', 'bootm.c', 'resource.c', 'container.c', 'capability.c'] obj = env.Object(src_local) Return('obj') diff --git a/src/generic/container.c b/src/generic/container.c index 85a359a..108af8b 100644 --- a/src/generic/container.c +++ b/src/generic/container.c @@ -17,15 +17,19 @@ * Add irqs, exceptions */ +#define CONFIG_CONT0_PAGER_START 0x40000 +#define CONFIG_CONT0_PHYS_END 0x1000000 +#define CONFIG_CONT0_PHYS_START CONFIG_CONT0_PAGER_START + struct container_info cinfo[] = { [0] = { .name = "Codezero POSIX Services", .npagers = 1, .pager = { [0] = { - .pager_lma = __pfn(0x38000), + .pager_lma = __pfn(CONFIG_CONT0_PAGER_START), .pager_vma = __pfn(0xE0000000), - .pager_size = __pfn(0x96000), + .pager_size = __pfn(0x9F000), .ncaps = 14, .caps = { [0] = { @@ -67,8 +71,8 @@ struct container_info cinfo[] = { .access = CAP_MAP_CACHED | CAP_MAP_UNCACHED | CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC | CAP_MAP_UNMAP, - .start = __pfn(0x38000), - .end = __pfn(0x1000000), /* 16 MB for all posix services */ + .start = __pfn(CONFIG_CONT0_PHYS_START), + .end = __pfn(CONFIG_CONT0_PHYS_END), /* 16 MB for all posix services */ }, [5] = { .type = CAP_TYPE_IPC | CAP_RTYPE_CONTAINER, @@ -269,9 +273,13 @@ int init_first_pager(struct pager *pager, mutex_init(&space->lock); space->pgd = current_pgd; + /* Initialize container relationships */ task->space = space; - task->container = cont; pager->tcb = task; + task->pager = pager; + task->container = cont; + link_init(&task->cap_list.caps); /* TODO: Do this in tcb_alloc_init */ + task->cap_list_ptr = &pager->cap_list; /* Map the task's space */ add_mapping_pgd(pager->start_lma, pager->start_vma, @@ -314,9 +322,12 @@ int init_pager(struct pager *pager, struct container *cont) task->space = address_space_create(0); - task->container = cont; - + /* Initialize container relationships */ pager->tcb = task; + task->pager = pager; + task->container = cont; + link_init(&task->cap_list.caps); /* TODO: Do this in tcb_alloc_init */ + task->cap_list_ptr = &pager->cap_list; add_mapping_pgd(pager->start_lma, pager->start_vma, page_align_up(pager->memsize), diff --git a/src/generic/physmem.c b/src/generic/physmem.c deleted file mode 100644 index 3cfcfd9..0000000 --- a/src/generic/physmem.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Global physical memory descriptions. - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -#include -#include -#include -#include -#include INC_SUBARCH(mm.h) -#include INC_GLUE(memlayout.h) -#include INC_GLUE(memory.h) -#include INC_PLAT(offsets.h) -#include INC_PLAT(printascii.h) -#include INC_ARCH(linker.h) - -struct page_bitmap page_map; - -static void init_page_map(unsigned long start, unsigned long end) -{ - page_map.pfn_start = __pfn(start); - page_map.pfn_end = __pfn(end); - set_page_map(start, __pfn(end - 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(unsigned long start, int numpages, int val) -{ - unsigned long pfn_start = __pfn(start); - 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; -} - -/* Describes physical memory boundaries of the system. */ -struct memdesc physmem; - -/* Fills in the physmem structure with free physical memory information */ -void physmem_init() -{ - unsigned long start = (unsigned long)_start_kernel; - unsigned long end = (unsigned long)_end_kernel; - - /* Initialise page map */ - init_page_map(PHYS_MEM_START, PHYS_MEM_END); - - /* Mark kernel areas as used */ - set_page_map(virt_to_phys(start), __pfn(end - start), 1); - - /* Map initial pgd area as used */ - start = (unsigned long)__pt_start; - end = (unsigned long)__pt_end; - set_page_map(virt_to_phys(TASK_PGD(current)), __pfn(end - start), 1); - - physmem.start = PHYS_MEM_START; - physmem.end = PHYS_MEM_END; - - physmem.free_cur = __svc_images_end; - physmem.free_end = PHYS_MEM_END; - physmem.numpages = (PHYS_MEM_START - PHYS_MEM_END) / PAGE_SIZE; -} - -void memory_init() -{ - //init_pgalloc(); -} - diff --git a/src/glue/arm/init.c b/src/glue/arm/init.c index 64bb775..016fe41 100644 --- a/src/glue/arm/init.c +++ b/src/glue/arm/init.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -17,7 +16,6 @@ #include #include INC_ARCH(linker.h) #include INC_ARCH(asm.h) -#include INC_ARCH(bootdesc.h) #include INC_SUBARCH(mm.h) #include INC_SUBARCH(mmu_ops.h) #include INC_GLUE(memlayout.h) diff --git a/src/glue/arm/memory.c b/src/glue/arm/memory.c index e779710..1cc52c9 100644 --- a/src/glue/arm/memory.c +++ b/src/glue/arm/memory.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include INC_SUBARCH(mm.h) diff --git a/tasks/fs0/include/kdata.h b/tasks/fs0/include/kdata.h deleted file mode 100644 index 1057acc..0000000 --- a/tasks/fs0/include/kdata.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2007 Bahadir Balban - */ -#ifndef __MM_KDATA_H__ -#define __MM_KDATA_H__ - -#include -#include -#include -#include -#include INC_PLAT(offsets.h) -#include INC_GLUE(memory.h) -#include INC_GLUE(memlayout.h) -#include INC_ARCH(bootdesc.h) - -struct initdata { - struct bootdesc *bootdesc; -}; - -extern struct initdata initdata; - -int request_initdata(struct initdata *i); - -#endif /* __MM_KDATA_H__ */ diff --git a/tasks/fs0/main.c b/tasks/fs0/main.c index dbd5d28..7fc7475 100644 --- a/tasks/fs0/main.c +++ b/tasks/fs0/main.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/tasks/fs0/src/init.c b/tasks/fs0/src/init.c index d5ce55c..84ff20c 100644 --- a/tasks/fs0/src/init.c +++ b/tasks/fs0/src/init.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -58,7 +57,7 @@ int initialise(void) struct superblock *root_sb; /* Get standard init data from microkernel */ - request_initdata(&initdata); + // request_initdata(&initdata); /* Register compiled-in filesystems with vfs core. */ vfs_register_filesystems(); diff --git a/tasks/fs0/src/kdata.c b/tasks/fs0/src/kdata.c deleted file mode 100644 index 4c90c34..0000000 --- a/tasks/fs0/src/kdata.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Requesting system information from kernel during init. - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -#include -#include -#include -#include INC_API(kip.h) -#include - -/* 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); - } -} - -int request_initdata(struct initdata *initdata) -{ - int err; - int bootdesc_size; - - /* 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: %s failed during initialisation. exiting.\n", __TASKNAME__); - return err; -} - diff --git a/include/l4/arch/arm/bootdesc.h b/tasks/mm0/include/bootdesc.h similarity index 76% rename from include/l4/arch/arm/bootdesc.h rename to tasks/mm0/include/bootdesc.h index 855b44a..5c39f79 100644 --- a/include/l4/arch/arm/bootdesc.h +++ b/tasks/mm0/include/bootdesc.h @@ -15,11 +15,7 @@ struct bootdesc { struct svc_image images[]; } __attribute__((__packed__)); -#if defined (__KERNEL__) -extern struct bootdesc *bootdesc; - -void read_bootdesc(void); -void copy_bootdesc(void); -#endif +struct initdata; +void read_bootdesc(struct initdata *initdata); #endif /* __BOOTDESC_H__ */ diff --git a/tasks/mm0/include/bootm.h b/tasks/mm0/include/bootm.h new file mode 100644 index 0000000..c342b35 --- /dev/null +++ b/tasks/mm0/include/bootm.h @@ -0,0 +1,9 @@ +#ifndef __PAGER_BOOTM_H__ +#define __PAGER_BOOTM_H__ + +#define __initdata SECTION(".init.data") + +void *alloc_bootmem(int size, int alignment); + + +#endif /* __PAGER_BOOTM_H__ */ diff --git a/tasks/mm0/include/capability.h b/tasks/mm0/include/capability.h new file mode 100644 index 0000000..3460500 --- /dev/null +++ b/tasks/mm0/include/capability.h @@ -0,0 +1,41 @@ +/* + * Capability-related operations of the pager. + * + * Copyright (C) 2009 Bahadir Balban + */ +#ifndef __MM0_CAPABILITY_H__ +#define __MM0_CAPABILITY_H__ + +#include +#include + +struct cap_list { + int ncaps; + struct link caps; +}; + +struct capability { + struct link list; + + /* Capability identifiers */ + l4id_t capid; /* Unique capability ID */ + l4id_t resid; /* Targeted resource ID */ + l4id_t owner; /* Capability owner ID */ + unsigned int type; /* Capability and target resource type */ + + /* Capability limits/permissions */ + u32 access; /* Permitted operations */ + + /* Limits on the resource */ + unsigned long start; /* Resource start value */ + unsigned long end; /* Resource end value */ + unsigned long size; /* Resource size */ +}; + + +extern struct cap_list capability_list; + +struct initdata; +int read_kernel_capabilities(struct initdata *); + +#endif /* __MM0_CAPABILITY_H__ */ diff --git a/tasks/mm0/include/init.h b/tasks/mm0/include/init.h index dde79f4..c436575 100644 --- a/tasks/mm0/include/init.h +++ b/tasks/mm0/include/init.h @@ -9,16 +9,19 @@ #include #include #include -#include #include INC_PLAT(offsets.h) #include INC_GLUE(memory.h) #include INC_GLUE(memlayout.h) -#include INC_ARCH(bootdesc.h) +#include +#include #include +#include struct initdata { + struct capability *bootcaps; + struct capability *physmem; struct bootdesc *bootdesc; - struct page_bitmap page_map; + struct page_bitmap *page_map; unsigned long pager_utcb_virt; unsigned long pager_utcb_phys; struct link boot_file_list; @@ -26,9 +29,9 @@ struct initdata { extern struct initdata initdata; -int request_initdata(struct initdata *i); +void init_pager(void); -void initialise(void); +/* TODO: Remove this stuff from here. */ int init_devzero(void); struct vm_file *get_devzero(void); int init_boot_files(struct initdata *initdata); diff --git a/tasks/mm0/include/linker.lds b/tasks/mm0/include/linker.lds index 3d6d288..c114b26 100644 --- a/tasks/mm0/include/linker.lds +++ b/tasks/mm0/include/linker.lds @@ -33,12 +33,19 @@ SECTIONS { *(.data) } - . = ALIGN(4K); - _start_init = .; - .init : AT (ADDR(.init) - offset) { *(.init.stack) } - . = ALIGN(8); - __stack = .; /* This is the preallocated boot stack */ - _end_init = .; .bss : AT (ADDR(.bss) - offset) { *(.bss) } + . = ALIGN(4K); + . += 0x2000; /* BSS doesnt increment link counter??? */ + /* Below part is to be discarded after boot */ + _start_init = .; + .init : AT (ADDR(.init) - offset) + { + *(.init.data) + *(.init.bootmem) + *(.init.stack) + } + _end_init = .; + __stack = .; /* This is the preallocated boot stack */ + _end_init = .; _end = .; } diff --git a/tasks/mm0/include/memory.h b/tasks/mm0/include/memory.h index efd5b75..281c47a 100644 --- a/tasks/mm0/include/memory.h +++ b/tasks/mm0/include/memory.h @@ -8,14 +8,7 @@ #include #include - -struct membank { - unsigned long start; - unsigned long end; - unsigned long free; - struct page *page_array; -}; -extern struct membank membank[]; +#include void init_mm_descriptors(struct page_bitmap *page_map, struct bootdesc *bootdesc, struct membank *membank); diff --git a/tasks/mm0/include/physmem.h b/tasks/mm0/include/physmem.h new file mode 100644 index 0000000..698be40 --- /dev/null +++ b/tasks/mm0/include/physmem.h @@ -0,0 +1,45 @@ +/* + * Physical memory descriptors + * + * Copyright (C) 2007 - 2009 Bahadir Balban + */ +#ifndef __PAGER_PHYSMEM_H__ +#define __PAGER_PHYSMEM_H__ + +/* A compact memory descriptor to determine used/unused pages in the system */ +struct page_bitmap { + unsigned long pfn_start; + unsigned long pfn_end; + unsigned int map[]; +}; + +/* Describes a portion of physical memory. */ +struct memdesc { + unsigned int start; + unsigned int end; + unsigned int free_cur; + unsigned int free_end; + unsigned int numpages; +}; + +struct membank { + unsigned long start; + unsigned long end; + unsigned long free; + struct page *page_array; +}; +extern struct membank membank[]; + +/* Describes bitmap of used/unused state for all physical pages */ +extern struct page_bitmap page_map; +extern struct memdesc physmem; + +/* Sets the global page map as used/unused. Aligns input when needed. */ +int set_page_map(struct page_bitmap *pmap, unsigned long start, + int numpages, int val); + +struct initdata; +void init_physmem_primary(struct initdata *initdata); +void init_physmem_secondary(struct initdata *initdata, struct membank *membank); + +#endif /* __PAGER_PHYSMEM_H__ */ diff --git a/tasks/mm0/main.c b/tasks/mm0/main.c index e046c61..fe32503 100644 --- a/tasks/mm0/main.c +++ b/tasks/mm0/main.c @@ -261,7 +261,7 @@ void main(void) printf("\n%s: Started with thread id %d\n", __TASKNAME__, self_tid()); /* Initialise the memory, server tasks, mmap and start them. */ - initialise(); + init_pager(); printf("%s: Memory/Process manager initialized. Listening requests.\n", __TASKNAME__); while (1) { diff --git a/tasks/mm0/src/bootdesc.c b/tasks/mm0/src/bootdesc.c new file mode 100644 index 0000000..bae6118 --- /dev/null +++ b/tasks/mm0/src/bootdesc.c @@ -0,0 +1,44 @@ +/* + * Reading of bootdesc forged at build time. + * + * Copyright (C) 2007 - 2009 Bahadir Balban + */ + +#include +#include +#include +#include + +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); +} diff --git a/tasks/mm0/src/bootm.c b/tasks/mm0/src/bootm.c new file mode 100644 index 0000000..393f99a --- /dev/null +++ b/tasks/mm0/src/bootm.c @@ -0,0 +1,62 @@ +/* + * Boot memory allocator + * + * Copyright (C) 2009 Bahadir Balban + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include INC_GLUE(memory.h) + +#include + +/* 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; +} + diff --git a/tasks/mm0/src/capability.c b/tasks/mm0/src/capability.c new file mode 100644 index 0000000..e82653b --- /dev/null +++ b/tasks/mm0/src/capability.c @@ -0,0 +1,62 @@ +/* + * Pager's capabilities for kernel resources + * + * Copyright (C) 2009 Bahadir Balban + */ +#include +#include +#include +#include +#include +#include /* 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(); +} + diff --git a/tasks/mm0/src/init.c b/tasks/mm0/src/init.c index eba4708..f433468 100644 --- a/tasks/mm0/src/init.c +++ b/tasks/mm0/src/init.c @@ -19,10 +19,61 @@ #include #include #include +#include /* 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); diff --git a/tasks/mm0/src/kdata.c b/tasks/mm0/src/kdata.c deleted file mode 100644 index 294d211..0000000 --- a/tasks/mm0/src/kdata.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Requesting system information from kernel during init. - * - * Copyright (C) 2007 Bahadir Balban - */ -#include -#include -#include -#include INC_API(kip.h) -#include -#include - -/* 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; -} - diff --git a/tasks/mm0/src/memory.c b/tasks/mm0/src/memory.c index 52af22c..0d4ae77 100644 --- a/tasks/mm0/src/memory.c +++ b/tasks/mm0/src/memory.c @@ -17,8 +17,6 @@ #include #include -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) { diff --git a/tasks/mm0/src/pagers.c b/tasks/mm0/src/pagers.c index 5959ff1..9b88c62 100644 --- a/tasks/mm0/src/pagers.c +++ b/tasks/mm0/src/pagers.c @@ -12,7 +12,6 @@ #include #include #include -#include INC_ARCH(bootdesc.h) #include struct page *page_init(struct page *page) diff --git a/tasks/mm0/src/physmem.c b/tasks/mm0/src/physmem.c new file mode 100644 index 0000000..18541d5 --- /dev/null +++ b/tasks/mm0/src/physmem.c @@ -0,0 +1,166 @@ +/* + * Global physical memory descriptions. + * + * Copyright (C) 2007 - 2009 Bahadir Balban + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include INC_GLUE(memory.h) + +#include +#include +#include +#include + +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); +} + diff --git a/tasks/mm0/src/stack.c b/tasks/mm0/src/stack.c deleted file mode 100644 index 05e2e82..0000000 --- a/tasks/mm0/src/stack.c +++ /dev/null @@ -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 -#include -#include -#include INC_GLUE(memlayout.h) -#include - -/* 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; - -} -