1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

Define page table entry type

This commit is contained in:
Achilleas Anagnostopoulos 2017-06-02 08:15:59 +01:00
parent b67a2045b9
commit 35eaa1a13c
2 changed files with 105 additions and 0 deletions

44
kernel/mem/vmm/pte.go Normal file
View File

@ -0,0 +1,44 @@
package vmm
import (
"github.com/achilleasa/gopher-os/kernel/mem"
"github.com/achilleasa/gopher-os/kernel/mem/pmm"
)
// PageTableEntryFlag describes a flag that can be applied to a page table entry.
type PageTableEntryFlag uintptr
// pageTableEntry describes a page table entry. These entries encode
// a physical frame address and a set of flags. The actual format
// of the entry and flags is architecture-dependent.
type pageTableEntry uintptr
// HasFlags returns true if this entry has all the input flags set.
func (pte pageTableEntry) HasFlags(flags PageTableEntryFlag) bool {
return (uintptr(pte) & uintptr(flags)) == uintptr(flags)
}
// HasAnyFlag returns true if this entry has at least one of the input flags set.
func (pte pageTableEntry) HasAnyFlag(flags PageTableEntryFlag) bool {
return (uintptr(pte) & uintptr(flags)) != 0
}
// SetFlags sets the input list of flags to the page table entry.
func (pte *pageTableEntry) SetFlags(flags PageTableEntryFlag) {
*pte = (pageTableEntry)(uintptr(*pte) | uintptr(flags))
}
// ClearFlags unsets the input list of flags from the page table entry.
func (pte *pageTableEntry) ClearFlags(flags PageTableEntryFlag) {
*pte = (pageTableEntry)(uintptr(*pte) &^ uintptr(flags))
}
// Frame returns the physical page frame that this page table entry points to.
func (pte pageTableEntry) Frame() pmm.Frame {
return pmm.Frame((uintptr(pte) & ptePhysPageMask) >> mem.PageShift)
}
// SetFrame updates the page table entry to point the the given physical frame .
func (pte *pageTableEntry) SetFrame(frame pmm.Frame) {
*pte = (pageTableEntry)((uintptr(*pte) &^ ptePhysPageMask) | frame.Address())
}

View File

@ -0,0 +1,61 @@
package vmm
import (
"testing"
"github.com/achilleasa/gopher-os/kernel/mem/pmm"
)
func TestPageTableEntryFlags(t *testing.T) {
var (
pte pageTableEntry
flag1 = PageTableEntryFlag(1 << 10)
flag2 = PageTableEntryFlag(1 << 21)
)
if pte.HasAnyFlag(flag1 | flag2) {
t.Fatalf("expected HasAnyFlags to return false")
}
pte.SetFlags(flag1 | flag2)
if !pte.HasAnyFlag(flag1 | flag2) {
t.Fatalf("expected HasAnyFlags to return true")
}
if !pte.HasFlags(flag1 | flag2) {
t.Fatalf("expected HasFlags to return true")
}
pte.ClearFlags(flag1)
if !pte.HasAnyFlag(flag1 | flag2) {
t.Fatalf("expected HasAnyFlags to return true")
}
if pte.HasFlags(flag1 | flag2) {
t.Fatalf("expected HasFlags to return false")
}
pte.ClearFlags(flag1 | flag2)
if pte.HasAnyFlag(flag1 | flag2) {
t.Fatalf("expected HasAnyFlags to return false")
}
if pte.HasFlags(flag1 | flag2) {
t.Fatalf("expected HasFlags to return false")
}
}
func TestPageTableEntryFrameEncoding(t *testing.T) {
var (
pte pageTableEntry
physFrame = pmm.Frame(123)
)
pte.SetFrame(physFrame)
if got := pte.Frame(); got != physFrame {
t.Fatalf("expected pte.Frame() to return %v; got %v", physFrame, got)
}
}