void logc(char c) { if(!reqPorts) { /* request io-ports for qemu and bochs */ sassert(reqport(0xe9) >= 0); sassert(reqport(0x3f8) >= 0); sassert(reqport(0x3fd) >= 0); reqPorts = true; } while((inbyte(0x3f8 + 5) & 0x20) == 0) ; outbyte(0x3f8,c); }
// source: NUL/NRE void x86Machine::rebootSysCtrlPort() { if(reqport(0x92) < 0) { printe("Unable to request port 0x92"); return; } outbyte(0x92,0x01); }
void x86Machine::rebootPulseResetLine() { if(reqport(PORT_KB_DATA) < 0) throw init_error("Unable to request keyboard data-port"); if(reqport(PORT_KB_CTRL) < 0) throw init_error("Unable to request keyboard-control-port"); // wait until in-buffer empty while((inbyte(PORT_KB_CTRL) & 0x2) != 0) ; // command 0xD1 to write the outputport outbyte(PORT_KB_CTRL,0xD1); // wait again until in-buffer empty while((inbyte(PORT_KB_CTRL) & 0x2) != 0) ; // now set the new output-port for reset outbyte(PORT_KB_DATA,0xFE); }
// source: NUL/NRE void x86Machine::rebootPCI() { if(reqport(0xcf9) < 0) { printe("Unable to request port 0xcf9"); return; } outbyte(0xcf9,(inbyte(0xcf9) & ~4) | 0x02); outbyte(0xcf9,0x06); outbyte(0xcf9,0x01); }
// source: NUL/NRE void x86Machine::rebootACPI() { size_t len; FACP *facp = reinterpret_cast<FACP*>(mapTable("FACP",&len)); if(facp == NULL || len < 129) { if(len < 129) printe("FACP too small (%zu)",len); return; } if(~facp->flags & RESET_REG_SUP) { printe("ACPI reset unsupported"); return; } if(facp->RESET_REG.regBitWidth != 8) { printe("Register width invalid (%u)",facp->RESET_REG.regBitWidth); return; } if(facp->RESET_REG.regBitOffset != 0) { printe("Register offset invalid (%u)",facp->RESET_REG.regBitOffset); return; } if(facp->RESET_REG.accessSize > 1) { printe("We need byte access"); return; } uint8_t method = facp->RESET_REG.addressSpace; uint8_t value = facp->RESET_VALUE; uint64_t addr = facp->RESET_REG.address; printe("Using method=%#x, value=%#x, addr=%#Lx",method,value,addr); switch(method) { case SYS_MEM: { uintptr_t phys = addr; volatile uint8_t *virt = reinterpret_cast<volatile uint8_t *>( mmapphys(&phys,1,0,MAP_PHYS_MAP)); if(!virt) { printe("Unable to map %p",addr); return; } *virt = value; break; } case SYS_IO: { if(reqport(addr) < 0) { printe("Unable to request port %#Lx",addr); return; } outbyte(addr,value); break; } case PCI_CONF_SPACE: { if(reqports(0xcf8,8) < 0) { printe("Unable to request ports %#x..%#x",0xcf8,0xcf8 + 7); return; } uint32_t val = (addr & 0x1f00000000ull) >> (32 - 11); val |= (addr & 0x70000) >> (16 - 8); val |= addr & 0x3c; outdword(0xcf8,val); outbyte(0xcf8 + (4 | (addr & 0x3)),val); break; } default: printe("Unknown reset method %#x",method); break; } }