mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
hw: cache maintainance on mapping removal too
Older ARM processors like ARMv6, or Cortex A8 need to write back changes of the page-tables to physical ram because the MMU does not use the cache. This naturally needs to be done not only when adding a mapping, but on removal too. Fix #3715
This commit is contained in:
parent
03c3040a1d
commit
ff378a8c5b
@ -21,6 +21,6 @@ constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
|
||||
constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
|
||||
|
||||
void Hw::Page_table::_translation_added(unsigned long, unsigned long) { }
|
||||
void Hw::Page_table::_table_changed(unsigned long, unsigned long) { }
|
||||
|
||||
#endif /* _SRC__BOOTSTRAP__SPEC__ARM__CORTEX_A8_PAGE_TABLE_H_ */
|
||||
|
@ -21,6 +21,6 @@ constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
|
||||
constexpr bool Hw::Page_table::Descriptor_base::_smp() { return true; }
|
||||
|
||||
void Hw::Page_table::_translation_added(unsigned long, unsigned long) { }
|
||||
void Hw::Page_table::_table_changed(unsigned long, unsigned long) { }
|
||||
|
||||
#endif /* _SRC__BOOTSTRAP__SPEC__ARM__CORTEX_A9_PAGE_TABLE_H_ */
|
||||
|
@ -28,7 +28,6 @@ constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
|
||||
|
||||
|
||||
void Hw::Page_table::_translation_added(unsigned long, unsigned long) {
|
||||
Board::Cpu::clean_invalidate_data_cache(); }
|
||||
void Hw::Page_table::_table_changed(unsigned long, unsigned long) { }
|
||||
|
||||
#endif /* _SRC__BOOTSTRAP__SPEC__RPI__BOARD_H_ */
|
||||
|
@ -24,7 +24,7 @@ constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
|
||||
constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
|
||||
|
||||
void Hw::Page_table::_translation_added(unsigned long addr, unsigned long size)
|
||||
void Hw::Page_table::_table_changed(unsigned long addr, unsigned long size)
|
||||
{
|
||||
Genode::Arm_cpu::clean_data_cache_by_virt_region(addr, size);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
|
||||
constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
|
||||
|
||||
void Hw::Page_table::_translation_added(unsigned long addr, unsigned long size)
|
||||
void Hw::Page_table::_table_changed(unsigned long addr, unsigned long size)
|
||||
{
|
||||
/*
|
||||
* The Cortex-A8 CPU can't use the L1 cache on page-table
|
||||
|
@ -22,6 +22,6 @@ constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() {
|
||||
|
||||
constexpr bool Hw::Page_table::Descriptor_base::_smp() { return true; }
|
||||
|
||||
void Hw::Page_table::_translation_added(unsigned long, unsigned long) { }
|
||||
void Hw::Page_table::_table_changed(unsigned long, unsigned long) { }
|
||||
|
||||
#endif /* _CORE__SPEC__CORTEX_A9__TRANSLATION_TABLE_H_ */
|
||||
|
@ -416,7 +416,7 @@ class Hw::Page_table
|
||||
|
||||
enum { MAX_INDEX = sizeof(_entries) / sizeof(_entries[0]) - 1 };
|
||||
|
||||
static inline void _translation_added(addr_t, size_t);
|
||||
static inline void _table_changed(addr_t, size_t);
|
||||
|
||||
/**
|
||||
* Try to get entry index in 'i' for virtual offset 'vo!
|
||||
@ -457,7 +457,7 @@ class Hw::Page_table
|
||||
/* create and link page table */
|
||||
Pt & pt = alloc.construct<Pt>();
|
||||
_entries[i] = Ptd::create(alloc.phys_addr(pt));
|
||||
_translation_added((addr_t)&_entries[i], sizeof(Ptd));
|
||||
_table_changed((addr_t)&_entries[i], sizeof(Ptd));
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
||||
@ -465,7 +465,7 @@ class Hw::Page_table
|
||||
{
|
||||
Pt & pt = alloc.virt_addr<Pt>(Ptd::Pa::masked(_entries[i]));
|
||||
pt.insert_translation(vo - Section::Pa::masked(vo), pa, size, flags);
|
||||
_translation_added((addr_t)&pt, sizeof(Page_table_level_2));
|
||||
_table_changed((addr_t)&pt, sizeof(Page_table_level_2));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -532,7 +532,7 @@ class Hw::Page_table
|
||||
_entries[i] = e;
|
||||
|
||||
/* some CPUs need to act on changed translations */
|
||||
_translation_added((addr_t)&_entries[i], sizeof(Section));
|
||||
_table_changed((addr_t)&_entries[i], sizeof(Section));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -580,6 +580,7 @@ class Hw::Page_table
|
||||
|
||||
addr_t const pt_vo = vo - Section::Pa::masked(vo);
|
||||
pt.remove_translation(pt_vo, Genode::min(size, end-vo));
|
||||
_table_changed((addr_t)&pt, sizeof(Page_table_level_2));
|
||||
|
||||
if (pt.empty()) {
|
||||
Descriptor::invalidate(_entries[i]);
|
||||
@ -588,7 +589,12 @@ class Hw::Page_table
|
||||
break;
|
||||
}
|
||||
|
||||
default: Descriptor::invalidate(_entries[i]); }
|
||||
default:
|
||||
{
|
||||
Descriptor::invalidate(_entries[i]);
|
||||
_table_changed((addr_t)&_entries[i], sizeof(Section));
|
||||
}
|
||||
}
|
||||
|
||||
/* check whether we wrap */
|
||||
if (end < vo) return;
|
||||
|
Loading…
Reference in New Issue
Block a user