func (memory *MemoryMap) Reserve( vm *platform.Vm, device Device, memtype MemoryType, start platform.Paddr, size uint64, user []byte) error { // Verbose messages. device.Debug( "reserving (type: %d) of size %x in [%x,%x]", memtype, size, start, start.After(size-1)) // Ensure all targets are aligned. if (start.Align(platform.PageSize, false) != start) || (size%platform.PageSize != 0) { return MemoryUnaligned } // Ensure underlying map is aligned. // This may be harder to detect later on. if user != nil && uintptr(unsafe.Pointer(&user[0]))%platform.PageSize != 0 { return MemoryUnaligned } // Add the region. region := &TypedMemoryRegion{ MemoryRegion: MemoryRegion{start, size}, MemoryType: memtype, Device: device, user: user, allocated: make(map[uint64]uint64), } err := memory.Add(region) if err != nil { return err } // Do the mapping. switch region.MemoryType { case MemoryTypeUser: err = vm.MapUserMemory(region.Start, region.Size, region.user) case MemoryTypeReserved: err = vm.MapReservedMemory(region.Start, region.Size) case MemoryTypeAcpi: err = vm.MapUserMemory(region.Start, region.Size, region.user) case MemoryTypeSpecial: err = vm.MapSpecialMemory(region.Start) } return err }
func (model *Model) Handle( vm *platform.Vm, cache *IoCache, handler *IoHandler, ioevent IoEvent, addr platform.Paddr) error { if handler != nil { // Our offset from handler start. offset := addr.OffsetFrom(handler.start) // Submit our function. err := handler.queue.Submit(ioevent, offset) // Should we save this request? if ioevent.IsWrite() && err == SaveIO { err = cache.save( vm, addr, handler, ioevent, offset) } // Return to our vcpu. return err } else if !ioevent.IsWrite() { // Invalid reads return all 1's. switch ioevent.Size() { case 1: ioevent.SetData(0xff) case 2: ioevent.SetData(0xffff) case 4: ioevent.SetData(0xffffffff) case 8: ioevent.SetData(0xffffffffffffffff) } } return nil }
func (region *MemoryRegion) Contains(start platform.Paddr, size uint64) bool { return region.Start <= start && region.End() >= start.After(size) }
func (region *MemoryRegion) Overlaps(start platform.Paddr, size uint64) bool { return ((region.Start >= start && region.Start < start.After(size)) || (region.End() > start && region.End() <= start.After(size))) }