Reading from kb-controller gets slow if mouse in use
Posted: Sat May 02, 2009 1:29 pm
Hi,
I want to work with keyboard and mouse at the same time. If the mouse is disabled the keyboard works fine, if I enable the mouse the mouse works fine, too. But if I press keys when the mouse is already enabled, reading from the keyboard-controller gets very slow. I have measured the cpu-cycles of the keyboard-interrupt. Before using the keyboard it takes about 0x40000, after it takes about 0x8000000 cycles.
Here are the the important parts of my code. The parts are from different programs, so it's not executed in that sequence. I've separated the parts by "// === ... ===":
I experience this behaviour in qemu and bochs.
Has anybody an idea what I am doing wrong?
Thanks!
hrniels
I want to work with keyboard and mouse at the same time. If the mouse is disabled the keyboard works fine, if I enable the mouse the mouse works fine, too. But if I press keys when the mouse is already enabled, reading from the keyboard-controller gets very slow. I have measured the cpu-cycles of the keyboard-interrupt. Before using the keyboard it takes about 0x40000, after it takes about 0x8000000 cycles.
Here are the the important parts of my code. The parts are from different programs, so it's not executed in that sequence. I've separated the parts by "// === ... ===":
Code: Select all
// === init keyboard ===
/* reset keyboard */
outByte(IOPORT_KB_DATA,0xff);
while(inByte(IOPORT_KB_DATA) != 0xaa)
yield();
// === init mouse ===
/* activate mouse */
outByte(IOPORT_KB_CTRL,KBC_CMD_ENABLE_MOUSE);
kb_checkCmd();
/* put mouse in streaming mode */
kb_writeMouse(MOUSE_CMD_STREAMING);
/* read cmd byte */
outByte(IOPORT_KB_CTRL,KBC_CMD_READ_STATUS);
kb_checkCmd();
u8 cmdByte = kb_read();
outByte(IOPORT_KB_CTRL,KBC_CMD_SET_STATUS);
kb_checkCmd();
cmdByte |= KBC_CMDBYTE_ENABLE_IRQ12 | KBC_CMDBYTE_ENABLE_IRQ1;
cmdByte &= ~KBC_CMDBYTE_DISABLE_KB;
outByte(IOPORT_KB_DATA,cmdByte);
kb_checkCmd();
// === helper ===
static void kb_checkCmd(void) {
while(inByte(IOPORT_KB_CTRL) & KBC_STATUS_BUSY);
}
static u16 kb_read(void) {
u8 status;
while(!((status = inByte(IOPORT_KB_CTRL)) & KBC_STATUS_DATA_AVAIL));
return inByte(IOPORT_KB_DATA);
}
static u16 kb_writeMouse(u8 cmd) {
outByte(IOPORT_KB_CTRL,KBC_CMD_NEXT2MOUSE);
kb_checkCmd();
outByte(IOPORT_KB_DATA,cmd);
kb_checkCmd();
return kb_read();
}
// === interrupt-handlers ===
static void kbIntrptHandler(tSig sig,u32 data) {
u8 scanCode = inByte(IOPORT_KB_DATA);
if(kb_set1_getKeycode(&resp,scanCode)) {
/* write in receive-pipe */
write(selfFd,&resp,sizeof(sMsgKbResponse));
}
}
static void mouseIntrptHandler(tSig sig,u32 data) {
/* check if there is mouse-data */
u8 status = inByte(IOPORT_KB_CTRL);
if(!(status & KBC_STATUS_MOUSE_DATA_AVAIL))
return;
switch(byteNo) {
case 0:
packet.status.all = inByte(IOPORT_KB_DATA);
byteNo++;
break;
case 1:
packet.xcoord = inByte(IOPORT_KB_DATA);
byteNo++;
break;
case 2:
packet.ycoord = inByte(IOPORT_KB_DATA);
byteNo = 0;
/* write the message in our receive-pipe */
msg.data.x = packet.xcoord;
msg.data.y = packet.ycoord;
msg.data.buttons = (packet.status.leftBtn << 2) |
(packet.status.rightBtn << 1) |
(packet.status.middleBtn << 0);
write(selfFd,&msg,sizeof(sMsgMouse));
break;
}
}
// === constants ===
#define IOPORT_KB_CTRL 0x64
#define IOPORT_KB_DATA 0x60
#define KBC_CMD_ENABLE_MOUSE 0xA8
#define KBC_CMD_NEXT2MOUSE 0xD4
#define MOUSE_CMD_STREAMING 0xF4
#define KBC_STATUS_DATA_AVAIL (1 << 0)
#define KBC_STATUS_BUSY (1 << 1)
#define KBC_STATUS_MOUSE_DATA_AVAIL (1 << 5)
#define KBC_CMDBYTE_DISABLE_KB (1 << 4)
#define KBC_CMDBYTE_ENABLE_IRQ12 (1 << 1)
#define KBC_CMDBYTE_ENABLE_IRQ1 (1 << 0)
Has anybody an idea what I am doing wrong?
Thanks!
hrniels