kbd detection basics
kbd detection basics
Happy New Coding to ya'll!
My question is about the very basics of detecting keyboard: after POST completes, how
do I find out if a serial kbd controller is present, and if so, what range of ports/memory
it is mapped to? After that I'll need to detect if a PS/2 keyboard is connected and if it is,
what IRQ is assigned to it. Thanks. Boba.
My question is about the very basics of detecting keyboard: after POST completes, how
do I find out if a serial kbd controller is present, and if so, what range of ports/memory
it is mapped to? After that I'll need to detect if a PS/2 keyboard is connected and if it is,
what IRQ is assigned to it. Thanks. Boba.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: kbd detection basics
There's no way you can portably detect whether you have a keyboard controller or not (in most cases, you can't do it at all)---you generally assume it. It's always mapped to IRQ 1. You could detect USB keyboards but you'd need an USB stack before you could support HID but that's unnecessary anyway, as most systems emulate HID to PS/2 via SMM.
Since you're asking what to do after POST and how to detect serial keyboards, I take it you're writing firmware. So you shouldn't worry too much about portability. Modern systems emulate the keyboard controller in the northbridge (or equivalent)) so you should just read the appropriate datasheets.
Since you're asking what to do after POST and how to detect serial keyboards, I take it you're writing firmware. So you shouldn't worry too much about portability. Modern systems emulate the keyboard controller in the northbridge (or equivalent)) so you should just read the appropriate datasheets.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: kbd detection basics
WRONG, WRONG, WRONG!Love4Boobies wrote:There's no way you can portably detect whether you have a keyboard controller or not (in most cases, you can't do it at all)---you generally assume it.
ACPI can tell you if you have a keyboard controller. You must listen to this. If there is not keyboard controller and you touch it, you will crash many machines, including every x86 Mac. If the keyboard controller is present, it has the same port and IRQ assignments it has always had (subject to any ACPI APIC IRQ redirection table entries)
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: kbd detection basics
Alas, one of my systems doesn't show it and it does have one...
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: kbd detection basics
I find it hard to believe that they managed to break the keyboard in every version of Windows since XP.Love4Boobies wrote:Alas, one of my systems doesn't show it and it does have one...
Re: kbd detection basics
Hi,
I personally think that these should be implemented as entirely different types of device drivers. For example, have a device driver for the PS/2 controller, and separate device drivers for keyboards, mouses, touchpads, etc. This helps for debugging and flexibility, and also helps for portability (as the "PS/2 controller" can look very different on other types of computers that happen to support the same PS/2 keyboards, mouses, etc).
For initialising the PS/2 controller properly (including self tests, etc) and detecting the type/s of devices connected to the PS/2 controller, you might want to read this old old post about it to get some ideas. There are a few things missing in that old post though - hot-plug support to start with (not really hard to do); and finding USB controllers and disabling "PS/2 emulation" before you start trying to mess with the real PS/2 controller (as the "PS/2 emulation" built into most BIOSs is typically very dodgy).
Finally, there's a page in the OSdev wiki about keyboards that should help!
Cheers,
Brendan
First, there's 2 separate types of devices involved. The first type of device is the PS/2 controller ("8042 keyboard controller") which is a chip that handles one or two serial communications channels. The second type of device is anything that can be plugged into a PS/2 port (keyboard, mouse, touchpad, bar code scanner, etc).Boba wrote:My question is about the very basics of detecting keyboard: after POST completes, how
do I find out if a serial kbd controller is present, and if so, what range of ports/memory
it is mapped to? After that I'll need to detect if a PS/2 keyboard is connected and if it is,
what IRQ is assigned to it. Thanks. Boba.
I personally think that these should be implemented as entirely different types of device drivers. For example, have a device driver for the PS/2 controller, and separate device drivers for keyboards, mouses, touchpads, etc. This helps for debugging and flexibility, and also helps for portability (as the "PS/2 controller" can look very different on other types of computers that happen to support the same PS/2 keyboards, mouses, etc).
For initialising the PS/2 controller properly (including self tests, etc) and detecting the type/s of devices connected to the PS/2 controller, you might want to read this old old post about it to get some ideas. There are a few things missing in that old post though - hot-plug support to start with (not really hard to do); and finding USB controllers and disabling "PS/2 emulation" before you start trying to mess with the real PS/2 controller (as the "PS/2 emulation" built into most BIOSs is typically very dodgy).
Finally, there's a page in the OSdev wiki about keyboards that should help!
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: kbd detection basics
thank you all for the input. I'm afraid I'll have to hardcode it. It would be nice to have
a table similar to the MP Configuration Table, or a feature similar to the one provided
by PCI specs where one could enum all devices on the mobo with their VendorIDs/IRQs
etc. I assume future developments in the chip sets will consider this option. Boba.
a table similar to the MP Configuration Table, or a feature similar to the one provided
by PCI specs where one could enum all devices on the mobo with their VendorIDs/IRQs
etc. I assume future developments in the chip sets will consider this option. Boba.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: kbd detection basics
It's called ACPI. Its the definitive PC configuration database.Boba wrote:thank you all for the input. I'm afraid I'll have to hardcode it. It would be nice to have
a table similar to the MP Configuration Table, or a feature similar to the one provided
by PCI specs where one could enum all devices on the mobo with their VendorIDs/IRQs
etc. I assume future developments in the chip sets will consider this option. Boba.
Re: kbd detection basics
sorry ...better late then never...
what's on it. I can't afford disassembling BIOS from ROM.
Today, my question is about how to disable NMIs. My attempt to send 80
to port 70 does no-good. Is there a reliable way to inhibit LINT1 line? instead
of re-programming IOAPIC. Thank you. Boba.
thank you, Owen, but I was talking about bus/chip ability to provide info onOwen wrote:It's called ACPI...
what's on it. I can't afford disassembling BIOS from ROM.
Today, my question is about how to disable NMIs. My attempt to send 80
to port 70 does no-good. Is there a reliable way to inhibit LINT1 line? instead
of re-programming IOAPIC. Thank you. Boba.
Re: kbd detection basics
ROTFL. Let me help you: NMI = Non Maskable Interrupt. Even if you find a tricky way to disable it, you shouldn't.Boba wrote:how to disable NMIs.
Re: kbd detection basics
M'kay...turdus wrote:ROTFL.
so what? what stops me from disabling'em?turdus wrote:Let me help you: NMI = Non Maskable Interrupt.
don't see anything 'tricky' about it: I need to include some piece of code that requiresturdus wrote:Even if you find a tricky way to disable it, you shouldn't.
NMIs to be temporarily disabled while it runs, and I can do it depending on the system,
but I need a 'universal way' of doing so and it has to be no more than a few bytes long.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: kbd detection basics
The point was that requiring NMIs to be off is usually a design error.
Unless you configured it otherwise, it is originally meant for the PC's indication of hardware failure and should never be ignored at all. Plus, there is no guaranteed way of disabling it or knowing whether or not it might be used.
Unless you configured it otherwise, it is originally meant for the PC's indication of hardware failure and should never be ignored at all. Plus, there is no guaranteed way of disabling it or knowing whether or not it might be used.
Re: kbd detection basics
Hi,
Usually when people think they want to disable NMI they're doing CPU mode switches. Because you can't atomically change the IDT and CR0 at the same time, there's a race condition - a small amount of time that an NMI could occur when the IDT doesn't suit the CPU mode. There's 2 ways to handle this properly.
The first way is to set the IDT limit to zero (so that any NMI would cause a triple fault, rather than undefined behaviour caused by the CPU misinterpreting the IDT). This is only really an option during boot, where a very low chance of unexpected reset won't cause data loss.
The second way is tricky. You can have a temporary IDT; with a NMI entry for real mode at offset 0x0008, an NMI entry for 32-bit protected mode at offset 0x0010, and an NMI entry for long mode at offset 0x20. That way the same IDT can work regardless of which mode the CPU happens to be in at the time an NMI occurs. You'd also have to make sure that SS looks sane in both modes (e.g. SS = 0x0080, with "base address = 0x00000800" in the corresponding GDT entry in protected mode).
Of course for both of these cases you'd change the IDT to something that suits the new CPU mode as soon as you can after changing CPU modes.
Cheers,
Brendan
Yes.Combuster wrote:The point was that requiring NMIs to be off is usually a design error.
Usually when people think they want to disable NMI they're doing CPU mode switches. Because you can't atomically change the IDT and CR0 at the same time, there's a race condition - a small amount of time that an NMI could occur when the IDT doesn't suit the CPU mode. There's 2 ways to handle this properly.
The first way is to set the IDT limit to zero (so that any NMI would cause a triple fault, rather than undefined behaviour caused by the CPU misinterpreting the IDT). This is only really an option during boot, where a very low chance of unexpected reset won't cause data loss.
The second way is tricky. You can have a temporary IDT; with a NMI entry for real mode at offset 0x0008, an NMI entry for 32-bit protected mode at offset 0x0010, and an NMI entry for long mode at offset 0x20. That way the same IDT can work regardless of which mode the CPU happens to be in at the time an NMI occurs. You'd also have to make sure that SS looks sane in both modes (e.g. SS = 0x0080, with "base address = 0x00000800" in the corresponding GDT entry in protected mode).
Of course for both of these cases you'd change the IDT to something that suits the new CPU mode as soon as you can after changing CPU modes.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: kbd detection basics
Yes. Masking an interrupt prevents it from firing, so you can say it's disabled. So non maskable means there's no way to disable. Of course we're talking about Intel engineers, so there's a tricky way to do it, but Combuster and Brendan is right, you have a bad design if you want to do this.Boba wrote:so what? what stops me from disabling'em?turdus wrote:Let me help you: NMI = Non Maskable Interrupt.
Re: kbd detection basics
I'd rather say it prevents the CPU from being interrupted: the event still takes place.turdus wrote:Masking an interrupt prevents it from firing...
to me it means you can not mask it out. When CPU pays no attention to NMIs, it runs as if they are temporarily disabled.turdus wrote:So non maskable means there's no way to disable.
do you mean the 'port 70 trick' was not 'by design'?turdus wrote:Of course we're talking about Intel engineers...
agree; it isn't my design: I have to include the code written by a 3rd party and it requires NMIs to be disabled. I will disassemble it (if permitted) to see what they're doing in there (my guess is it has something to do with chip/bus timings). Thank ya'll for the ideas. Boba.turdus wrote:...but Combuster and Brendan is right, you have a bad design...