2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Platform interface implementation
|
|
|
|
* \author Norman Feske
|
|
|
|
* \author Sebastian Sumpf
|
2012-08-01 16:16:51 +02:00
|
|
|
* \author Alexander Boettcher
|
2011-12-22 16:19:25 +01:00
|
|
|
* \date 2009-10-02
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2012-01-03 15:35:05 +01:00
|
|
|
* Copyright (C) 2009-2012 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <base/printf.h>
|
|
|
|
#include <base/sleep.h>
|
|
|
|
#include <base/thread.h>
|
2012-08-01 16:16:51 +02:00
|
|
|
#include <base/cap_sel_alloc.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* core includes */
|
|
|
|
#include <core_parent.h>
|
|
|
|
#include <platform.h>
|
|
|
|
#include <nova_util.h>
|
|
|
|
#include <util.h>
|
|
|
|
|
|
|
|
/* NOVA includes */
|
|
|
|
#include <nova/syscalls.h>
|
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
using namespace Nova;
|
|
|
|
|
|
|
|
|
|
|
|
enum { verbose_boot_info = true };
|
|
|
|
|
2012-09-28 12:24:14 +02:00
|
|
|
Native_utcb *main_thread_utcb();
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initial value of esp register, saved by the crt0 startup code
|
|
|
|
*
|
|
|
|
* This value contains the address of the hypervisor information page.
|
|
|
|
*/
|
|
|
|
extern long __initial_sp;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pointer to the UTCB of the main thread
|
|
|
|
*/
|
2012-09-28 12:24:14 +02:00
|
|
|
Utcb *__main_thread_utcb;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Virtual address range consumed by core's program image
|
|
|
|
*/
|
|
|
|
extern unsigned _prog_img_beg, _prog_img_end;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Capability selector of root PD
|
|
|
|
*/
|
2012-08-01 17:04:43 +02:00
|
|
|
addr_t __core_pd_sel;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-11-22 14:11:15 +01:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/**
|
2012-11-22 14:11:15 +01:00
|
|
|
* Map preserved physical page for the exclusive read-execute-only used by core
|
2011-12-22 16:19:25 +01:00
|
|
|
*/
|
2012-11-22 11:26:51 +01:00
|
|
|
addr_t Platform::_map_page(addr_t phys_page, addr_t pages)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2012-11-22 11:26:51 +01:00
|
|
|
/* set an invalid address */
|
|
|
|
void * core_local_ptr = 0;
|
|
|
|
if (!region_alloc()->alloc(pages << get_page_size_log2(),
|
|
|
|
&core_local_ptr))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
addr_t core_local_addr = reinterpret_cast<addr_t>(core_local_ptr);
|
|
|
|
int res = map_local(__main_thread_utcb, phys_page << get_page_size_log2(),
|
|
|
|
core_local_addr, pages,
|
2012-11-22 14:11:15 +01:00
|
|
|
Nova::Rights(true, false, true), true);
|
2012-11-22 11:26:51 +01:00
|
|
|
if (res)
|
|
|
|
PERR("map_local failed res=%d", res);
|
|
|
|
|
|
|
|
return res ? 0 : core_local_addr;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
2012-11-22 14:11:15 +01:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/*****************************
|
|
|
|
** Core page-fault handler **
|
|
|
|
*****************************/
|
|
|
|
|
2012-09-04 12:45:27 +02:00
|
|
|
enum { CORE_PAGER_UTCB_ADDR = 0xbff02000 };
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* IDC handler for the page-fault portal
|
|
|
|
*/
|
|
|
|
static void page_fault_handler()
|
|
|
|
{
|
|
|
|
Utcb *utcb = (Utcb *)CORE_PAGER_UTCB_ADDR;
|
|
|
|
|
|
|
|
addr_t pf_addr = utcb->qual[1];
|
2012-08-24 10:25:24 +02:00
|
|
|
addr_t pf_ip = utcb->ip;
|
|
|
|
addr_t pf_sp = utcb->sp;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
printf("\nPAGE-FAULT IN CORE: ADDR %lx IP %lx SP %lx stack trace follows...\n",
|
2012-08-24 10:25:24 +02:00
|
|
|
pf_addr, pf_ip, pf_sp);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* dump stack trace */
|
|
|
|
struct Core_img
|
|
|
|
{
|
|
|
|
addr_t _beg;
|
|
|
|
addr_t _end;
|
|
|
|
addr_t *_ip;
|
|
|
|
|
|
|
|
Core_img(addr_t sp)
|
|
|
|
{
|
|
|
|
extern addr_t _dtors_end;
|
|
|
|
_beg = (addr_t)&_prog_img_beg;
|
|
|
|
_end = (addr_t)&_dtors_end;
|
|
|
|
|
|
|
|
_ip = (addr_t *)sp;
|
|
|
|
for (;!ip_valid(); _ip++) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
addr_t *ip() { return _ip; }
|
|
|
|
void next_ip() { _ip = ((addr_t *)*(_ip - 1)) + 1;}
|
|
|
|
bool ip_valid() { return *_ip >= _beg && *_ip < _end; }
|
|
|
|
};
|
|
|
|
|
|
|
|
int count = 1;
|
2012-08-24 10:25:24 +02:00
|
|
|
printf(" #%d %08lx %08lx\n", count++, pf_sp, pf_ip);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-08-24 10:25:24 +02:00
|
|
|
Core_img dump(pf_sp);
|
2011-12-22 16:19:25 +01:00
|
|
|
while (dump.ip_valid()) {
|
|
|
|
printf(" #%d %p %08lx\n", count++, dump.ip(), *dump.ip());
|
|
|
|
dump.next_ip();
|
|
|
|
}
|
|
|
|
|
|
|
|
sleep_forever();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-05 14:46:16 +02:00
|
|
|
static addr_t core_pager_stack_top()
|
|
|
|
{
|
|
|
|
enum { STACK_SIZE = 4*1024 };
|
|
|
|
static char stack[STACK_SIZE];
|
|
|
|
return (addr_t)&stack[STACK_SIZE - sizeof(addr_t)];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Startup handler for core threads
|
|
|
|
*/
|
|
|
|
static void startup_handler()
|
|
|
|
{
|
|
|
|
Utcb *utcb = (Utcb *)CORE_PAGER_UTCB_ADDR;
|
|
|
|
|
|
|
|
/* initial IP is on stack */
|
|
|
|
utcb->ip = *reinterpret_cast<addr_t *>(utcb->sp);
|
|
|
|
utcb->mtd = Mtd::EIP | Mtd::ESP;
|
|
|
|
utcb->set_msg_word(0);
|
|
|
|
|
|
|
|
reply((void*)core_pager_stack_top());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
static void init_core_page_fault_handler()
|
|
|
|
{
|
|
|
|
/* create echo EC */
|
2012-08-01 16:16:51 +02:00
|
|
|
enum {
|
2011-12-22 16:19:25 +01:00
|
|
|
CPU_NO = 0,
|
|
|
|
GLOBAL = false,
|
|
|
|
EXC_BASE = 0
|
|
|
|
};
|
|
|
|
|
2012-07-30 10:56:07 +02:00
|
|
|
addr_t ec_sel = cap_selector_allocator()->alloc();
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-07-30 10:56:07 +02:00
|
|
|
uint8_t ret = create_ec(ec_sel, __core_pd_sel, CPU_NO,
|
2012-10-05 14:46:16 +02:00
|
|
|
CORE_PAGER_UTCB_ADDR, core_pager_stack_top(),
|
|
|
|
EXC_BASE, GLOBAL);
|
2011-12-22 16:19:25 +01:00
|
|
|
if (ret)
|
2012-07-30 10:56:07 +02:00
|
|
|
PDBG("create_ec returned %u", ret);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* set up page-fault portal */
|
2012-08-01 17:04:43 +02:00
|
|
|
create_pt(PT_SEL_PAGE_FAULT, __core_pd_sel, ec_sel,
|
2011-12-22 16:19:25 +01:00
|
|
|
Mtd(Mtd::QUAL | Mtd::ESP | Mtd::EIP),
|
2012-07-30 10:56:07 +02:00
|
|
|
(addr_t)page_fault_handler);
|
2012-10-05 14:46:16 +02:00
|
|
|
|
|
|
|
/* startup portal for global core threads */
|
|
|
|
create_pt(PT_SEL_STARTUP, __core_pd_sel, ec_sel,
|
|
|
|
Mtd(Mtd::EIP | Mtd::ESP),
|
|
|
|
(addr_t)startup_handler);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************
|
|
|
|
** Platform **
|
|
|
|
**************/
|
|
|
|
|
|
|
|
Platform::Platform() :
|
|
|
|
_io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()),
|
|
|
|
_irq_alloc(core_mem_alloc()),
|
2012-11-19 10:23:37 +01:00
|
|
|
_vm_base(0x2000), _vm_size(0)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
Hip *hip = (Hip *)__initial_sp;
|
|
|
|
|
|
|
|
/* register UTCB of main thread */
|
|
|
|
__main_thread_utcb = (Utcb *)(__initial_sp - get_page_size());
|
|
|
|
|
|
|
|
/* set core pd selector */
|
2012-08-01 17:04:43 +02:00
|
|
|
__core_pd_sel = hip->sel_exc;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-08-01 16:16:51 +02:00
|
|
|
/* create lock used by capability allocator */
|
2012-08-01 17:04:43 +02:00
|
|
|
Nova::create_sm(Nova::SM_SEL_EC, __core_pd_sel, 0);
|
2012-08-01 16:16:51 +02:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/* locally map the whole I/O port range */
|
|
|
|
enum { ORDER_64K = 16 };
|
|
|
|
map_local_one_to_one(__main_thread_utcb, Io_crd(0, ORDER_64K));
|
2012-11-19 10:23:37 +01:00
|
|
|
/* map BDA region, core_console reads out serial i/o ports at 0x400 */
|
|
|
|
map_local_phys_to_virt(__main_thread_utcb,
|
|
|
|
Mem_crd(0x0, 0, Rights(true, false, false)),
|
|
|
|
Mem_crd(0x1, 0, Rights(true, false, false)));
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Now that we can access the I/O ports for comport 0, printf works...
|
|
|
|
*/
|
|
|
|
|
2012-10-01 12:01:04 +02:00
|
|
|
/* sanity checks */
|
|
|
|
if (hip->sel_exc + 3 > NUM_INITIAL_PT_RESERVED) {
|
|
|
|
printf("configuration error\n");
|
|
|
|
nova_die();
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:45:27 +02:00
|
|
|
/* configure virtual address spaces */
|
|
|
|
#ifdef __x86_64__
|
|
|
|
_vm_size = 0x800000000000UL - _vm_base;
|
|
|
|
#else
|
|
|
|
_vm_size = 0xc0000000UL - _vm_base;
|
|
|
|
#endif
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/* set up page fault handler for core - for debugging */
|
|
|
|
init_core_page_fault_handler();
|
|
|
|
|
|
|
|
if (verbose_boot_info) {
|
|
|
|
printf("Hypervisor %s VMX\n", hip->has_feature_vmx() ? "features" : "does not feature");
|
|
|
|
printf("Hypervisor %s SVM\n", hip->has_feature_svm() ? "features" : "does not feature");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize core allocators */
|
|
|
|
size_t num_mem_desc = (hip->hip_length - hip->mem_desc_offset)
|
|
|
|
/ hip->mem_desc_size;
|
|
|
|
|
|
|
|
if (verbose_boot_info)
|
|
|
|
printf("Hypervisor info page contains %zd memory descriptors:\n", num_mem_desc);
|
|
|
|
|
|
|
|
addr_t mem_desc_base = ((addr_t)hip + hip->mem_desc_offset);
|
|
|
|
|
|
|
|
/* define core's virtual address space */
|
2012-09-04 12:45:27 +02:00
|
|
|
addr_t virt_beg = _vm_base;
|
|
|
|
addr_t virt_end = _vm_size;
|
|
|
|
_core_mem_alloc.virt_alloc()->add_range(virt_beg, virt_end - virt_beg);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* exclude core image from core's virtual address allocator */
|
|
|
|
addr_t core_virt_beg = trunc_page((addr_t)&_prog_img_beg),
|
|
|
|
core_virt_end = round_page((addr_t)&_prog_img_end);
|
|
|
|
size_t core_size = core_virt_end - core_virt_beg;
|
|
|
|
_core_mem_alloc.virt_alloc()->remove_range(core_virt_beg, core_size);
|
|
|
|
|
|
|
|
/* preserve context area in core's virtual address space */
|
2012-08-29 14:42:56 +02:00
|
|
|
_core_mem_alloc.virt_alloc()->remove_range(Native_config::context_area_virtual_base(),
|
|
|
|
Native_config::context_area_virtual_size());
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-09-04 12:45:27 +02:00
|
|
|
/* exclude utcb of core pager thread + empty guard pages before and after */
|
|
|
|
_core_mem_alloc.virt_alloc()->remove_range(CORE_PAGER_UTCB_ADDR - get_page_size(),
|
|
|
|
get_page_size() * 3);
|
|
|
|
|
|
|
|
/* exclude utcb of echo thread + empty guard pages before and after */
|
|
|
|
_core_mem_alloc.virt_alloc()->remove_range(Echo::ECHO_UTCB_ADDR - get_page_size(),
|
|
|
|
get_page_size() * 3);
|
|
|
|
|
|
|
|
/* exclude utcb of main thread and hip + empty guard pages before and after */
|
|
|
|
_core_mem_alloc.virt_alloc()->remove_range((addr_t)__main_thread_utcb - get_page_size(),
|
|
|
|
get_page_size() * 4);
|
|
|
|
|
|
|
|
/* sanity checks */
|
|
|
|
addr_t check [] = {
|
|
|
|
reinterpret_cast<addr_t>(__main_thread_utcb), CORE_PAGER_UTCB_ADDR,
|
|
|
|
Echo::ECHO_UTCB_ADDR,
|
|
|
|
};
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < sizeof(check) / sizeof(check[0]); i++) {
|
|
|
|
if (Native_config::context_area_virtual_base() <= check[i] &&
|
|
|
|
check[i] < Native_config::context_area_virtual_base() +
|
|
|
|
Native_config::context_area_virtual_size())
|
|
|
|
{
|
|
|
|
PERR("overlapping area - [%lx, %lx) vs %lx",
|
|
|
|
Native_config::context_area_virtual_base(),
|
|
|
|
Native_config::context_area_virtual_base() +
|
|
|
|
Native_config::context_area_virtual_size(), check[i]);
|
|
|
|
nova_die();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/* initialize core's physical-memory and I/O memory allocator */
|
2012-09-04 12:45:27 +02:00
|
|
|
_io_mem_alloc.add_range(0, ~0xfffUL);
|
2011-12-22 16:19:25 +01:00
|
|
|
Hip::Mem_desc *mem_desc = (Hip::Mem_desc *)mem_desc_base;
|
|
|
|
for (unsigned i = 0; i < num_mem_desc; i++, mem_desc++) {
|
|
|
|
if (mem_desc->type != Hip::Mem_desc::AVAILABLE_MEMORY) continue;
|
|
|
|
|
2012-07-09 11:00:03 +02:00
|
|
|
if (verbose_boot_info)
|
2012-11-22 11:26:51 +01:00
|
|
|
printf("detected physical memory: 0x%16llx - size: 0x%llx\n",
|
|
|
|
mem_desc->addr, mem_desc->size);
|
2012-07-09 11:00:03 +02:00
|
|
|
|
|
|
|
/* skip regions above 4G on 32 bit, no op on 64 bit */
|
|
|
|
if (mem_desc->addr > ~0UL) continue;
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
addr_t base = round_page(mem_desc->addr);
|
2012-07-09 11:00:03 +02:00
|
|
|
size_t size;
|
|
|
|
/* truncate size if base+size larger then natural 32/64 bit boundary */
|
|
|
|
if (mem_desc->addr >= ~0UL - mem_desc->size + 1)
|
|
|
|
size = trunc_page(~0UL - mem_desc->addr + 1);
|
|
|
|
else
|
|
|
|
size = trunc_page(mem_desc->addr + mem_desc->size) - base;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
if (verbose_boot_info)
|
2012-11-22 11:26:51 +01:00
|
|
|
printf("use physical memory: 0x%16lx - size: 0x%zx\n", base, size);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
_io_mem_alloc.remove_range(base, size);
|
|
|
|
_core_mem_alloc.phys_alloc()->add_range(base, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* exclude all non-available memory from physical allocator */
|
|
|
|
mem_desc = (Hip::Mem_desc *)mem_desc_base;
|
|
|
|
for (unsigned i = 0; i < num_mem_desc; i++, mem_desc++) {
|
|
|
|
if (mem_desc->type == Hip::Mem_desc::AVAILABLE_MEMORY) continue;
|
|
|
|
|
2012-07-09 11:00:03 +02:00
|
|
|
/* skip regions above 4G on 32 bit, no op on 64 bit */
|
|
|
|
if (mem_desc->addr > ~0UL) continue;
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
addr_t base = trunc_page(mem_desc->addr);
|
2012-07-09 11:00:03 +02:00
|
|
|
size_t size;
|
|
|
|
/* truncate size if base+size larger then natural 32/64 bit boundary */
|
|
|
|
if (mem_desc->addr >= ~0UL - mem_desc->size + 1)
|
|
|
|
size = round_page(~0UL - mem_desc->addr + 1);
|
|
|
|
else
|
|
|
|
size = round_page(mem_desc->addr + mem_desc->size) - base;
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
_io_mem_alloc.add_range(base, size);
|
|
|
|
_core_mem_alloc.phys_alloc()->remove_range(base, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* needed as I/O memory by the VESA driver */
|
|
|
|
_io_mem_alloc.add_range(0, 0x1000);
|
|
|
|
_core_mem_alloc.phys_alloc()->remove_range(0, 0x1000);
|
|
|
|
|
|
|
|
/* exclude pages holding multi-boot command lines from core allocators */
|
|
|
|
mem_desc = (Hip::Mem_desc *)mem_desc_base;
|
|
|
|
addr_t prev_cmd_line_page = 0, curr_cmd_line_page = 0;
|
|
|
|
for (unsigned i = 0; i < num_mem_desc; i++, mem_desc++) {
|
|
|
|
if (mem_desc->type != Hip::Mem_desc::MULTIBOOT_MODULE) continue;
|
2012-07-09 11:00:03 +02:00
|
|
|
if (!mem_desc->aux) continue;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
curr_cmd_line_page = mem_desc->aux >> get_page_size_log2();
|
|
|
|
if (curr_cmd_line_page == prev_cmd_line_page) continue;
|
|
|
|
|
2012-11-22 11:26:51 +01:00
|
|
|
ram_alloc()->remove_range(curr_cmd_line_page << get_page_size_log2(),
|
|
|
|
get_page_size());
|
2011-12-22 16:19:25 +01:00
|
|
|
prev_cmd_line_page = curr_cmd_line_page;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* preserve page following the last multi-boot command line */
|
2012-11-22 11:26:51 +01:00
|
|
|
ram_alloc()->remove_range((curr_cmd_line_page + 1) << get_page_size_log2(),
|
|
|
|
get_page_size());
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* From now on, it is save to use the core allocators...
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* build ROM file system */
|
|
|
|
mem_desc = (Hip::Mem_desc *)mem_desc_base;
|
2012-11-22 11:26:51 +01:00
|
|
|
prev_cmd_line_page = 0, curr_cmd_line_page = 0;
|
|
|
|
addr_t mapped_cmd_line = 0;
|
2011-12-22 16:19:25 +01:00
|
|
|
for (unsigned i = 0; i < num_mem_desc; i++, mem_desc++) {
|
|
|
|
if (mem_desc->type != Hip::Mem_desc::MULTIBOOT_MODULE) continue;
|
2012-07-09 11:00:03 +02:00
|
|
|
if (!mem_desc->addr || !mem_desc->size || !mem_desc->aux) continue;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-11-22 11:26:51 +01:00
|
|
|
addr_t core_local_addr =
|
|
|
|
_map_page(trunc_page(mem_desc->addr) >> get_page_size_log2(),
|
|
|
|
(round_page(mem_desc->addr + mem_desc->size) -
|
|
|
|
trunc_page(mem_desc->addr)) >> get_page_size_log2());
|
|
|
|
if (!core_local_addr) {
|
|
|
|
PERR("could not map multi boot module");
|
|
|
|
nova_die();
|
|
|
|
}
|
|
|
|
/* adjust module addr if it is not page aligned */
|
|
|
|
core_local_addr += mem_desc->addr - trunc_page(mem_desc->addr);
|
|
|
|
|
2012-11-22 14:11:15 +01:00
|
|
|
printf("map multi-boot module: physical 0x%8lx -> [0x%8lx-0x%8lx) - ",
|
|
|
|
(addr_t)mem_desc->addr, (addr_t)core_local_addr,
|
|
|
|
(addr_t)(core_local_addr + mem_desc->size));
|
|
|
|
|
2012-11-22 11:26:51 +01:00
|
|
|
/* check if cmd line is part of the module pages, don't map it twice */
|
|
|
|
addr_t aux;
|
|
|
|
if (trunc_page(mem_desc->addr) <= mem_desc->aux &&
|
|
|
|
mem_desc->aux < round_page(mem_desc->addr + mem_desc->size)) {
|
|
|
|
aux = core_local_addr + (mem_desc->aux - mem_desc->addr);
|
|
|
|
} else {
|
|
|
|
curr_cmd_line_page = mem_desc->aux >> get_page_size_log2();
|
|
|
|
if (curr_cmd_line_page != prev_cmd_line_page) {
|
|
|
|
mapped_cmd_line = _map_page(curr_cmd_line_page, 2);
|
|
|
|
prev_cmd_line_page = curr_cmd_line_page;
|
|
|
|
}
|
|
|
|
aux = mapped_cmd_line + (mem_desc->aux - trunc_page(mem_desc->aux));
|
|
|
|
}
|
2012-06-07 09:35:22 +02:00
|
|
|
const char *name = commandline_to_basename(reinterpret_cast<char *>(aux));
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-11-22 14:11:15 +01:00
|
|
|
printf("%s\n", name);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
Rom_module *rom_module = new (core_mem_alloc())
|
2012-11-22 11:26:51 +01:00
|
|
|
Rom_module(core_local_addr, mem_desc->size, name);
|
2011-12-22 16:19:25 +01:00
|
|
|
_rom_fs.insert(rom_module);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* export hypervisor info page as ROM module */
|
|
|
|
_rom_fs.insert(new (core_mem_alloc())
|
|
|
|
Rom_module((addr_t)hip, get_page_size(), "hypervisor_info_page"));
|
|
|
|
|
|
|
|
/* I/O port allocator (only meaningful for x86) */
|
|
|
|
_io_port_alloc.add_range(0, 0x10000);
|
|
|
|
|
|
|
|
/* IRQ allocator */
|
|
|
|
_irq_alloc.add_range(0, hip->sel_gsi - 1);
|
2012-06-06 10:19:48 +02:00
|
|
|
_gsi_base_sel = (hip->mem_desc_offset - hip->cpu_desc_offset) / hip->cpu_desc_size;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-09-28 12:24:14 +02:00
|
|
|
/* remap main utcb to default utbc address */
|
|
|
|
if (map_local(__main_thread_utcb, (addr_t)__main_thread_utcb,
|
2012-11-22 14:11:15 +01:00
|
|
|
(addr_t)main_thread_utcb(), 1, Rights(true, true, false))) {
|
2012-09-28 12:24:14 +02:00
|
|
|
PERR("could not remap main threads utcb");
|
|
|
|
nova_die();
|
|
|
|
}
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
if (verbose_boot_info) {
|
|
|
|
printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree();
|
|
|
|
printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree();
|
|
|
|
printf(":io_mem_alloc: "); _io_mem_alloc.raw()->dump_addr_tree();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************
|
|
|
|
** Support for core memory management **
|
|
|
|
****************************************/
|
|
|
|
|
|
|
|
bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr,
|
|
|
|
addr_t phys_addr,
|
|
|
|
unsigned size_log2)
|
|
|
|
{
|
|
|
|
map_local((Utcb *)Thread_base::myself()->utcb(), phys_addr,
|
2012-11-20 10:05:14 +01:00
|
|
|
virt_addr, 1 << (size_log2 - get_page_size_log2()),
|
|
|
|
Rights(true, true, true), true);
|
2011-12-22 16:19:25 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/********************************
|
|
|
|
** Generic platform interface **
|
|
|
|
********************************/
|
|
|
|
|
|
|
|
void Platform::wait_for_exit() { sleep_forever(); }
|
|
|
|
|
|
|
|
|
|
|
|
void Core_parent::exit(int exit_value) { }
|