2013-11-18 14:42:21 +01:00
|
|
|
/*
|
|
|
|
* \brief Virtual Machine Monitor MMU definition
|
|
|
|
* \author Stefan Kalkowski
|
|
|
|
* \date 2012-06-25
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2012-2017 Genode Labs GmbH
|
2013-11-18 14:42:21 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2013-11-18 14:42:21 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _SRC__SERVER__VMM__INCLUDE__MMU_H_
|
|
|
|
#define _SRC__SERVER__VMM__INCLUDE__MMU_H_
|
|
|
|
|
2018-09-26 15:53:18 +02:00
|
|
|
/* base includes */
|
|
|
|
#include <cpu/vm_state.h>
|
|
|
|
|
2013-11-18 14:42:21 +01:00
|
|
|
/* local includes */
|
|
|
|
#include <ram.h>
|
|
|
|
|
|
|
|
class Mmu
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2017-01-05 20:42:16 +01:00
|
|
|
Genode::Vm_state &_state;
|
|
|
|
Ram const &_ram;
|
2013-11-18 14:42:21 +01:00
|
|
|
|
2017-01-05 20:42:16 +01:00
|
|
|
unsigned _n_bits() { return _state.ttbrc & 0x7; }
|
2013-11-18 14:42:21 +01:00
|
|
|
|
|
|
|
bool _ttbr0(Genode::addr_t mva) {
|
|
|
|
return (!_n_bits() || !(mva >> (32 - _n_bits()))); }
|
|
|
|
|
|
|
|
Genode::addr_t _first_level(Genode::addr_t va)
|
|
|
|
{
|
|
|
|
if (!_ttbr0(va))
|
2017-01-05 20:42:16 +01:00
|
|
|
return ((_state.ttbr[1] & 0xffffc000) |
|
2013-11-18 14:42:21 +01:00
|
|
|
((va >> 18) & 0xffffc));
|
|
|
|
unsigned shift = 14 - _n_bits();
|
2017-01-05 20:42:16 +01:00
|
|
|
return (((_state.ttbr[0] >> shift) << shift) |
|
2013-11-18 14:42:21 +01:00
|
|
|
(((va << _n_bits()) >> (18 + _n_bits())) & 0x3ffc));
|
|
|
|
}
|
|
|
|
|
|
|
|
Genode::addr_t _page(Genode::addr_t fe, Genode::addr_t va)
|
|
|
|
{
|
|
|
|
enum Type { FAULT, LARGE, SMALL };
|
|
|
|
|
2017-01-05 20:42:16 +01:00
|
|
|
Genode::addr_t se = *((Genode::addr_t*)_ram.va(((fe & (~0UL << 10)) |
|
2013-11-18 14:42:21 +01:00
|
|
|
((va >> 10) & 0x3fc))));
|
|
|
|
switch (se & 0x3) {
|
|
|
|
case FAULT:
|
|
|
|
return 0;
|
|
|
|
case LARGE:
|
|
|
|
return ((se & (~0UL << 16)) | (va & (~0UL >> 16)));
|
|
|
|
default:
|
|
|
|
return ((se & (~0UL << 12)) | (va & (~0UL >> 20)));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Genode::addr_t _section(Genode::addr_t fe, Genode::addr_t va) {
|
|
|
|
return ((fe & 0xfff00000) | (va & 0xfffff)); }
|
|
|
|
|
|
|
|
Genode::addr_t _supersection(Genode::addr_t fe, Genode::addr_t va)
|
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
Genode::warning(__func__, " not implemented yet!");
|
2013-11-18 14:42:21 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2017-01-05 20:42:16 +01:00
|
|
|
Mmu(Genode::Vm_state &state, Ram const &ram)
|
2013-11-18 14:42:21 +01:00
|
|
|
: _state(state), _ram(ram) {}
|
|
|
|
|
|
|
|
|
|
|
|
Genode::addr_t phys_addr(Genode::addr_t va)
|
|
|
|
{
|
|
|
|
enum Type { FAULT, PAGETABLE, SECTION };
|
|
|
|
|
2017-01-05 20:42:16 +01:00
|
|
|
Genode::addr_t fe = *((Genode::addr_t*)_ram.va(_first_level(va)));
|
2013-11-18 14:42:21 +01:00
|
|
|
switch (fe & 0x3) {
|
|
|
|
case PAGETABLE:
|
|
|
|
return _page(fe, va);
|
|
|
|
case SECTION:
|
|
|
|
return (fe & 0x40000) ? _supersection(fe, va)
|
|
|
|
: _section(fe, va);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* _SRC__SERVER__VMM__INCLUDE__MMU_H_ */
|