func (vcpu *Vcpu) SetFpuState(state Fpu) error { // Prepare our data. var kvm_fpu C.struct_kvm_fpu for i := 0; i < len(state.FPR); i += 1 { for j := 0; j < len(state.FPR[i]); j += 1 { kvm_fpu.fpr[i][j] = C.__u8(state.FPR[i][j]) } } kvm_fpu.fcw = C.__u16(state.FCW) kvm_fpu.fsw = C.__u16(state.FSW) kvm_fpu.ftwx = C.__u8(state.FTWX) kvm_fpu.last_opcode = C.__u16(state.LastOpcode) kvm_fpu.last_ip = C.__u64(state.LastIp) kvm_fpu.last_dp = C.__u64(state.LastDp) for i := 0; i < len(state.XMM); i += 1 { for j := 0; j < len(state.XMM[i]); j += 1 { kvm_fpu.xmm[i][j] = C.__u8(state.XMM[i][j]) } } kvm_fpu.mxcsr = C.__u32(state.MXCSR) // Execute the ioctl. _, _, e := syscall.Syscall( syscall.SYS_IOCTL, uintptr(vcpu.fd), uintptr(C.IoctlSetFpu), uintptr(unsafe.Pointer(&kvm_fpu))) if e != 0 { return e } return nil }
// This command selects a device register (through the cmd byte), sends // 1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return. func (smb SMBus) Block_process_call(cmd byte, buf []byte) ([]byte, error) { smb.Set_addr(smb.addr) ret, err := C.i2c_smbus_block_process_call(C.int(smb.bus.Fd()), C.__u8(cmd), C.__u8(len(buf)), ((*C.__u8)(&buf[0]))) if err != nil { return nil, err } else { return buf[:ret], nil } }
// This command selects a device register (through the cmd byte), sends // 16 bits of data to it, and reads 16 bits of data in return. func (smb SMBus) Process_call(cmd byte, value uint16) (uint16, error) { smb.Set_addr(smb.addr) ret, err := C.i2c_smbus_process_call(C.int(smb.bus.Fd()), C.__u8(cmd), C.__u16(value)) if err != nil { ret = 0 } return uint16(ret & 0x0FFFF), err }
// This operation is very like Read Byte; again, data is read from a // device, from a designated register that is specified through the cmd // byte. But this time, the data is a complete word (16 bits). func (smb *SMBus) Read_word_data(cmd byte) (uint16, error) { smb.Set_addr(smb.addr) ret, err := C.i2c_smbus_read_word_data(C.int(smb.bus.Fd()), C.__u8(cmd)) if err != nil { ret = 0 } return uint16(ret & 0x0FFFF), err }
// Reads a single byte from a device, from a designated register. // The register is specified through the cmd byte func (smb SMBus) Read_byte_data(cmd byte) (byte, error) { smb.Set_addr(smb.addr) ret, err := C.i2c_smbus_read_byte_data(C.int(smb.bus.Fd()), C.__u8(cmd)) if err != nil { ret = 0 } return byte(ret & 0x0FF), err }
// This command reads a block of up to 32 bytes from a device, from a // designated register that is specified through the cmd byte. The amount // of data in byte is specified by the length of the buf slice. // To read 4 bytes of data, pass a slice created like this: make([]byte, 4) func (smb SMBus) Read_block_data(cmd byte, buf []byte) (int, error) { smb.Set_addr(smb.addr) ret, err := C.i2c_smbus_read_block_data( C.int(smb.bus.Fd()), C.__u8(cmd), (*C.__u8)(unsafe.Pointer(&buf[0])), ) return int(ret), err }
func (vcpu *Vcpu) Translate( vaddr Vaddr) (Paddr, bool, bool, bool, error) { // Perform the translation. var translation C.struct_kvm_translation translation.linear_address = C.__u64(vaddr) _, _, e := syscall.Syscall( syscall.SYS_IOCTL, uintptr(vcpu.fd), uintptr(C.IoctlTranslate), uintptr(unsafe.Pointer(&translation))) if e != 0 { return Paddr(0), false, false, false, e } paddr := Paddr(translation.physical_address) valid := translation.valid != C.__u8(0) writeable := translation.writeable != C.__u8(0) usermode := translation.valid != C.__u8(0) return paddr, valid, writeable, usermode, nil }
func (i2c *I2C) smbusAccess(readWrite, register uint8, size int, data unsafe.Pointer) (uintptr, error) { args := C.struct_i2c_smbus_ioctl_data{ read_write: C.char(readWrite), command: C.__u8(register), size: C.int(size), data: (*C.union_i2c_smbus_data)(data), } result, _, errno := syscall.Syscall(syscall.SYS_IOCTL, i2c.file.Fd(), C.I2C_SMBUS, uintptr(unsafe.Pointer(&args))) if int(result) == -1 { return 0, errno } return result, nil }
func (vcpu *Vcpu) GetEvents() (Events, error) { // Execute the ioctl. var kvm_events C.struct_kvm_vcpu_events _, _, e := syscall.Syscall( syscall.SYS_IOCTL, uintptr(vcpu.fd), uintptr(C.IoctlGetVcpuEvents), uintptr(unsafe.Pointer(&kvm_events))) if e != 0 { return Events{}, e } // Prepare our state. events := Events{ NmiPending: kvm_events.nmi.pending != C.__u8(0), NmiMasked: kvm_events.nmi.masked != C.__u8(0), SipiVector: uint32(kvm_events.sipi_vector), Flags: uint32(kvm_events.flags), } if kvm_events.exception.injected != C.__u8(0) { events.Exception = &ExceptionEvent{ Number: uint8(kvm_events.exception.nr), } if kvm_events.exception.has_error_code != C.__u8(0) { error_code := uint32(kvm_events.exception.error_code) events.Exception.ErrorCode = &error_code } } if kvm_events.interrupt.injected != C.__u8(0) { events.Interrupt = &InterruptEvent{ Number: uint8(kvm_events.interrupt.nr), Soft: kvm_events.interrupt.soft != C.__u8(0), Shadow: kvm_events.interrupt.shadow != C.__u8(0), } } return events, nil }
func (vcpu *Vcpu) SetSegment( seg Segment, val SegmentValue, sync bool) error { err := vcpu.refreshSRegs(true) if err != nil { return err } switch seg { case CS: vcpu.sregs.cs.base = C.__u64(val.Base) vcpu.sregs.cs.limit = C.__u32(val.Limit) vcpu.sregs.cs.selector = C.__u16(val.Selector) vcpu.sregs.cs._type = C.__u8(val.Type) vcpu.sregs.cs.present = C.__u8(val.Present) vcpu.sregs.cs.dpl = C.__u8(val.Dpl) vcpu.sregs.cs.db = C.__u8(val.Db) vcpu.sregs.cs.s = C.__u8(val.S) vcpu.sregs.cs.l = C.__u8(val.L) vcpu.sregs.cs.g = C.__u8(val.G) vcpu.sregs.cs.avl = C.__u8(val.Avl) vcpu.sregs.cs.unusable = C.__u8(^val.Present & 0x1) case DS: vcpu.sregs.ds.base = C.__u64(val.Base) vcpu.sregs.ds.limit = C.__u32(val.Limit) vcpu.sregs.ds.selector = C.__u16(val.Selector) vcpu.sregs.ds._type = C.__u8(val.Type) vcpu.sregs.ds.present = C.__u8(val.Present) vcpu.sregs.ds.dpl = C.__u8(val.Dpl) vcpu.sregs.ds.db = C.__u8(val.Db) vcpu.sregs.ds.s = C.__u8(val.S) vcpu.sregs.ds.l = C.__u8(val.L) vcpu.sregs.ds.g = C.__u8(val.G) vcpu.sregs.ds.avl = C.__u8(val.Avl) vcpu.sregs.ds.unusable = C.__u8(^val.Present & 0x1) case ES: vcpu.sregs.es.base = C.__u64(val.Base) vcpu.sregs.es.limit = C.__u32(val.Limit) vcpu.sregs.es.selector = C.__u16(val.Selector) vcpu.sregs.es._type = C.__u8(val.Type) vcpu.sregs.es.present = C.__u8(val.Present) vcpu.sregs.es.dpl = C.__u8(val.Dpl) vcpu.sregs.es.db = C.__u8(val.Db) vcpu.sregs.es.s = C.__u8(val.S) vcpu.sregs.es.l = C.__u8(val.L) vcpu.sregs.es.g = C.__u8(val.G) vcpu.sregs.es.avl = C.__u8(val.Avl) vcpu.sregs.es.unusable = C.__u8(^val.Present & 0x1) case FS: vcpu.sregs.fs.base = C.__u64(val.Base) vcpu.sregs.fs.limit = C.__u32(val.Limit) vcpu.sregs.fs.selector = C.__u16(val.Selector) vcpu.sregs.fs._type = C.__u8(val.Type) vcpu.sregs.fs.present = C.__u8(val.Present) vcpu.sregs.fs.dpl = C.__u8(val.Dpl) vcpu.sregs.fs.db = C.__u8(val.Db) vcpu.sregs.fs.s = C.__u8(val.S) vcpu.sregs.fs.l = C.__u8(val.L) vcpu.sregs.fs.g = C.__u8(val.G) vcpu.sregs.fs.avl = C.__u8(val.Avl) vcpu.sregs.fs.unusable = C.__u8(^val.Present & 0x1) case GS: vcpu.sregs.gs.base = C.__u64(val.Base) vcpu.sregs.gs.limit = C.__u32(val.Limit) vcpu.sregs.gs.selector = C.__u16(val.Selector) vcpu.sregs.gs._type = C.__u8(val.Type) vcpu.sregs.gs.present = C.__u8(val.Present) vcpu.sregs.gs.dpl = C.__u8(val.Dpl) vcpu.sregs.gs.db = C.__u8(val.Db) vcpu.sregs.gs.s = C.__u8(val.S) vcpu.sregs.gs.l = C.__u8(val.L) vcpu.sregs.gs.g = C.__u8(val.G) vcpu.sregs.gs.avl = C.__u8(val.Avl) vcpu.sregs.gs.unusable = C.__u8(^val.Present & 0x1) case SS: vcpu.sregs.ss.base = C.__u64(val.Base) vcpu.sregs.ss.limit = C.__u32(val.Limit) vcpu.sregs.ss.selector = C.__u16(val.Selector) vcpu.sregs.ss._type = C.__u8(val.Type) vcpu.sregs.ss.present = C.__u8(val.Present) vcpu.sregs.ss.dpl = C.__u8(val.Dpl) vcpu.sregs.ss.db = C.__u8(val.Db) vcpu.sregs.ss.s = C.__u8(val.S) vcpu.sregs.ss.l = C.__u8(val.L) vcpu.sregs.ss.g = C.__u8(val.G) vcpu.sregs.ss.avl = C.__u8(val.Avl) vcpu.sregs.ss.unusable = C.__u8(^val.Present & 0x1) case TR: vcpu.sregs.tr.base = C.__u64(val.Base) vcpu.sregs.tr.limit = C.__u32(val.Limit) vcpu.sregs.tr.selector = C.__u16(val.Selector) vcpu.sregs.tr._type = C.__u8(val.Type) vcpu.sregs.tr.present = C.__u8(val.Present) vcpu.sregs.tr.dpl = C.__u8(val.Dpl) vcpu.sregs.tr.db = C.__u8(val.Db) vcpu.sregs.tr.s = C.__u8(val.S) vcpu.sregs.tr.l = C.__u8(val.L) vcpu.sregs.tr.g = C.__u8(val.G) vcpu.sregs.tr.avl = C.__u8(val.Avl) vcpu.sregs.tr.unusable = C.__u8(^val.Present & 0x1) case LDT: vcpu.sregs.ldt.base = C.__u64(val.Base) vcpu.sregs.ldt.limit = C.__u32(val.Limit) vcpu.sregs.ldt.selector = C.__u16(val.Selector) vcpu.sregs.ldt._type = C.__u8(val.Type) vcpu.sregs.ldt.present = C.__u8(val.Present) vcpu.sregs.ldt.dpl = C.__u8(val.Dpl) vcpu.sregs.ldt.db = C.__u8(val.Db) vcpu.sregs.ldt.s = C.__u8(val.S) vcpu.sregs.ldt.l = C.__u8(val.L) vcpu.sregs.ldt.g = C.__u8(val.G) vcpu.sregs.ldt.avl = C.__u8(val.Avl) vcpu.sregs.ldt.unusable = C.__u8(^val.Present & 0x1) default: return UnknownRegister } if sync { err = vcpu.flushSRegs() if err != nil { return err } } return nil }
func SetupLinuxBootParams( model *machine.Model, boot_params_data []byte, orig_boot_params_data []byte, cmdline_addr platform.Paddr, initrd_addr platform.Paddr, initrd_len uint64) error { // Grab a reference to our boot params struct. boot_params := (*C.struct_boot_params)(unsafe.Pointer(&boot_params_data[0])) // The setup header. // First step is to copy the existing setup_header // out of the given kernel image. We copy only the // header, and not the rest of the setup page. setup_start := 0x01f1 setup_end := 0x0202 + int(orig_boot_params_data[0x0201]) if setup_end > platform.PageSize { return InvalidSetupHeader } C.memcpy( unsafe.Pointer(&boot_params_data[setup_start]), unsafe.Pointer(&orig_boot_params_data[setup_start]), C.size_t(setup_end-setup_start)) // Setup our BIOS memory map. // NOTE: We have to do this via C bindings. This is really // annoying, but basically because of the unaligned structures // in the struct_boot_params, the Go code generated here is // actually *incompatible* with the actual C layout. // First, the count. C.e820_set_count(boot_params, C.int(len(model.MemoryMap))) // Then, fill out the region information. for index, region := range model.MemoryMap { var memtype C.int switch region.MemoryType { case machine.MemoryTypeUser: memtype = C.E820Ram case machine.MemoryTypeReserved: memtype = C.E820Reserved case machine.MemoryTypeSpecial: memtype = C.E820Reserved case machine.MemoryTypeAcpi: memtype = C.E820Acpi } C.e820_set_region( boot_params, C.int(index), C.__u64(region.Start), C.__u64(region.Size), C.__u8(memtype)) } // Set necessary setup header bits. C.set_header( boot_params, C.__u64(initrd_addr), C.__u64(initrd_len), C.__u64(cmdline_addr)) // All done! return nil }
// Sends a single bit to the device, at the place of the Rd/Wr bit. func (smb SMBus) Write_quick(value byte) error { smb.Set_addr(smb.addr) _, err := C.i2c_smbus_write_quick(C.int(smb.bus.Fd()), C.__u8(value)) return err }
// Block write method for devices without SMBus support. Uses plain i2c interface func (smb SMBus) Write_i2c_block_data(cmd byte, buf []byte) (int, error) { smb.Set_addr(smb.addr) ret, err := C.i2c_smbus_write_i2c_block_data(C.int(smb.bus.Fd()), C.__u8(cmd), C.__u8(len(buf)), ((*C.__u8)(&buf[0]))) return int(ret), err }
// This is the opposite of the Read Word operation. 16 bits // of data is written to a device, to the designated register that is // specified through the cmd byte. func (smb SMBus) Write_word_data(cmd byte, value uint16) error { smb.Set_addr(smb.addr) _, err := C.i2c_smbus_write_word_data(C.int(smb.bus.Fd()), C.__u8(cmd), C.__u16(value)) return err }
func (vcpu *Vcpu) SetEvents(events Events) error { // Prepare our state. var kvm_events C.struct_kvm_vcpu_events if events.NmiPending { kvm_events.nmi.pending = C.__u8(1) } else { kvm_events.nmi.pending = C.__u8(0) } if events.NmiMasked { kvm_events.nmi.masked = C.__u8(1) } else { kvm_events.nmi.masked = C.__u8(0) } kvm_events.sipi_vector = C.__u32(events.SipiVector) kvm_events.flags = C.__u32(events.Flags) if events.Exception != nil { kvm_events.exception.injected = C.__u8(1) kvm_events.exception.nr = C.__u8(events.Exception.Number) if events.Exception.ErrorCode != nil { kvm_events.exception.has_error_code = C.__u8(1) kvm_events.exception.error_code = C.__u32(*events.Exception.ErrorCode) } else { kvm_events.exception.has_error_code = C.__u8(0) kvm_events.exception.error_code = C.__u32(0) } } else { kvm_events.exception.injected = C.__u8(0) kvm_events.exception.nr = C.__u8(0) kvm_events.exception.has_error_code = C.__u8(0) kvm_events.exception.error_code = C.__u32(0) } if events.Interrupt != nil { kvm_events.interrupt.injected = C.__u8(1) kvm_events.interrupt.nr = C.__u8(events.Interrupt.Number) if events.Interrupt.Soft { kvm_events.interrupt.soft = C.__u8(1) } else { kvm_events.interrupt.soft = C.__u8(0) } if events.Interrupt.Shadow { kvm_events.interrupt.shadow = C.__u8(1) } else { kvm_events.interrupt.shadow = C.__u8(0) } } else { kvm_events.interrupt.injected = C.__u8(0) kvm_events.interrupt.nr = C.__u8(0) kvm_events.interrupt.soft = C.__u8(0) kvm_events.interrupt.shadow = C.__u8(0) } // Execute the ioctl. _, _, e := syscall.Syscall( syscall.SYS_IOCTL, uintptr(vcpu.fd), uintptr(C.IoctlSetVcpuEvents), uintptr(unsafe.Pointer(&kvm_events))) if e != 0 { return e } return nil }