PS/2 device detection strange output on Bochs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

PS/2 device detection strange output on Bochs

Post by Ycep »

Hi, this thread replaces old one "PS/2 Mouse help" as too much thread crapping was in it.

By some reason PS/2 returns 85 (0x55) as first identification byte response to 0xF2 command (identify command). It does not seem to be ACK, Resend, or anything like that. What I do is:
Image
SendPort() and ReceivePort():
Image

I post images instead of PHPBB3 code blocks since they are much more readable.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 device detection strange output on Bochs

Post by Octocontrabass »

Lukand wrote:I post images instead of PHPBB3 code blocks since they are much more readable.
No they're not. Post your code as text.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 device detection strange output on Bochs

Post by Ycep »

If you say so...

Code: Select all

inline void Ps2SendPort(uint8 i, uint8 data)
{
	if(i==1)
	{
		WaitSignal();
		outb(0x64, 0xD4);
	}
	WaitSignal();
	outb(0x64,data);
}
inline uint8 Ps2ReceivePort(uint8 i=0)
{
	WaitData();
	return inb(0x60);
}

Code: Select all

	uint8 rcv[2];
	//Recognize first port
	Ps2SendPort(0, 0xF2);  //Identify command
	Ps2ReceivePort(0);  //Receive ACK
	rcv[0]=Ps2ReceivePort(0);  //Receive first identification byte
	if(!WaitData())rcv[1]=inb(0x60);  //Check if there is second identification byte
	else rcv[1]=0x00;  //there is not
	DeviceInit(0,&rcv[0]);  //Port 0 device initialization
	//Recognize second port
	Ps2SendPort(1, 0xF2);  //Identify command
	Ps2ReceivePort(1);  //Receive ACK
	rcv[0]=Ps2ReceivePort(1);  //Receive first identification byte
	if(!WaitData())rcv[1]=inb(0x60);  //Check if there is second identification byte
	else rcv[1]=0x00;  //there is not
	DeviceInit(1,&rcv[0]);  //Port 1 device initialization
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 device detection strange output on Bochs

Post by Octocontrabass »

Lukand wrote:

Code: Select all

inline void Ps2SendPort(uint8 i, uint8 data)
{
	// snip
	outb(0x64,data);
}
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 device detection strange output on Bochs

Post by Ycep »

Finally I got something to work. Thank you a lot Octocontrabass, myself I would never find that ;).
But, due to some strange reason on Bochs now I got "MF2 keyboard with translation enabled in the PS/2" according to this table on first port.
(0xAB 0x41)
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 device detection strange output on Bochs

Post by Octocontrabass »

What's strange about it? Were you not expecting to get that kind of response from the keyboard?
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 device detection strange output on Bochs

Post by Ycep »

I should get normal MF2 keyboard, not the one with translation, right!?
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 device detection strange output on Bochs

Post by Octocontrabass »

Translation is enabled by default.

You may also want to look at initializing the PS/2 controller. (Note that the self-test command, 0xAA, will completely reset some keyboard controllers, so you must disable translation after the self-test to ensure it gets disabled properly.)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PS/2 device detection strange output on Bochs

Post by Brendan »

Hi,
Lukand wrote:I should get normal MF2 keyboard, not the one with translation, right!?
Should, yes (assuming that you do try to disable translation).

However, the last time I messed around with PS/2 in Bochs (years ago now) I found that (unlike real hardware) Bochs didn't allow the translation to be disabled. I don't know if Bochs has been fixed since, but I suspect (assuming that you do try to disable translation) that perhaps it hasn't.

In general; I approach this sort of problem by doing it right (for correct hardware, or the majority of hardware) and then adding work-arounds for dodgy (real or emulated) hardware - I don't like the alternative (the "lowest common denominator" approach where you nerf the OS on all hardware to avoid problems on less common dodgy hardware).

For Bochs keyboard (back then), this meant a special keyboard driver that was only used if translation couldn't be disabled. Sadly, the translation is destructive (a "reverse translation" can't recover the original bytes) so the simpler option isn't viable.


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.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: PS/2 device detection strange output on Bochs

Post by Gigasoft »

Translation can be disabled in the current version of Bochs, but I found that Parallels Desktop 7 always has it enabled no matter what. So, when Parallels Desktop is detected, I have to undo the translation before passing the data to the keyboard driver.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 device detection strange output on Bochs

Post by Ycep »

It seems I could not get input from mouse now. What does happens is that keyboard interferes mouse, eg. input from keyboard has interference with mouse input. Through moving mouse and clicking on it does nothing, but typing keys does.
Sadly there's no way to seperate keyboard input with mouse input except using semaphores as used in multithreading...
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: PS/2 device detection strange output on Bochs

Post by BenLunt »

I may be getting into something I shouldn't here, but I am going to try.

The PS/2 controller uses the exact same I/O port(s) for both mouse and keyboard. If a key is pressed on the keyboard, it sends the scan code to the exact same I/O port as it does when sending data from the mouse. i.e.: If the mouse sends a packet to the PS/2 controller, the controller sends it to the same I/O port as the one it sent for the keyboard. As for the PS/2 controller, this is called the Output Buffer and holds one byte at a time. It will hold this byte there until you read it, where it will then send another byte to that Output Buffer until all bytes are read.

At first you would think that this is confusing and how the heck do I determine which byte is for what.

For example, let's say that I type a key on the keyboard and that key produces a three byte code. At the exact same time, I move the mouse and that motion produces a 4 byte packet. The Output Buffer may look something like this:

Code: Select all

 key[0] ->  XX
           XX <- Mouse[0]
 key[1] ->  XX
           XX <- Mouse[1]
 key[2] ->  XX
           XX <- Mouse[2]
           XX <- Mouse[3]
So, how do I tell which bytes are the key scan code and which bytes are the mouse packet?

Simple!

The PS/2 controller will fire an interrupt each time it places a byte into the Output Buffer. The trick is, and here is the funny thing, it fires a different IRQ for the mouse than it does for the Keyboard.

Therefore, when the IRQ for the Mouse fires, have that Handler read from the Output Buffer, set a flag, send the EOI, and return. Nothing more.
When the IRQ for the Keyboard fires, have that Handler read from the Output Buffer, set a flag, send the EOI, and return. Again, nothing more.

Then your keyboard and mouse drivers watch for their respected flag. When set, it adds this byte to its internal buffer. When a full packet has been received from either the mouse or the keyboard, the corresponding driver does something with it.

It is really that simple. Really.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 device detection strange output on Bochs

Post by Ycep »

Ben Lunt,
I'm trying to avoid overhauling I/O by interrupts. Doesn't mouse just send interrupts only when automatic packet interrupts are enabled? Or I'm wrong? And is it good idea to create semaphores (eg. when waiting for mouse input disable the port where keyboard is located in)?
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 device detection strange output on Bochs

Post by Octocontrabass »

Lukand wrote:I'm trying to avoid overhauling I/O by interrupts.
Why are you trying to avoid it?

The only way to tell which PS/2 device sent the data is using interrupts. If you're not using interrupts, then you can't tell if you're receiving data from the first port or the second port.
Lukand wrote:Doesn't mouse just send interrupts only when automatic packet interrupts are enabled? Or I'm wrong?
The mouse doesn't send interrupts at all, it send bytes. The PS/2 controller raises an interrupt request when it receives a byte. If you prevent the mouse from sending bytes, or you prevent the PS/2 controller from sending IRQs, then you won't receive any interrupts.
Lukand wrote:And is it good idea to create semaphores (eg. when waiting for mouse input disable the port where keyboard is located in)?
No. That creates a race condition. The PS/2 controller can receive a byte from the keyboard at the same time you're disabling the keyboard port, so the next byte you receive comes from the keyboard even though you've just disabled it.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PS/2 device detection strange output on Bochs

Post by Brendan »

Hi,
Lukand wrote:It seems I could not get input from mouse now. What does happens is that keyboard interferes mouse, eg. input from keyboard has interference with mouse input. Through moving mouse and clicking on it does nothing, but typing keys does.
Sadly there's no way to seperate keyboard input with mouse input except using semaphores as used in multithreading...
I told you that would happen (that the drivers would interfere with each other) and how to avoid the problem last month.

Mostly; there are 3 different devices, so you need 3 separate drivers (one for the PS/2 controller itself, and one for each type of device that could be plugged into a PS/2 port) in the same way that you'd have multiple drivers for USB (one for the USB controller, and one for each type of device that could be plugged into a USB port).

Note: By "3 separate drivers" I don't necessarily mean (e.g.) 3 separate processes (for micro-kernel) or 3 separate "kernel modules" (for monolithic). It could just be "logical separation" (where the source code is split into 3 separate directories, but it's all assembled/compiled/linked together and becomes a single executable/process/kernel module).

The "PS/2 controller driver" would initialise (and test) the controller, determine if there are any devices plugged into the PS/2 ports and get their "device ID", then use the "device ID" to determine which drivers are needed and start the right driver (note that you can have 2 keyboards and no mouse, or 2 mouse and no keyboards, or a bar-code scanner and a touch-pad and no keyboards and no mouse, or...).

The drivers for devices plugged into a PS/2 port (e.g. the keyboard driver and mouse driver) would ask the "PS/2 controller driver" to send bytes to whichever port it's connected to, and the "PS/2 controller driver" would tell the driver for a PS/2 port about any bytes received. The drivers for devices plugged into a PS/2 port would never use any IO ports or IRQs themselves. If you port your OS to a different type of computer (with a different type of PS/2 controller - e.g. the PL050 on some ARM SoCs) you only need to write a new "PS/2 controller driver" and (assuming C source code or something) will not need to change any driver for a PS/2 device (the keyboard, mouse, bar-code, touch-pad, touch-screen, .... drivers).

Another thing the "PS/2 controller driver" would do is handle "hot-plug" - if the user unplugs a device it'd tell (terminate?) whichever driver was using that PS/2 port, and if a user plugs a device into a previously empty PS/2 port the "PS/2 controller driver" would figure out the type of device that was plugged in and start an appropriate driver. The "PS/2 controller driver" could also (optionally) monitor the other drivers - e.g. if your keyboard driver crashes then "PS/2 controller driver" might notice and start another keyboard driver; and if you install a newer keyboard driver then "PS/2 controller driver" might notice and terminate the old driver and start the new one.

Finally; it'd probably be nice to build support for debugging into your "PS/2 controller driver"; so that anyone writing a driver for any PS/2 device can enable debugging for whichever port the device is connected to and see all bytes received by their driver and see all bytes sent by their driver (without having any code in their driver). This just makes it much easier for people (you) to write drivers for different PS/2 devices.


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.
Post Reply