1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00
gopher-os/kernel/mem/pmm/bootmem_allocator_test.go
Achilleas Anagnostopoulos d7eb2547dd Change the Frame type to uintptr and remove Size/Order methods
To keep the implementation portable, the Frame type had to be changed
from uint64 to uintptr. Using uintptr ensures that the frame will always
match the pointer size of the platform.
2017-05-31 15:07:09 +01:00

86 lines
3.0 KiB
Go

package pmm
import (
"testing"
"unsafe"
"github.com/achilleasa/gopher-os/kernel/driver/video/console"
"github.com/achilleasa/gopher-os/kernel/hal"
"github.com/achilleasa/gopher-os/kernel/hal/multiboot"
"github.com/achilleasa/gopher-os/kernel/mem"
)
func TestBootMemoryAllocator(t *testing.T) {
// Mock a tty to handle early.Printf output
mockConsoleFb := make([]byte, 160*25)
mockConsole := &console.Ega{}
mockConsole.Init(80, 25, uintptr(unsafe.Pointer(&mockConsoleFb[0])))
hal.ActiveTerminal.AttachTo(mockConsole)
multiboot.SetInfoPtr(uintptr(unsafe.Pointer(&multibootMemoryMap[0])))
var totalFreeFrames uint64
multiboot.VisitMemRegions(func(region *multiboot.MemoryMapEntry) bool {
if region.Type == multiboot.MemAvailable {
regionStartFrameIndex := uint64(((mem.Size(region.PhysAddress) + (mem.PageSize - 1)) & ^(mem.PageSize - 1)) >> mem.PageShift)
regionEndFrameIndex := uint64(((mem.Size(region.PhysAddress+region.Length) - (mem.PageSize - 1)) & ^(mem.PageSize - 1)) >> mem.PageShift)
totalFreeFrames += regionEndFrameIndex - regionStartFrameIndex + 1
}
return true
})
var (
alloc BootMemAllocator
allocFrameCount uint64
)
for alloc.Init(); ; allocFrameCount++ {
frame, ok := alloc.AllocFrame(mem.PageOrder(0))
if !ok {
break
}
expAddress := uintptr(uint64(alloc.lastAllocIndex) * uint64(mem.PageSize))
if got := frame.Address(); got != expAddress {
t.Errorf("[frame %d] expected frame address to be 0x%x; got 0x%x", allocFrameCount, expAddress, got)
}
if !frame.IsValid() {
t.Errorf("[frame %d] expected IsValid() to return true", allocFrameCount)
}
}
if allocFrameCount != totalFreeFrames {
t.Fatalf("expected allocator to allocate %d frames; allocated %d", totalFreeFrames, allocFrameCount)
}
// This allocator only works with order(0) blocks
if frame, ok := alloc.AllocFrame(mem.PageOrder(1)); ok || frame.IsValid() {
t.Fatalf("expected allocator to return false and an invalid frame when requested to allocate a block with order > 0; got %t, %v", ok, frame)
}
}
var (
// A dump of multiboot data when running under qemu containing only the memory region tag.
multibootMemoryMap = []byte{
72, 5, 0, 0, 0, 0, 0, 0,
6, 0, 0, 0, 160, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 9, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 252, 9, 0, 0, 0, 0, 0,
0, 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0,
0, 0, 238, 7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 254, 7, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 255, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
9, 0, 0, 0, 212, 3, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0,
21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0,
1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 16, 0, 0, 16, 0, 0,
24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
}
)