X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmouse.c;h=e26cf694ca5bcc37791d533c564071f1ee863efd;hb=refs%2Fheads%2Fcoreboot;hp=23e17dedf819c4e36170a7cdf726c6db12dbc2f2;hpb=15c1f2207f4d406bb56032cef5920f474f32de88;p=seabios.git diff --git a/src/mouse.c b/src/mouse.c index 23e17de..e26cf69 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -3,83 +3,31 @@ // Copyright (C) 2008 Kevin O'Connor // Copyright (C) 2002 MandrakeSoft S.A. // -// This file may be distributed under the terms of the GNU GPLv3 license. +// This file may be distributed under the terms of the GNU LGPLv3 license. -#include "biosvar.h" // struct bregs +#include "biosvar.h" // GET_EBDA #include "util.h" // debug_isr +#include "pic.h" // eoi_pic2 +#include "bregs.h" // struct bregs +#include "ps2port.h" // ps2_mouse_command +#include "usb-hid.h" // usb_mouse_command -#define DEBUGF1(fmt, args...) bprintf(0, fmt , ##args) -#define DEBUGF(fmt, args...) - -static char panic_msg_keyb_buffer_full[] = "%s: keyboard input buffer full\n"; - -static void -set_kbd_command_byte(u8 command_byte) -{ - if (inb(PORT_PS2_STATUS) & 0x02) - BX_PANIC(panic_msg_keyb_buffer_full, "setkbdcomm"); - outb(0xD4, PORT_PS2_STATUS); - - outb(0x60, PORT_PS2_STATUS); // write command byte - outb(command_byte, PORT_PS2_DATA); -} - -static u8 -inhibit_mouse_int_and_events() -{ - // Turn off IRQ generation and aux data line - if (inb(PORT_PS2_STATUS) & 0x02) - BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse"); - outb(0x20, PORT_PS2_STATUS); // get command byte - while ((inb(PORT_PS2_STATUS) & 0x01) != 0x01) - ; - u8 prev_command_byte = inb(PORT_PS2_DATA); - u8 command_byte = prev_command_byte; - //while ( (inb(PORT_PS2_STATUS) & 0x02) ); - if ( inb(PORT_PS2_STATUS) & 0x02 ) - BX_PANIC(panic_msg_keyb_buffer_full,"inhibmouse"); - command_byte &= 0xfd; // turn off IRQ 12 generation - command_byte |= 0x20; // disable mouse serial clock line - outb(0x60, PORT_PS2_STATUS); // write command byte - outb(command_byte, PORT_PS2_DATA); - return prev_command_byte; -} - -static void -enable_mouse_int_and_events() -{ - // Turn on IRQ generation and aux data line - if ( inb(PORT_PS2_STATUS) & 0x02 ) - BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse"); - outb(0x20, PORT_PS2_STATUS); // get command byte - while ((inb(PORT_PS2_STATUS) & 0x01) != 0x01) - ; - u8 command_byte = inb(PORT_PS2_DATA); - //while ( (inb(PORT_PS2_STATUS) & 0x02) ); - if (inb(PORT_PS2_STATUS) & 0x02) - BX_PANIC(panic_msg_keyb_buffer_full,"enabmouse"); - command_byte |= 0x02; // turn on IRQ 12 generation - command_byte &= 0xdf; // enable mouse serial clock line - outb(0x60, PORT_PS2_STATUS); // write command byte - outb(command_byte, PORT_PS2_DATA); -} - -static void -send_to_mouse_ctrl(u8 sendbyte) +void +mouse_setup(void) { - // wait for chance to write to ctrl - if (inb(PORT_PS2_STATUS) & 0x02) - BX_PANIC(panic_msg_keyb_buffer_full,"sendmouse"); - outb(0xD4, PORT_PS2_STATUS); - outb(sendbyte, PORT_PS2_DATA); + if (! CONFIG_MOUSE) + return; + dprintf(3, "init mouse\n"); + // pointing device installed + SETBITS_BDA(equipment_list_flags, 0x04); } -static void -get_mouse_data(u8 *data) +static inline int +mouse_command(int command, u8 *param) { - while ((inb(PORT_PS2_STATUS) & 0x21) != 0x21) - ; - *data = inb(PORT_PS2_DATA); + if (usb_mouse_active()) + return usb_mouse_command(command, param); + return ps2_mouse_command(command, param); } #define RET_SUCCESS 0x00 @@ -93,41 +41,34 @@ get_mouse_data(u8 *data) static void mouse_15c20000(struct bregs *regs) { - inhibit_mouse_int_and_events(); // disable IRQ12 and packets - send_to_mouse_ctrl(0xF5); // disable mouse command - u8 mouse_data1; - get_mouse_data(&mouse_data1); - set_code_success(regs); + int ret = mouse_command(PSMOUSE_CMD_DISABLE, NULL); + if (ret) + set_code_invalid(regs, RET_ENEEDRESEND); + else + set_code_success(regs); } -#define BX_DEBUG_INT15(args...) - // Enable Mouse static void mouse_15c20001(struct bregs *regs) { u8 mouse_flags_2 = GET_EBDA(mouse_flag2); if ((mouse_flags_2 & 0x80) == 0) { - BX_DEBUG_INT15("INT 15h C2 Enable Mouse, no far call handler\n"); - set_code_fail(regs, RET_ENOHANDLER); + set_code_invalid(regs, RET_ENOHANDLER); return; } - inhibit_mouse_int_and_events(); // disable IRQ12 and packets - send_to_mouse_ctrl(0xF4); // enable mouse command - u8 mouse_data1; - get_mouse_data(&mouse_data1); - if (mouse_data1 == 0xFA) { - enable_mouse_int_and_events(); // turn IRQ12 and packet generation on + + int ret = mouse_command(PSMOUSE_CMD_ENABLE, NULL); + if (ret) + set_code_invalid(regs, RET_ENEEDRESEND); + else set_code_success(regs); - return; - } - set_code_fail(regs, RET_ENEEDRESEND); } static void mouse_15c200XX(struct bregs *regs) { - set_code_fail(regs, RET_EINVFUNCTION); + set_code_unimplemented(regs, RET_EINVFUNCTION); } // Disable/Enable Mouse @@ -145,24 +86,14 @@ mouse_15c200(struct bregs *regs) static void mouse_15c201(struct bregs *regs) { - inhibit_mouse_int_and_events(); // disable IRQ12 and packets - send_to_mouse_ctrl(0xFF); // reset mouse command - u8 mouse_data1, mouse_data2, mouse_data3; - get_mouse_data(&mouse_data3); - // if no mouse attached, it will return RESEND - if (mouse_data3 == 0xfe) { - set_code_fail(regs, RET_ENEEDRESEND); + u8 param[2]; + int ret = mouse_command(PSMOUSE_CMD_RESET_BAT, param); + if (ret) { + set_code_invalid(regs, RET_ENEEDRESEND); return; } - if (mouse_data3 != 0xfa) - BX_PANIC("Mouse reset returned %02x (should be ack)\n" - , (unsigned)mouse_data3); - get_mouse_data(&mouse_data1); - get_mouse_data(&mouse_data2); - // turn IRQ12 and packet generation on - enable_mouse_int_and_events(); - regs->bl = mouse_data1; - regs->bh = mouse_data2; + regs->bl = param[0]; + regs->bh = param[1]; set_code_success(regs); } @@ -170,19 +101,17 @@ mouse_15c201(struct bregs *regs) static void mouse_15c202(struct bregs *regs) { - if (regs->bh >= 7) { - set_code_fail(regs, RET_EUNSUPPORTED); + static u8 VAR16 sample_rates[7] = {10, 20, 40, 60, 80, 100, 200}; + if (regs->bh >= ARRAY_SIZE(sample_rates)) { + set_code_invalid(regs, RET_EINVINPUT); return; } - u8 mouse_data1 = regs->bh * 20; - if (!mouse_data1) - mouse_data1 = 10; - send_to_mouse_ctrl(0xF3); // set sample rate command - u8 mouse_data2; - get_mouse_data(&mouse_data2); - send_to_mouse_ctrl(mouse_data1); - get_mouse_data(&mouse_data2); - set_code_success(regs); + u8 mouse_data1 = GET_GLOBAL(sample_rates[regs->bh]); + int ret = mouse_command(PSMOUSE_CMD_SETRATE, &mouse_data1); + if (ret) + set_code_invalid(regs, RET_ENEEDRESEND); + else + set_code_success(regs); } // Set Resolution @@ -194,38 +123,29 @@ mouse_15c203(struct bregs *regs) // 1 = 50 dpi, 2 counts per millimeter // 2 = 100 dpi, 4 counts per millimeter // 3 = 200 dpi, 8 counts per millimeter - u8 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets if (regs->bh >= 4) { - set_code_fail(regs, RET_EUNSUPPORTED); - goto done; + set_code_invalid(regs, RET_EINVINPUT); + return; } - send_to_mouse_ctrl(0xE8); // set resolution command - u8 mouse_data1; - get_mouse_data(&mouse_data1); - if (mouse_data1 != 0xfa) - BX_PANIC("Mouse status returned %02x (should be ack)\n" - , (unsigned)mouse_data1); - send_to_mouse_ctrl(regs->bh); - get_mouse_data(&mouse_data1); - if (mouse_data1 != 0xfa) - BX_PANIC("Mouse status returned %02x (should be ack)\n" - , (unsigned)mouse_data1); - set_code_success(regs); - -done: - set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable + u8 param = regs->bh; + int ret = mouse_command(PSMOUSE_CMD_SETRES, ¶m); + if (ret) + set_code_invalid(regs, RET_ENEEDRESEND); + else + set_code_success(regs); } // Get Device ID static void mouse_15c204(struct bregs *regs) { - inhibit_mouse_int_and_events(); // disable IRQ12 and packets - send_to_mouse_ctrl(0xF2); // get mouse ID command - u8 mouse_data1, mouse_data2; - get_mouse_data(&mouse_data1); - get_mouse_data(&mouse_data2); - regs->bh = mouse_data2; + u8 param[2]; + int ret = mouse_command(PSMOUSE_CMD_GETID, param); + if (ret) { + set_code_invalid(regs, RET_ENEEDRESEND); + return; + } + regs->bh = param[0]; set_code_success(regs); } @@ -234,11 +154,12 @@ static void mouse_15c205(struct bregs *regs) { if (regs->bh != 3) { - set_code_fail(regs, RET_EINTERFACE); + set_code_invalid(regs, RET_EINTERFACE); return; } - SET_EBDA(mouse_flag1, 0x00); - SET_EBDA(mouse_flag2, regs->bh); + u16 ebda_seg = get_ebda_seg(); + SET_EBDA2(ebda_seg, mouse_flag1, 0x00); + SET_EBDA2(ebda_seg, mouse_flag2, regs->bh); // Reset Mouse mouse_15c201(regs); @@ -248,55 +169,44 @@ mouse_15c205(struct bregs *regs) static void mouse_15c20600(struct bregs *regs) { - u8 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets - send_to_mouse_ctrl(0xE9); // get mouse info command - u8 mouse_data1, mouse_data2, mouse_data3; - get_mouse_data(&mouse_data1); - if (mouse_data1 != 0xfa) - BX_PANIC("Mouse status returned %02x (should be ack)\n" - , (unsigned)mouse_data1); - get_mouse_data(&mouse_data1); - get_mouse_data(&mouse_data2); - get_mouse_data(&mouse_data3); - regs->bl = mouse_data1; - regs->cl = mouse_data2; - regs->dl = mouse_data3; + u8 param[3]; + int ret = mouse_command(PSMOUSE_CMD_GETINFO, param); + if (ret) { + set_code_invalid(regs, RET_ENEEDRESEND); + return; + } + regs->bl = param[0]; + regs->cl = param[1]; + regs->dl = param[2]; set_code_success(regs); - set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable -} - -static void -set_scaling(struct bregs *regs, u8 cmd) -{ - u8 comm_byte = inhibit_mouse_int_and_events(); // disable IRQ12 and packets - send_to_mouse_ctrl(0xE6); - u8 mouse_data1; - get_mouse_data(&mouse_data1); - if (mouse_data1 != 0xFA) - set_code_fail(regs, RET_EUNSUPPORTED); - else - set_code_success(regs); - set_kbd_command_byte(comm_byte); // restore IRQ12 and serial enable } // Set Scaling Factor to 1:1 static void mouse_15c20601(struct bregs *regs) { - set_scaling(regs, 0xE6); + int ret = mouse_command(PSMOUSE_CMD_SETSCALE11, NULL); + if (ret) + set_code_invalid(regs, RET_ENEEDRESEND); + else + set_code_success(regs); } // Set Scaling Factor to 2:1 static void mouse_15c20602(struct bregs *regs) { - set_scaling(regs, 0xE7); + int ret = mouse_command(PSMOUSE_CMD_SETSCALE21, NULL); + if (ret) + set_code_invalid(regs, RET_ENEEDRESEND); + else + set_code_success(regs); } static void mouse_15c206XX(struct bregs *regs) { - BX_PANIC("INT 15h C2 AL=6, BH=%02x\n", regs->bh); + set_code_unimplemented(regs, RET_EINVFUNCTION); } // Return Status & Set Scaling Factor... @@ -315,27 +225,28 @@ mouse_15c206(struct bregs *regs) static void mouse_15c207(struct bregs *regs) { - u32 farptr = (regs->es << 16) | regs->bx; - SET_EBDA(far_call_pointer, farptr); - u8 mouse_flags_2 = GET_EBDA(mouse_flag2); - if (! farptr) { + struct segoff_s farptr = SEGOFF(regs->es, regs->bx); + u16 ebda_seg = get_ebda_seg(); + u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); + if (! farptr.segoff) { /* remove handler */ if ((mouse_flags_2 & 0x80) != 0) { mouse_flags_2 &= ~0x80; - inhibit_mouse_int_and_events(); // disable IRQ12 and packets + mouse_command(PSMOUSE_CMD_DISABLE, NULL); } } else { /* install handler */ mouse_flags_2 |= 0x80; } - SET_EBDA(mouse_flag2, mouse_flags_2); + SET_EBDA2(ebda_seg, mouse_flag2, mouse_flags_2); + SET_EBDA2(ebda_seg, far_call_pointer, farptr); set_code_success(regs); } static void mouse_15c2XX(struct bregs *regs) { - set_code_fail(regs, RET_EINVFUNCTION); + set_code_unimplemented(regs, RET_EINVFUNCTION); } void @@ -343,8 +254,8 @@ handle_15c2(struct bregs *regs) { //debug_stub(regs); - if (! CONFIG_PS2_MOUSE) { - set_code_fail(regs, RET_EUNSUPPORTED); + if (! CONFIG_MOUSE) { + set_code_invalid(regs, RET_EUNSUPPORTED); return; } @@ -361,42 +272,43 @@ handle_15c2(struct bregs *regs) } } -static void -int74_function() +void noinline +process_mouse(u8 data) { - u8 v = inb(PORT_PS2_STATUS); - if ((v & 0x21) != 0x21) + if (!CONFIG_MOUSE) return; - v = inb(PORT_PS2_DATA); - - u8 mouse_flags_1 = GET_EBDA(mouse_flag1); - u8 mouse_flags_2 = GET_EBDA(mouse_flag2); + u16 ebda_seg = get_ebda_seg(); + u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1); + u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); - if ((mouse_flags_2 & 0x80) != 0x80) + if (! (mouse_flags_2 & 0x80)) + // far call handler not installed return; u8 package_count = mouse_flags_2 & 0x07; u8 index = mouse_flags_1 & 0x07; - SET_EBDA(mouse_data[index], v); + SET_EBDA2(ebda_seg, mouse_data[index], data); if ((index+1) < package_count) { mouse_flags_1++; - SET_EBDA(mouse_flag1, mouse_flags_1); + SET_EBDA2(ebda_seg, mouse_flag1, mouse_flags_1); return; } - //BX_DEBUG_INT74("int74_function: make_farcall=1\n"); - u16 status = GET_EBDA(mouse_data[0]); - u16 X = GET_EBDA(mouse_data[1]); - u16 Y = GET_EBDA(mouse_data[2]); - SET_EBDA(mouse_flag1, 0); - // check if far call handler installed - if (! (mouse_flags_2 & 0x80)) - return; + u16 status = GET_EBDA2(ebda_seg, mouse_data[0]); + u16 X = GET_EBDA2(ebda_seg, mouse_data[1]); + u16 Y = GET_EBDA2(ebda_seg, mouse_data[2]); + SET_EBDA2(ebda_seg, mouse_flag1, 0); + + struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer); + dprintf(16, "mouse farcall s=%04x x=%04x y=%04x func=%04x:%04x\n" + , status, X, Y, func.seg, func.offset); - u32 func = GET_EBDA(far_call_pointer); asm volatile( + "pushl %%ebp\n" + "sti\n" + "pushl %0\n" "pushw %w1\n" // status "pushw %w2\n" // X @@ -404,22 +316,11 @@ int74_function() "pushw $0\n" // Z "lcallw *8(%%esp)\n" "addl $12, %%esp\n" + + "cli\n" "cld\n" - : "+a" (func), "+b" (status), "+c" (X), "+d" (Y) + "popl %%ebp" + : "+a"(func.segoff), "+c"(status), "+d"(X), "+b"(Y) : - : "esi", "edi", "ebp", "cc" - ); -} - -// INT74h : PS/2 mouse hardware interrupt -void VISIBLE16 -handle_74() -{ - debug_isr(DEBUG_ISR_74); - - irq_enable(); - int74_function(); - irq_disable(); - - eoi_both_pics(); + : "edi", "esi", "cc", "memory"); }