mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-11 20:01:48 +00:00
committed by
Christian Helmuth
parent
90390fe053
commit
998dfa6c5e
@ -35,7 +35,13 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
inline bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages)
|
inline bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages)
|
||||||
{
|
{
|
||||||
platform_specific()->core_vm_space().map(from_phys, to_virt, num_pages);
|
enum { DONT_FLUSH = false };
|
||||||
|
try {
|
||||||
|
platform_specific()->core_vm_space().map(from_phys, to_virt,
|
||||||
|
num_pages, DONT_FLUSH);
|
||||||
|
} catch (Page_table_registry::Mapping_cache_full) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <base/exception.h>
|
#include <base/exception.h>
|
||||||
|
#include <base/log.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
@ -30,6 +31,7 @@ class Genode::Page_table_registry
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
class Lookup_failed : Exception { };
|
class Lookup_failed : Exception { };
|
||||||
|
class Mapping_cache_full : Exception { };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -93,7 +95,11 @@ class Genode::Page_table_registry
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
_entries.insert(new (entry_alloc) Entry(addr, sel));
|
_entries.insert(new (entry_alloc) Entry(addr, sel));
|
||||||
|
} catch (Genode::Allocator::Out_of_memory) {
|
||||||
|
throw Mapping_cache_full();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_entry(Allocator &entry_alloc, addr_t addr)
|
void remove_entry(Allocator &entry_alloc, addr_t addr)
|
||||||
@ -107,6 +113,14 @@ class Genode::Page_table_registry
|
|||||||
PWRN("trying to remove non-existing page frame for 0x%lx", addr);
|
PWRN("trying to remove non-existing page frame for 0x%lx", addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush_all(Allocator &entry_alloc)
|
||||||
|
{
|
||||||
|
for (; Entry *entry = _entries.first();) {
|
||||||
|
_entries.remove(entry);
|
||||||
|
destroy(entry_alloc, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -257,6 +271,13 @@ class Genode::Page_table_registry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void flush_cache()
|
||||||
|
{
|
||||||
|
for (Page_table *pt = _page_tables.first(); pt; pt = pt->next())
|
||||||
|
pt->flush_all(_page_table_entry_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply functor 'fn' to selector of specified virtual address
|
* Apply functor 'fn' to selector of specified virtual address
|
||||||
*
|
*
|
||||||
|
@ -148,7 +148,7 @@ class Genode::Vm_space
|
|||||||
*/
|
*/
|
||||||
unsigned _idx_to_sel(unsigned idx) const { return (_id << 20) | idx; }
|
unsigned _idx_to_sel(unsigned idx) const { return (_id << 20) | idx; }
|
||||||
|
|
||||||
void _map_page(addr_t from_phys, addr_t to_virt)
|
void _map_page(addr_t from_phys, addr_t to_virt, bool flush_support)
|
||||||
{
|
{
|
||||||
/* allocate page-table entry selector */
|
/* allocate page-table entry selector */
|
||||||
unsigned pte_idx = _sel_alloc.alloc();
|
unsigned pte_idx = _sel_alloc.alloc();
|
||||||
@ -164,7 +164,19 @@ class Genode::Vm_space
|
|||||||
Cnode_index(_leaf_cnode_entry(pte_idx)));
|
Cnode_index(_leaf_cnode_entry(pte_idx)));
|
||||||
|
|
||||||
/* remember relationship between pte_sel and the virtual address */
|
/* remember relationship between pte_sel and the virtual address */
|
||||||
|
try {
|
||||||
_page_table_registry.insert_page_table_entry(to_virt, pte_idx);
|
_page_table_registry.insert_page_table_entry(to_virt, pte_idx);
|
||||||
|
} catch (Page_table_registry::Mapping_cache_full) {
|
||||||
|
if (!flush_support)
|
||||||
|
throw;
|
||||||
|
|
||||||
|
warning("flush page table entries - mapping cache full");
|
||||||
|
|
||||||
|
_page_table_registry.flush_cache();
|
||||||
|
|
||||||
|
/* re-try once */
|
||||||
|
_page_table_registry.insert_page_table_entry(to_virt, pte_idx);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert copy of page-frame selector into page table
|
* Insert copy of page-frame selector into page table
|
||||||
@ -300,7 +312,8 @@ class Genode::Vm_space
|
|||||||
_vm_cnodes[i].destruct(_cap_sel_alloc);
|
_vm_cnodes[i].destruct(_cap_sel_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void map(addr_t from_phys, addr_t to_virt, size_t num_pages)
|
void map(addr_t from_phys, addr_t to_virt, size_t num_pages,
|
||||||
|
bool flush_support = true)
|
||||||
{
|
{
|
||||||
Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
@ -310,7 +323,7 @@ class Genode::Vm_space
|
|||||||
|
|
||||||
for (size_t i = 0; i < num_pages; i++) {
|
for (size_t i = 0; i < num_pages; i++) {
|
||||||
off_t const offset = i << get_page_size_log2();
|
off_t const offset = i << get_page_size_log2();
|
||||||
_map_page(from_phys + offset, to_virt + offset);
|
_map_page(from_phys + offset, to_virt + offset, flush_support);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
#include <ram_session_component.h>
|
#include <ram_session_component.h>
|
||||||
@ -43,14 +43,18 @@ void Ram_session_component::_clear_ds (Dataspace_component *ds)
|
|||||||
/* allocate range in core's virtual address space */
|
/* allocate range in core's virtual address space */
|
||||||
void *virt_addr;
|
void *virt_addr;
|
||||||
if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) {
|
if (!platform()->region_alloc()->alloc(page_rounded_size, &virt_addr)) {
|
||||||
PERR("could not allocate virtual address range in core of size %zd\n",
|
error("could not allocate virtual address range in core of size ",
|
||||||
page_rounded_size);
|
page_rounded_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map the dataspace's physical pages to core-local virtual addresses */
|
/* map the dataspace's physical pages to core-local virtual addresses */
|
||||||
size_t num_pages = page_rounded_size >> get_page_size_log2();
|
size_t num_pages = page_rounded_size >> get_page_size_log2();
|
||||||
map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages);
|
if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages)) {
|
||||||
|
error("could not map virtual address range in core of size ",
|
||||||
|
page_rounded_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* clear dataspace */
|
/* clear dataspace */
|
||||||
size_t num_longwords = page_rounded_size/sizeof(long);
|
size_t num_longwords = page_rounded_size/sizeof(long);
|
||||||
|
Reference in New Issue
Block a user