Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Dec 2008 15:16:44 +0200
From:      Andriy Gapon <avg@icyb.net.ua>
To:        freebsd-hackers@FreeBSD.org
Subject:   usb keyboard vs btx: an SMI theory
Message-ID:  <4947AA3C.4040005@icyb.net.ua>

next in thread | raw e-mail | index | archive | help

I am not a close-to-hardware guy, my knowledge of IA32 architecture and
IA32 assembly is very (very!) limited, so my reasoning can have some
glaring flaws. Also, I am quite fuzzy on the details of btx workings and
some other aspects.

Still I have a theory (or a "gut feeling") about the bad interaction
between "newer" loader and USB keyboard that I experienced. I believe
that a number other people had the same or similar issues.

It seems that i386 btx code contains routines, intx31/int_hw +
rret_tramp, to enter real mode, execute an interrupt handler and exit
real mode. It seems that this code can be invoked in two cases: (1) when
protected code wishes to execute a BIOS int function and calls into btx
via int 31h; (2) when a hardware interrupt happens while in protected mode.
It also looks that the routine saves and restores certain context before
entering and after exiting real mode. This is done in a special fixed
memory location (MEM_ESPR). This memory lcoation also seems to be used
as a stack base address for real mode.

Normally there can not be any shared/overlapping access to that
location. This is because in all cases interrupts are disabled and
machine is supposed to be uniprocessor mode still.

Now lets look at the other end - "USB legacy support". I think that BIOS
emulates PS/2 keyboard for real USB keyboard in the following way.
When a key is pressed a USB event is generated by the keyboard.
USB host controller generates an SMI upon the USB event.
SMM code checks if SMI was generated by USB, performs necessary USB
chores and then pretends as if the key press was made on an PS/2 keyboard.
This is something that I am very fuzzy about, but I think that SMM code
somehow invokes IRQ 1 handler.

And I think that because SMI is not maskable it can be "nested" inside
any other interrupt (software or hardware) and it is possible that IRQ1
handler for protected mode can be executed (and thus int_hw) while we
were already executing int_hw for some other reason -  a "system call"
from protected mode code or hardware interrupt.
In this case the context data stored in memory would get corrupted.
I suspect that what I actually observe looks like interrupts never
getting re-enabled.

Again, I am very fuzzy about the exact details, but I think that this is
something that could be happening and I think that SMI is of primary
interest here. I also think that this might explain to a certain degree
the difference in behavior between "older" btx and "newer" btx.


-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4947AA3C.4040005>