Reboot: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
Alyssa (talk | contribs)
Add note about UEFI options
m Bot: Replace deprecated source tag with syntaxhighlight
 
(7 intermediate revisions by 5 users not shown)
Line 5:
# Use the 8042 keyboard controller to pulse the CPU's RESET pin
# Use the ResetSystem runtime [[UEFI]] service, if available.
# Far jump to the reset vector (0xFFFF:0000)/ Triple fault
 
== ACPI reset command ==
Line 10 ⟶ 11:
In the FADT, there are several General Address Structures. Take a look at the [[FADT#GenericAddressStructure|FADT]] page for details. The FADT structure contains a generic address structure called ResetReg, followed by a byte called ResetValue. This is an optional feature and software must check support for it by checking if the FADT is version 2 or newer, and then testing if bit 10 of the Flags field in the FADT is set.
After that, software can reset the system by writing the value in ResetValue into the area pointed to by ResetReg. ACPI says the ResetReg can only be located in I/O bus, PCI bus or memory-mapped. If it is in the I/O bus, simply do:
<sourcesyntaxhighlight lang="c">
outportb(FADT->ResetReg->.Address, FADT->ResetValue);
</syntaxhighlight>
</source>
If it is memory-mapped, simply map the memory pointed by ResetReg->Address somewhere in the virtual address space, and write ResetValue there as an 8-bit operation. Like:
<syntaxhighlight lang="c">
vmm_map(FADT->ResetReg.Address, 1); // Map 1 byte
uint8_t *reg = (uint8_t *)((uintptr_t)FADT->ResetReg.Address);
*reg = FADT->ResetValue;
</syntaxhighlight>
 
But if it is on the PCI Configuration Space, you need to write ResetValue as a byte on:
'''TODO:''' Determine how PCI bus resets work.
* Segment: 0
* Bus: 0
* Slot: (address >> 32) & 0xFFFF
* Function: (address >> 16) & 0xFFFF
* Offset: address & 0xFFFF
That operation in C looks like:
<syntaxhighlight lang="c">
pci_writeb(0, 0, (FADT->ResetReg.Address >> 32) & 0xFFFF, (FADT->ResetReg.Address >> 16) & 0xFFFF, FADT->ResetReg.Address & 0xFFFF, FADT->ResetValue);
</syntaxhighlight>
 
== Short code to do a 8042 reset ==
<sourcesyntaxhighlight lang="c">
void reboot()
{
Line 27 ⟶ 42:
halt();
}
</syntaxhighlight>
</source>
 
 
== Annotated code for reboot() ==
<sourcesyntaxhighlight lang="c">
/* keyboard interface IO port: data and control
READ: status port
Line 68 ⟶ 82:
goto loop; /* if a NMI is received, halt again */
}
</syntaxhighlight>
</source>
== Far jump to the reset vector/Triple fault ==
 
Probably the easiest way.
<syntaxhighlight lang="asm">
JMP 0xFFFF:0
</syntaxhighlight>
It'll far jump to the reset vector if you're in real mode, and triple faults if you're in protected mode and removed/haven't setup the gpf handler before.
[[Category:Power management]]