blob: 2ab133330e8e3384b9864a6a584d66c42a00f75d [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "mmu.h"
#include <lib/page-table/internal/bits.h>
#include <zircon/types.h>
namespace page_table::x86 {
bool PageTableEntry::is_page(int8_t level) const {
// Top level doesn't support pages.
if (level == kPageTableLevels - 1) {
return false;
}
// Bottom level only supports pages.
if (level == 0) {
return true;
}
return internal::ExtractBit(kPageBitIndex.at(level), raw);
}
PageTableEntry& PageTableEntry::set_is_page(int8_t level, bool value) {
// Top level doesn't support pages.
if (level == kPageTableLevels - 1) {
ZX_DEBUG_ASSERT(!value);
return *this;
}
// Bottom level only supports pages.
if (level == 0) {
ZX_DEBUG_ASSERT(value);
return *this;
}
raw = internal::SetBit(kPageBitIndex.at(level), /*word=*/raw, /*bit=*/value ? 1 : 0);
return *this;
}
uint64_t PageTableEntry::pat(int8_t level) const {
int index = kPatBitIndex.at(level);
ZX_DEBUG_ASSERT(index >= 0);
return internal::ExtractBit(index, raw);
}
PageTableEntry& PageTableEntry::set_pat(int8_t level, uint64_t value) {
int index = kPatBitIndex.at(level);
ZX_DEBUG_ASSERT(index >= 0);
raw = internal::SetBit(/*index=*/index, /*word=*/raw, /*bit=*/value);
return *this;
}
uint64_t PageTableEntry::page_paddr(int8_t level) const {
return internal::ExtractBits(kPhysAddressBits, PageLevelBits(level), raw) << PageLevelBits(level);
}
PageTableEntry& PageTableEntry::set_page_paddr(int8_t level, uint64_t value) {
ZX_DEBUG_ASSERT(value % (1 << PageLevelBits(level)) == 0);
raw = internal::ClearBits(/*high=*/kPhysAddressBits, /*low=*/PageLevelBits(level), raw) | value;
return *this;
}
} // namespace page_table::x86