jakethompson1 wrote on 2023-06-02, 05:48:
However, forcing a reset with A20 disabled and a custom int6 handler installed just reboots the system and doesn't seem to trigger the handler. I tried resets via triple fault and via the keyboard controller. Why wouldn't a chipset reenable A20 whenever the CPU resets or initiates a shutdown cycle?
A "classic" chipset doesn't control the A20 gate. The A20 gate is a simple AND gate (which might be contained in the integrated chipset), with one input being the A20 line, and the other input being the general purpose output pin P2.0 of the 8042 keyboard controller. In case of a shutdown-induced reset, the keyboard controller doesn't notice that a CPU reset is happening, so it won't raise P2.0 in response to that. Things might be different using the Port92-based "fast A20 gate", though, so I suggest you use the classic KBC method to disable A20 just to be sure.
jakethompson1 wrote on 2023-06-02, 05:48:
If it doesn't, it seems like accidentally resetting at FFEFFFF0h could easily happen, for machines that boot into DOS with A20 disabled, and then if software attempts to reset the system via the keyboard controller.
Resetting the system via the keyboard controller is a new feature of the AT platform, i.e. it has been introduced exactly at the same time as the A20 gate. Software that tries to reset the CPU using the keyboard controller is supposed to know that the keyboard controller has that A20 gate. Primarily, resetting the CPU using the keyboard controller is meant as a means to get out of protected mode - and while the system is operating in protected mode, you better have the A20 gate open!
jakethompson1 wrote on 2023-06-02, 05:48:
Is there more of a trick to it than loading INT6 (0000:0018h) with a far pointer to the desired handler?
Remember that you need to initialize the stack to something sensible. The CPU resets with SS=0 and SP=<undefined> according to Intel's manuals, so just entering the INT6 handler is overwriting 6 bytes at a random location in the low 64K. The BIOS sets SP to 400 or 3FE to use the end of the vector table as temporary stack on a "real reset" before trying to push anything, but we don't get to initialize SP before entering the exception. This means in theory we have to save/restore the low 64KB across the reset, whereas in practice, CPUID utilities seem to get away with ignoring this issue. Just setting the vector at 0:0018h should be enough to regain control.
jakethompson1 wrote on 2023-06-02, 05:48:
For my AMIBIOS system, the default int6 handler has code to skip over LOCK prefixes (f0 XX),
That's default BIOS behaviour since the 286, as the 8088 accepted LOCK before all instructions, whereas the 286 reports an INT6 on instructions that are not LOCKable.
jakethompson1 wrote on 2023-06-02, 05:48:
to handle 286 LOADALL emulation (0f 05)
That's default BIOS behaviour since the 386. An Intel application note about this emulation code is believed to be the first official documentation on LOADALL that leaked into the public.
jakethompson1 wrote on 2023-06-02, 05:48:
to handle various protected mode table instructions (0f 00)
That's not that well known to me. I need to take a look at some AMI 386 BIOS to see what you are referring to. 0F 00 has been introduced with the 286 processor, and isn't supposed to have "incompatibly evolved" since then.
jakethompson1 wrote on 2023-06-02, 05:48:
and then a catch-all for other illegal instructions which messes with the 8259 that I have not analyzed.
That sounds like the generic "unexpected IRQ" handler. It makes little sense to jump to that code from INT 06, as no IRQ is mapped to INT 06 by default, but IIRC I've seen this behaviour in some BIOS code already.