84 lines
2.0 KiB
C++
84 lines
2.0 KiB
C++
/*
|
|
* \brief Linux-specific definitions and utilities for the stack area
|
|
* \author Christian Helmuth
|
|
* \date 2013-09-26
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2010-2013 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#ifndef _INCLUDE__BASE__INTERNAL__STACK_AREA_H_
|
|
#define _INCLUDE__BASE__INTERNAL__STACK_AREA_H_
|
|
|
|
/* Genode includes */
|
|
#include <base/thread.h>
|
|
#include <rm_session/rm_session.h>
|
|
|
|
#include <linux_syscalls.h>
|
|
|
|
/* Linux includes */
|
|
#include <sys/mman.h>
|
|
|
|
|
|
extern Genode::addr_t _stack_area_start;
|
|
|
|
|
|
namespace Genode {
|
|
|
|
/**
|
|
* Stack area base address
|
|
*
|
|
* Please update platform-specific files after changing these
|
|
* functions, e.g., 'base-linux/src/ld/stack_area.*.ld'.
|
|
*/
|
|
static addr_t stack_area_virtual_base() {
|
|
return align_addr((addr_t)&_stack_area_start, 20); }
|
|
|
|
static constexpr addr_t stack_area_virtual_size() { return 0x10000000UL; }
|
|
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
|
|
}
|
|
|
|
|
|
static inline void flush_stack_area()
|
|
{
|
|
using namespace Genode;
|
|
|
|
void * const base = (void *)stack_area_virtual_base();
|
|
size_t const size = stack_area_virtual_size();
|
|
|
|
int ret;
|
|
if ((ret = lx_munmap(base, size)) < 0) {
|
|
PERR("%s: failed ret=%d", __func__, ret);
|
|
throw Rm_session::Region_conflict();
|
|
}
|
|
}
|
|
|
|
|
|
static inline Genode::addr_t reserve_stack_area()
|
|
{
|
|
using namespace Genode;
|
|
|
|
int const flags = MAP_ANONYMOUS | MAP_PRIVATE;
|
|
int const prot = PROT_NONE;
|
|
size_t const size = stack_area_virtual_size();
|
|
void * const addr_in = (void *)stack_area_virtual_base();
|
|
void * const addr_out = lx_mmap(addr_in, size, prot, flags, -1, 0);
|
|
|
|
/* reserve at local address failed - unmap incorrect mapping */
|
|
if (addr_in != addr_out) {
|
|
lx_munmap((void *)addr_out, size);
|
|
|
|
PERR("%s: failed addr_in=%p addr_out=%p ret=%ld)", __func__,
|
|
addr_in, addr_out, (long)addr_out);
|
|
throw Rm_session::Region_conflict();
|
|
}
|
|
|
|
return (addr_t) addr_out;
|
|
}
|
|
|
|
#endif /* _INCLUDE__BASE__INTERNAL__STACK_AREA_H_ */
|