mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
7441aba6d5
commit
29e21bff7f
@ -403,6 +403,41 @@ void Intel::Io_mmu::default_mappings_complete()
|
||||
}
|
||||
|
||||
|
||||
void Intel::Io_mmu::suspend()
|
||||
{
|
||||
_s3_fec = read<Fault_event_control>();
|
||||
_s3_fedata = read<Fault_event_data>();
|
||||
_s3_feaddr = read<Fault_event_address>();
|
||||
_s3_rta = read<Root_table_address>();
|
||||
}
|
||||
|
||||
|
||||
void Intel::Io_mmu::resume()
|
||||
{
|
||||
/* disable queued invalidation interface if it was re-enabled by kernel */
|
||||
if (read<Global_status::Enabled>() && read<Global_status::Qies>())
|
||||
_global_command<Global_command::Qie>(false);
|
||||
|
||||
/* restore fault events only if kernel did not enable IRQ remapping */
|
||||
if (!read<Global_status::Ires>()) {
|
||||
write<Fault_event_control>(_s3_fec);
|
||||
write<Fault_event_data>(_s3_fedata);
|
||||
write<Fault_event_address>(_s3_feaddr);
|
||||
}
|
||||
|
||||
/* issue set root table pointer command */
|
||||
write<Root_table_address>(_s3_rta);
|
||||
_global_command<Global_command::Srtp>(1);
|
||||
|
||||
if (!read<Capability::Esrtps>())
|
||||
invalidate_all();
|
||||
|
||||
/* enable IOMMU */
|
||||
if (!read<Global_status::Enabled>())
|
||||
_global_command<Global_command::Enable>(1);
|
||||
}
|
||||
|
||||
|
||||
Intel::Io_mmu::Io_mmu(Env & env,
|
||||
Io_mmu_devices & io_mmu_devices,
|
||||
Device::Name const & name,
|
||||
|
@ -408,6 +408,12 @@ class Intel::Io_mmu : private Attached_mmio<0x800>,
|
||||
struct Did : Bitfield<32,16> { };
|
||||
|
||||
};
|
||||
|
||||
/* saved registers during suspend */
|
||||
Fault_event_control::access_t _s3_fec { };
|
||||
Fault_event_data ::access_t _s3_fedata { };
|
||||
Fault_event_address ::access_t _s3_feaddr { };
|
||||
Root_table_address::access_t _s3_rta { };
|
||||
|
||||
uint32_t _max_domains() {
|
||||
return 1 << (4 + read<Capability::Domains>()*2); }
|
||||
@ -543,6 +549,12 @@ class Intel::Io_mmu : private Attached_mmio<0x800>,
|
||||
|
||||
void flush_write_buffer();
|
||||
|
||||
/**
|
||||
* Io_mmu suspend/resume interface
|
||||
*/
|
||||
void suspend() override;
|
||||
void resume() override;
|
||||
|
||||
/**
|
||||
* Io_mmu interface for default mappings
|
||||
*/
|
||||
|
@ -100,7 +100,17 @@ void Driver::Main::_system_update()
|
||||
_reset();
|
||||
|
||||
if (state == "suspend") {
|
||||
/* save IOMMU state */
|
||||
_common.io_mmu_devices().for_each([&] (Driver::Io_mmu & io_mmu) {
|
||||
io_mmu.suspend();
|
||||
});
|
||||
|
||||
try { _suspend("S3"); } catch (...) { error("suspend failed"); }
|
||||
|
||||
/* re-initialise IOMMU independent of result */
|
||||
_common.io_mmu_devices().for_each([&] (Driver::Io_mmu & io_mmu) {
|
||||
io_mmu.resume();
|
||||
});
|
||||
/* report independent of result */
|
||||
_common.report_resume();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user