parent
909c2dbc95
commit
de87fa1b5c
|
@ -398,47 +398,43 @@ namespace Arm
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove translations, wich overlap with a given virtual region
|
* Remove translations that overlap with a given virtual region
|
||||||
*
|
*
|
||||||
* \param vo offset of the virtual region within the region
|
* \param vo region offset within the tables virtual region
|
||||||
* represented by this table
|
|
||||||
* \param size region size
|
* \param size region size
|
||||||
*/
|
*/
|
||||||
void remove_region(addr_t const vo, size_t const size)
|
void remove_region(addr_t vo, size_t const size)
|
||||||
{
|
{
|
||||||
/* traverse all possibly affected entries */
|
addr_t const ve = vo + size;
|
||||||
addr_t residual_vo = vo;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* check if anything is left over to remove */
|
if (vo >= ve) { return; }
|
||||||
if (residual_vo >= vo + size) return;
|
if (_index_by_vo(i, vo)) { return; }
|
||||||
|
addr_t next_vo;
|
||||||
/* check if residual region overlaps with table */
|
|
||||||
if (_index_by_vo(i, residual_vo)) return;
|
|
||||||
|
|
||||||
/* update current entry and recalculate residual region */
|
|
||||||
switch (Descriptor::type(_entries[i])) {
|
switch (Descriptor::type(_entries[i])) {
|
||||||
|
|
||||||
case Descriptor::FAULT: {
|
case Descriptor::FAULT: {
|
||||||
|
|
||||||
residual_vo = (residual_vo & Fault::VIRT_BASE_MASK)
|
vo &= Fault::VIRT_BASE_MASK;
|
||||||
+ Fault::VIRT_SIZE;
|
next_vo = vo + Fault::VIRT_SIZE;
|
||||||
break; }
|
break; }
|
||||||
|
|
||||||
case Descriptor::SMALL_PAGE: {
|
case Descriptor::SMALL_PAGE: {
|
||||||
|
|
||||||
residual_vo = (residual_vo & Small_page::VIRT_BASE_MASK)
|
vo &= Small_page::VIRT_BASE_MASK;
|
||||||
+ Small_page::VIRT_SIZE;
|
|
||||||
Descriptor::invalidate(_entries[i]);
|
Descriptor::invalidate(_entries[i]);
|
||||||
|
next_vo = vo + Small_page::VIRT_SIZE;
|
||||||
break; }
|
break; }
|
||||||
|
|
||||||
case Descriptor::LARGE_PAGE: {
|
case Descriptor::LARGE_PAGE: {
|
||||||
|
|
||||||
PDBG("Removal of large pages not implemented");
|
PDBG("large pages not supported by now");
|
||||||
while (1) ;
|
while (1) ;
|
||||||
break; }
|
break; }
|
||||||
}
|
}
|
||||||
|
if (next_vo < vo) { return; }
|
||||||
|
vo = next_vo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,63 +796,55 @@ namespace Arm
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove translations, wich overlap with a given virtual region
|
* Remove translations that overlap with a given virtual region
|
||||||
*
|
*
|
||||||
* \param vo offset of the virtual region within the region
|
* \param vo region offset within the tables virtual region
|
||||||
* represented by this table
|
|
||||||
* \param size region size
|
* \param size region size
|
||||||
*/
|
*/
|
||||||
void remove_region(addr_t const vo, size_t const size)
|
void remove_region(addr_t vo, size_t const size)
|
||||||
{
|
{
|
||||||
/* traverse all possibly affected entries */
|
addr_t const ve = vo + size;
|
||||||
addr_t residual_vo = vo;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* check if anything is left over to remove */
|
if (vo >= ve) { return; }
|
||||||
if (residual_vo >= vo + size) return;
|
if (_index_by_vo(i, vo)) { return; }
|
||||||
|
addr_t next_vo;
|
||||||
|
switch (Descriptor::type(_entries[i])) {
|
||||||
|
|
||||||
/* check if the residual region overlaps with this table */
|
case Descriptor::FAULT: {
|
||||||
if (_index_by_vo(i, residual_vo)) return;
|
|
||||||
|
|
||||||
/* update current entry and recalculate residual region */
|
vo &= Fault::VIRT_BASE_MASK;
|
||||||
switch (Descriptor::type(_entries[i]))
|
next_vo = vo + Fault::VIRT_SIZE;
|
||||||
{
|
break; }
|
||||||
case Descriptor::FAULT:
|
|
||||||
{
|
|
||||||
residual_vo = (residual_vo & Fault::VIRT_BASE_MASK)
|
|
||||||
+ Fault::VIRT_SIZE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Descriptor::PAGE_TABLE:
|
|
||||||
{
|
|
||||||
/* instruct page table to remove residual region */
|
|
||||||
Page_table * const pt = (Page_table *)
|
|
||||||
(addr_t)Page_table_descriptor::Pa_31_10::masked(_entries[i]);
|
|
||||||
size_t const residual_size = vo + size - residual_vo;
|
|
||||||
addr_t const pt_vo = residual_vo
|
|
||||||
- Section::Pa_31_20::masked(residual_vo);
|
|
||||||
pt->remove_region(pt_vo, residual_size);
|
|
||||||
|
|
||||||
/* recalculate residual region */
|
case Descriptor::PAGE_TABLE: {
|
||||||
residual_vo = (residual_vo & Page_table::VIRT_BASE_MASK)
|
|
||||||
+ Page_table::VIRT_SIZE;
|
typedef Page_table_descriptor Ptd;
|
||||||
break;
|
typedef Page_table Pt;
|
||||||
}
|
|
||||||
case Descriptor::SECTION:
|
vo &= Pt::VIRT_BASE_MASK;
|
||||||
{
|
Pt * const pt = (Pt *)Ptd::Pa_31_10::masked(_entries[i]);
|
||||||
|
addr_t const pt_vo = vo - Section::Pa_31_20::masked(vo);
|
||||||
|
pt->remove_region(pt_vo, ve - vo);
|
||||||
|
next_vo = vo + Pt::VIRT_SIZE;
|
||||||
|
break; }
|
||||||
|
|
||||||
|
case Descriptor::SECTION: {
|
||||||
|
|
||||||
|
vo &= Section::VIRT_BASE_MASK;
|
||||||
Descriptor::invalidate(_entries[i]);
|
Descriptor::invalidate(_entries[i]);
|
||||||
residual_vo = (residual_vo & Section::VIRT_BASE_MASK)
|
next_vo = vo + Section::VIRT_SIZE;
|
||||||
+ Section::VIRT_SIZE;
|
break; }
|
||||||
break;
|
|
||||||
}
|
case Descriptor::SUPERSECTION: {
|
||||||
case Descriptor::SUPERSECTION:
|
|
||||||
{
|
PDBG("supersections not supported by now");
|
||||||
PDBG("Removal of supersections not implemented");
|
while (1) { }
|
||||||
while (1);
|
break; }
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (next_vo < vo) { return; }
|
||||||
|
vo = next_vo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user