hw/x86: use PAT for write combining support

Fixes #3623
This commit is contained in:
Alexander Boettcher 2020-01-29 10:56:35 +01:00 committed by Norman Feske
parent 44ace04b95
commit e096202b1f
3 changed files with 30 additions and 6 deletions

View File

@ -279,6 +279,16 @@ unsigned Bootstrap::Platform::enable_mmu()
{
using ::Board::Cpu;
/* enable PAT if available */
Cpu::Cpuid_1_edx::access_t cpuid1 = Cpu::Cpuid_1_edx::read();
if (Cpu::Cpuid_1_edx::Pat::get(cpuid1)) {
Cpu::IA32_pat::access_t pat = Cpu::IA32_pat::read();
if (Cpu::IA32_pat::Pa1::get(pat) != Cpu::IA32_pat::Pa1::WRITE_COMBINING) {
Cpu::IA32_pat::Pa1::set(pat, Cpu::IA32_pat::Pa1::WRITE_COMBINING);
Cpu::IA32_pat::write(pat);
}
}
Cpu::Cr3::write(Cpu::Cr3::Pdb::masked((addr_t)core_pd->table_base));
addr_t const stack_base = reinterpret_cast<addr_t>(&__bootstrap_stack);

View File

@ -84,6 +84,16 @@ struct Hw::X86_64_cpu
struct Lapic : Bitfield< 11, 1> { }; /* Enable/disable local APIC */
struct Base : Bitfield< 12, 24> { }; /* Base address of APIC registers */
);
X86_64_MSR_REGISTER(IA32_pat, 0x277,
struct Pa1 : Bitfield <8, 3> {
enum { WRITE_COMBINING = 0b001 };
};
);
X86_64_CPUID_REGISTER(Cpuid_1_edx, 1, edx,
struct Pat : Bitfield<16, 1> { };
);
};
#endif /* _SRC__LIB__HW__SPEC__X86_64__CPU_H_ */

View File

@ -67,8 +67,8 @@ namespace Hw
struct P : Bitfield<0, 1> { }; /* present */
struct Rw : Bitfield<1, 1> { }; /* read/write */
struct Us : Bitfield<2, 1> { }; /* user/supervisor */
struct Pwt : Bitfield<3, 1> { }; /* write-through */
struct Pcd : Bitfield<4, 1> { }; /* cache disable */
struct Pwt : Bitfield<3, 1> { }; /* write-through or PAT defined */
struct Pcd : Bitfield<4, 1> { }; /* cache disable or PAT defined */
struct A : Bitfield<5, 1> { }; /* accessed */
struct D : Bitfield<6, 1> { }; /* dirty */
struct Xd : Bitfield<63, 1> { }; /* execute-disable */
@ -121,10 +121,12 @@ class Hw::Level_4_translation_table
static access_t create(Page_flags const &flags, addr_t const pa)
{
/* XXX: Set memory type depending on active PAT */
bool const wc = flags.cacheable == Genode::Cache_attribute::WRITE_COMBINED;
return Common::create(flags)
| G::bits(flags.global)
| Pa::masked(pa);
| Pa::masked(pa)
| Pwt::bits(wc ? 1 : 0);
}
};
@ -299,11 +301,13 @@ class Hw::Page_directory
static typename Base::access_t create(Page_flags const &flags,
addr_t const pa)
{
/* XXX: Set memory type depending on active PAT */
bool const wc = flags.cacheable == Genode::Cache_attribute::WRITE_COMBINED;
return Base::create(flags)
| Base::Ps::bits(1)
| G::bits(flags.global)
| Pa::masked(pa);
| Pa::masked(pa)
| Base::Pwt::bits(wc ? 1 : 0);
}
};