On Tue, May 16, 2017 at 06:27:03PM +0200, Paolo Bonzini wrote:
On 16/05/2017 18:14, Kevin O'Connor wrote:
Don't write to the cmos index port on a mode switch if NMI is already disabled. This reduces the number of outb() calls.
Signed-off-by: Kevin O'Connor kevin@koconnor.net
src/stacks.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/stacks.c b/src/stacks.c index f4d15ce..2fe1bfb 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -66,8 +66,10 @@ call32_prep(u8 method)
// Backup cmos index register and disable nmi u8 cmosindex = inb(PORT_CMOS_INDEX);
- outb(cmosindex | NMI_DISABLE_BIT, PORT_CMOS_INDEX);
- inb(PORT_CMOS_DATA);
if (!(cmosindex & NMI_DISABLE_BIT)) {
outb(cmosindex | NMI_DISABLE_BIT, PORT_CMOS_INDEX);
inb(PORT_CMOS_DATA);
} SET_LOW(Call16Data.cmosindex, cmosindex);
SET_LOW(Call16Data.method, method);
@@ -103,8 +105,11 @@ call32_post(void) }
// Restore cmos index register
- outb(GET_LOW(Call16Data.cmosindex), PORT_CMOS_INDEX);
- inb(PORT_CMOS_DATA);
- u8 cmosindex = GET_LOW(Call16Data.cmosindex);
- if (!(cmosindex & NMI_DISABLE_BIT)) {
outb(cmosindex, PORT_CMOS_INDEX);
inb(PORT_CMOS_DATA);
- } return method;
}
NMI disable is actually a no-op on QEMU (as it never sends NMIs, either), we might as well skip it in that case.
This particular code is also run on real hardware. We could skip the inb() on QEMU, but my preference would be to try and minimize the number of platform specific branches.
Separately, the above patch should have also had:
--- a/src/stacks.c +++ b/src/stacks.c @@ -116,6 +121,7 @@ call16_override(int big) if (getesp() > BUILD_STACK_ADDR) panic("call16_override with invalid stack\n"); memset(&Call16Data, 0, sizeof(Call16Data)); + Call16Data.cmosindex = NMI_DISABLE_BIT; if (big) { Call16Data.method = C16_BIG; Call16Data.a20 = 1;
-Kevin