mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
74 lines
1.7 KiB
Go
74 lines
1.7 KiB
Go
package vmm
|
|
|
|
import (
|
|
"runtime"
|
|
"testing"
|
|
"unsafe"
|
|
|
|
"github.com/achilleasa/gopher-os/kernel/mem/pmm"
|
|
)
|
|
|
|
func TestTranslateAmd64(t *testing.T) {
|
|
if runtime.GOARCH != "amd64" {
|
|
t.Skip("test requires amd64 runtime; skipping")
|
|
}
|
|
|
|
defer func(origPtePtr func(uintptr) unsafe.Pointer) {
|
|
ptePtrFn = origPtePtr
|
|
}(ptePtrFn)
|
|
|
|
// the virtual address just contains the page offset
|
|
virtAddr := uintptr(1234)
|
|
expFrame := pmm.Frame(42)
|
|
expPhysAddr := expFrame.Address() + virtAddr
|
|
specs := [][pageLevels]bool{
|
|
{true, true, true, true},
|
|
{false, true, true, true},
|
|
{true, false, true, true},
|
|
{true, true, false, true},
|
|
{true, true, true, false},
|
|
}
|
|
|
|
for specIndex, spec := range specs {
|
|
pteCallCount := 0
|
|
ptePtrFn = func(entry uintptr) unsafe.Pointer {
|
|
var pte pageTableEntry
|
|
pte.SetFrame(expFrame)
|
|
if specs[specIndex][pteCallCount] {
|
|
pte.SetFlags(FlagPresent)
|
|
}
|
|
pteCallCount++
|
|
|
|
return unsafe.Pointer(&pte)
|
|
}
|
|
|
|
// An error is expected if any page level contains a non-present page
|
|
expError := false
|
|
for _, hasMapping := range spec {
|
|
if !hasMapping {
|
|
expError = true
|
|
break
|
|
}
|
|
}
|
|
|
|
physAddr, err := Translate(virtAddr)
|
|
switch {
|
|
case expError && err != ErrInvalidMapping:
|
|
t.Errorf("[spec %d] expected to get ErrInvalidMapping; got %v", specIndex, err)
|
|
case !expError && err != nil:
|
|
t.Errorf("[spec %d] unexpected error %v", specIndex, err)
|
|
case !expError && physAddr != expPhysAddr:
|
|
t.Errorf("[spec %d] expected phys addr to be 0x%x; got 0x%x", specIndex, expPhysAddr, physAddr)
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
phys, err := vmm.Translate(uintptr(100 * mem.Mb))
|
|
if err != nil {
|
|
early.Printf("err: %s\n", err.Error())
|
|
} else {
|
|
early.Printf("phys: 0x%x\n", phys)
|
|
}
|
|
*/
|