mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
/* Genode includes */
|
||||
#include <util/list.h>
|
||||
#include <base/exception.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <util.h>
|
||||
@ -30,6 +31,7 @@ class Genode::Page_table_registry
|
||||
public:
|
||||
|
||||
class Lookup_failed : Exception { };
|
||||
class Mapping_cache_full : Exception { };
|
||||
|
||||
private:
|
||||
|
||||
@ -93,7 +95,11 @@ class Genode::Page_table_registry
|
||||
return;
|
||||
}
|
||||
|
||||
_entries.insert(new (entry_alloc) Entry(addr, sel));
|
||||
try {
|
||||
_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)
|
||||
@ -107,6 +113,14 @@ class Genode::Page_table_registry
|
||||
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
|
||||
*
|
||||
|
@ -148,7 +148,7 @@ class Genode::Vm_space
|
||||
*/
|
||||
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 */
|
||||
unsigned pte_idx = _sel_alloc.alloc();
|
||||
@ -164,7 +164,19 @@ class Genode::Vm_space
|
||||
Cnode_index(_leaf_cnode_entry(pte_idx)));
|
||||
|
||||
/* remember relationship between pte_sel and the virtual address */
|
||||
_page_table_registry.insert_page_table_entry(to_virt, pte_idx);
|
||||
try {
|
||||
_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
|
||||
@ -300,7 +312,8 @@ class Genode::Vm_space
|
||||
_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);
|
||||
|
||||
@ -310,7 +323,7 @@ class Genode::Vm_space
|
||||
|
||||
for (size_t i = 0; i < num_pages; i++) {
|
||||
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 */
|
||||
#include <base/printf.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* core includes */
|
||||
#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 */
|
||||
void *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",
|
||||
page_rounded_size);
|
||||
error("could not allocate virtual address range in core of size ",
|
||||
page_rounded_size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* map the dataspace's physical pages to core-local virtual addresses */
|
||||
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 */
|
||||
size_t num_longwords = page_rounded_size/sizeof(long);
|
||||
|
Loading…
x
Reference in New Issue
Block a user