150 lines
2.7 KiB
C++
150 lines
2.7 KiB
C++
/*
|
|
* \brief Helper utilities for Broadwell GPU mutliplexer
|
|
* \author Josef Soentgen
|
|
* \data 2017-03-15
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2017 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
#ifndef _UTILS_H_
|
|
#define _UTILS_H_
|
|
|
|
/* Genode includes */
|
|
#include <util/interface.h>
|
|
#include <base/ram_allocator.h>
|
|
|
|
namespace Utils {
|
|
|
|
using size_t = Genode::size_t;
|
|
using uint32_t = Genode::uint32_t;
|
|
using Ram = Genode::Ram_dataspace_capability;
|
|
|
|
/*
|
|
* Backend allocator interface
|
|
*/
|
|
struct Backend_alloc : Genode::Interface
|
|
{
|
|
virtual Ram alloc(Genode::Allocator_guard &, Genode::size_t) = 0;
|
|
virtual void free(Genode::Allocator_guard &, Ram) = 0;
|
|
};
|
|
|
|
template <unsigned int ELEMENTS> class Address_map;
|
|
|
|
void clflush(volatile void *addr)
|
|
{
|
|
asm volatile("clflush %0" : "+m" (*(volatile char *)addr));
|
|
}
|
|
|
|
}
|
|
|
|
template <unsigned int ELEMENTS>
|
|
class Utils::Address_map
|
|
{
|
|
public:
|
|
|
|
struct Element
|
|
{
|
|
Ram ds_cap { };
|
|
void *va { nullptr };
|
|
void *pa { nullptr };
|
|
uint32_t index { 0 };
|
|
|
|
Element() { }
|
|
|
|
Element(uint32_t index, Ram ds_cap, void *va)
|
|
:
|
|
ds_cap(ds_cap),
|
|
va(va),
|
|
pa((void *)Genode::Dataspace_client(ds_cap).phys_addr()),
|
|
index(index)
|
|
{ }
|
|
|
|
Element(Element const &other)
|
|
:
|
|
ds_cap(other.ds_cap), va(other.va), pa(other.pa),
|
|
index(other.index)
|
|
{ }
|
|
|
|
Element &operator = (Element const &other)
|
|
{
|
|
ds_cap = other.ds_cap;
|
|
va = other.va;
|
|
pa = other.pa;
|
|
index = other.index;
|
|
return *this;
|
|
}
|
|
|
|
bool valid() { return va && pa; }
|
|
};
|
|
|
|
private:
|
|
|
|
Element _map[ELEMENTS];
|
|
|
|
public:
|
|
|
|
Address_map()
|
|
{
|
|
Genode::memset(&_map, 0, sizeof(_map));
|
|
}
|
|
|
|
~Address_map()
|
|
{
|
|
for (uint32_t i = 0; i < ELEMENTS; i++) {
|
|
if (!_map[i].valid()) { continue; }
|
|
|
|
Genode::error("Address_map entry ", Genode::Hex(i), " ",
|
|
"still valid (", _map[i].va, "/", _map[i].pa, ")");
|
|
}
|
|
}
|
|
|
|
bool add(Ram ds_cap, void *va)
|
|
{
|
|
for (uint32_t i = 0; i < ELEMENTS; i++) {
|
|
if (_map[i].valid()) { continue; }
|
|
|
|
_map[i] = Element(i, ds_cap, va);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Ram remove(void *va)
|
|
{
|
|
Ram cap;
|
|
|
|
for (uint32_t i = 0; i < ELEMENTS; i++) {
|
|
if (_map[i].va != va) { continue; }
|
|
|
|
cap = _map[i].ds_cap;
|
|
_map[i] = Element();
|
|
break;
|
|
}
|
|
|
|
return cap;
|
|
}
|
|
|
|
Element *phys_addr(void *va)
|
|
{
|
|
for (uint32_t i = 0; i < ELEMENTS; i++) {
|
|
if (_map[i].va == va) { return &_map[i]; }
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
Element *virt_addr(void *pa)
|
|
{
|
|
for (uint32_t i = 0; i < ELEMENTS; i++) {
|
|
if (_map[i].pa == pa) { return &_map[i]; }
|
|
}
|
|
return nullptr;
|
|
}
|
|
};
|
|
|
|
#endif /* _UTILS_H_ */
|