Beispiel #1
0
func (pcidevice *PciDevice) Attach(vm *platform.Vm, model *Model) error {

	// Find our pcibus.
	var ok bool
	var pcibus *PciBus
	for _, device := range model.devices {
		pcibus, ok = device.(*PciBus)
		if pcibus != nil && ok {
			break
		}
	}
	if pcibus == nil {
		return PciBusNotFound
	}

	// Rebuild our capabilities.
	pcidevice.RebuildCapabilities()

	// FIXME: Everything uses interrupt 1.
	// This is gross, but we hard-coded the line to 1
	// unless you're using MSI. This really should be
	// fixed (if we actually plan on using PCI devices).
	pcidevice.Config.Set8(PciConfigOffsetInterruptLine, 1)
	pcidevice.Config.Set8(PciConfigOffsetInterruptPin, 1)
	pcidevice.std_interrupt = func() error {
		vm.Interrupt(platform.Irq(1), true)
		vm.Interrupt(platform.Irq(1), false)
		return nil
	}

	// Attach to the PciBus.
	return pcibus.AddDevice(pcidevice)
}
Beispiel #2
0
func (mmio *MmioDevice) Attach(vm *platform.Vm, model *Model) error {

	// Build our IO Handlers.
	mmio.IoHandlers = make(IoHandlers)
	for region, ops := range mmio.IoMap {
		new_region := MemoryRegion{region.Start + mmio.Offset, region.Size}
		mmio.IoHandlers[new_region] = NewIoHandler(mmio, new_region.Start, ops)
	}

	// Reserve memory regions.
	if mmio.reservations != nil {
		for _, region := range mmio.reservations {
			err := model.Reserve(
				vm,
				mmio,
				MemoryTypeReserved,
				region.Start+mmio.Offset,
				region.Size,
				nil)
			if err != nil {
				return err
			}
		}
	}

	if mmio.InterruptNumber != 0 {
		// Reserve our interrupt.
		_, ok := model.InterruptMap[mmio.InterruptNumber]
		if ok {
			// Already a device there.
			return InterruptConflict
		}
		model.InterruptMap[mmio.InterruptNumber] = mmio

	} else {
		// Find an interrupt.
		for irq := platform.Irq(16); ; irq += 1 {
			if _, ok := model.InterruptMap[irq]; !ok {
				model.InterruptMap[irq] = mmio
				mmio.InterruptNumber = irq
			}
		}
	}

	return mmio.BaseDevice.Attach(vm, model)
}