<p>Philipp Deppenwiese <strong>merged</strong> this change.</p><p><a href="https://review.coreboot.org/18597">View Change</a></p><div style="white-space:pre-wrap">Approvals:
build bot (Jenkins): Verified
Patrick Georgi: Looks good to me, approved
Philipp Deppenwiese: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libpayload-x86: Add PS2 mouse driver<br><br>Make use of i8042 driver to add PS2 mouse driver support.<br><br>Tested on Lenovot T500.<br>The touchpad can be used to drive the mouse cursor.<br><br>Change-Id: I4be9c74467596b94d64dfa510824d8722108fe9c<br>Signed-off-by: Patrick Rudolph <siro@das-labor.org><br>Reviewed-on: https://review.coreboot.org/18597<br>Tested-by: build bot (Jenkins) <no-reply@coreboot.org><br>Reviewed-by: Patrick Georgi <pgeorgi@google.com><br>Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com><br>---<br>M payloads/libpayload/Kconfig<br>M payloads/libpayload/drivers/Makefile.inc<br>A payloads/libpayload/drivers/i8042/mouse.c<br>M payloads/libpayload/drivers/mouse_cursor.c<br>M payloads/libpayload/include/libpayload.h<br>5 files changed, 314 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig</span><br><span>index d4d76bb..e482e93 100644</span><br><span>--- a/payloads/libpayload/Kconfig</span><br><span>+++ b/payloads/libpayload/Kconfig</span><br><span>@@ -331,11 +331,18 @@</span><br><span> </span><br><span> config PC_I8042</span><br><span> bool "A common PC i8042 driver"</span><br><span style="color: hsl(0, 100%, 40%);">- default y if PC_KEYBOARD</span><br><span style="color: hsl(120, 100%, 40%);">+ default y if PC_KEYBOARD || PC_MOUSE</span><br><span> default n</span><br><span> help</span><br><span> To be used by PC_KEYBOARD and PC_MOUSE.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+config PC_MOUSE</span><br><span style="color: hsl(120, 100%, 40%);">+ bool "Allow input from a PC mouse"</span><br><span style="color: hsl(120, 100%, 40%);">+ default y if ARCH_X86 # uses IO</span><br><span style="color: hsl(120, 100%, 40%);">+ default n</span><br><span style="color: hsl(120, 100%, 40%);">+ help</span><br><span style="color: hsl(120, 100%, 40%);">+ PS/2 mouse driver on top of PC_I8042.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> config PC_KEYBOARD</span><br><span> bool "Allow input from a PC keyboard"</span><br><span> default y if ARCH_X86 # uses IO</span><br><span>@@ -367,6 +374,7 @@</span><br><span> </span><br><span> config MOUSE_CURSOR</span><br><span> bool "Support for mouse cursor handling"</span><br><span style="color: hsl(120, 100%, 40%);">+ default y if PC_MOUSE</span><br><span> default n</span><br><span> help</span><br><span> Provides a common interface for various mouse cursor drivers.</span><br><span>diff --git a/payloads/libpayload/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc</span><br><span>index 6eb9f0c..2d70856 100644</span><br><span>--- a/payloads/libpayload/drivers/Makefile.inc</span><br><span>+++ b/payloads/libpayload/drivers/Makefile.inc</span><br><span>@@ -39,6 +39,7 @@</span><br><span> libc-$(CONFIG_LP_IPQ40XX_SERIAL_CONSOLE) += serial/ipq40xx.c serial/serial.c</span><br><span> libc-$(CONFIG_LP_BG4CD_SERIAL_CONSOLE) += serial/bg4cd.c serial/serial.c</span><br><span> libc-$(CONFIG_LP_PC_KEYBOARD) += i8042/keyboard.c</span><br><span style="color: hsl(120, 100%, 40%);">+libc-$(CONFIG_LP_PC_MOUSE) += i8042/mouse.c</span><br><span> libc-$(CONFIG_LP_PC_I8042) += i8042/i8042.c</span><br><span> </span><br><span> libc-$(CONFIG_LP_CBMEM_CONSOLE) += cbmem_console.c</span><br><span>diff --git a/payloads/libpayload/drivers/i8042/mouse.c b/payloads/libpayload/drivers/i8042/mouse.c</span><br><span>new file mode 100644</span><br><span>index 0000000..21096d1</span><br><span>--- /dev/null</span><br><span>+++ b/payloads/libpayload/drivers/i8042/mouse.c</span><br><span>@@ -0,0 +1,292 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the libpayload project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Redistribution and use in source and binary forms, with or without</span><br><span style="color: hsl(120, 100%, 40%);">+ * modification, are permitted provided that the following conditions</span><br><span style="color: hsl(120, 100%, 40%);">+ * are met:</span><br><span style="color: hsl(120, 100%, 40%);">+ * 1. Redistributions of source code must retain the above copyright</span><br><span style="color: hsl(120, 100%, 40%);">+ * notice, this list of conditions and the following disclaimer.</span><br><span style="color: hsl(120, 100%, 40%);">+ * 2. Redistributions in binary form must reproduce the above copyright</span><br><span style="color: hsl(120, 100%, 40%);">+ * notice, this list of conditions and the following disclaimer in the</span><br><span style="color: hsl(120, 100%, 40%);">+ * documentation and/or other materials provided with the distribution.</span><br><span style="color: hsl(120, 100%, 40%);">+ * 3. The name of the author may not be used to endorse or promote products</span><br><span style="color: hsl(120, 100%, 40%);">+ * derived from this software without specific prior written permission.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND</span><br><span style="color: hsl(120, 100%, 40%);">+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span><br><span style="color: hsl(120, 100%, 40%);">+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</span><br><span style="color: hsl(120, 100%, 40%);">+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE</span><br><span style="color: hsl(120, 100%, 40%);">+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL</span><br><span style="color: hsl(120, 100%, 40%);">+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS</span><br><span style="color: hsl(120, 100%, 40%);">+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)</span><br><span style="color: hsl(120, 100%, 40%);">+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT</span><br><span style="color: hsl(120, 100%, 40%);">+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY</span><br><span style="color: hsl(120, 100%, 40%);">+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF</span><br><span style="color: hsl(120, 100%, 40%);">+ * SUCH DAMAGE.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <libpayload-config.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <libpayload.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int x_axis;</span><br><span style="color: hsl(120, 100%, 40%);">+static int y_axis;</span><br><span style="color: hsl(120, 100%, 40%);">+static int z_axis;</span><br><span style="color: hsl(120, 100%, 40%);">+static u32 buttons;</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 is_intellimouse;</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 is_explorer_intellimouse;</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 initialized;</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned char mouse_buf[4];</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned char mouse_buf_idx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 mouse_cmd(unsigned char cmd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_cmd(0xd4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_write_data(cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return i8042_wait_read_aux() == 0xfa;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 mouse_cmd_data(u8 cmd, u8 val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(cmd))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return mouse_cmd(val);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Try to detect Microsoft Intelli mouse */</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 mouse_is_intellimouse(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Silence mouse. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf5))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set standard. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf6))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Magic sequence. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd_data(0xf3, 0xc8))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd_data(0xf3, 0x64))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd_data(0xf3, 0x50))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Get mouse id */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf2))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (i8042_wait_read_aux() != 0x03)</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Try to detect Microsoft Explorer mouse */</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 mouse_is_intellimouse_explorer(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Silence mouse. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf5))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set standard. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf6))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Magic sequence. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd_data(0xf3, 0xc8))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd_data(0xf3, 0xc8))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd_data(0xf3, 0x50))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Get mouse id */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf2))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (i8042_wait_read_aux() != 4)</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Decode temporary buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * Sanity check to prevent out of order decode.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Decode PS/2 data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Supported devices:</span><br><span style="color: hsl(120, 100%, 40%);">+ * Generic 3 button mouse</span><br><span style="color: hsl(120, 100%, 40%);">+ * Microsoft Intelli mouse</span><br><span style="color: hsl(120, 100%, 40%);">+ * Microsoft Explorer mouse</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void mouse_decode(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Buffer full check and sanity check */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_intellimouse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mouse_buf_idx < 4)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((mouse_buf[3] & 0x10) != (mouse_buf[3] & 0x08)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_buf_idx = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (is_explorer_intellimouse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mouse_buf_idx < 4)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mouse_buf[3] & 0xc0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_buf_idx = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mouse_buf_idx < 3)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Common protocol */</span><br><span style="color: hsl(120, 100%, 40%);">+ x_axis += mouse_buf[1] ? mouse_buf[1] - ((mouse_buf[0] << 4) & 0x100) : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ y_axis += mouse_buf[2] ? ((mouse_buf[0] << 3) & 0x100) - mouse_buf[2] : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ buttons = mouse_buf[0] & 0x7;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Extended protocol */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_intellimouse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ z_axis += (mouse_buf[3] & 0x7) - (mouse_buf[3] & 0x08) ? 8 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (is_explorer_intellimouse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ z_axis += (mouse_buf[3] & 0x7) - (mouse_buf[3] & 0x08) ? 8 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ buttons = (mouse_buf[0] & 0x7) | (mouse_buf[3] & 0x30) >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_buf_idx = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Insert data into internal temporary buffer. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void insert_buf(unsigned char c)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Validate input:</span><br><span style="color: hsl(120, 100%, 40%);">+ * First byte shall have bit 3 set ! */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_buf_idx && !(c & 8))</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_buf[mouse_buf_idx++] = c;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Probe i8042 for new aux data and try to decode it. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void mouse_sample(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!initialized)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (i8042_data_ready_aux()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ insert_buf(i8042_read_data_aux());</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_decode();</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Mouse cursor interface method</span><br><span style="color: hsl(120, 100%, 40%);">+ * Return and reset internal state.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void mouse_state(int *x, int *y, int *z, u32 *b)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!initialized)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_sample();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (x) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *x = x_axis;</span><br><span style="color: hsl(120, 100%, 40%);">+ x_axis = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (y) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *y = y_axis;</span><br><span style="color: hsl(120, 100%, 40%);">+ y_axis = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (z) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *z = z_axis;</span><br><span style="color: hsl(120, 100%, 40%);">+ z_axis = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (b)</span><br><span style="color: hsl(120, 100%, 40%);">+ *b = buttons;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct mouse_cursor_input_driver curs = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .get_state = mouse_state,</span><br><span style="color: hsl(120, 100%, 40%);">+ .input_type = CURSOR_INPUT_TYPE_PS2,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/** Probe for PS/2 mouse */</span><br><span style="color: hsl(120, 100%, 40%);">+void i8042_mouse_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Initialize keyboard controller.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Might fail in case no AUX port or firmware disabled the AUX port.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!i8042_probe() || !i8042_has_aux())</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Empty mouse buffer. */</span><br><span style="color: hsl(120, 100%, 40%);">+ while (i8042_data_ready_aux())</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_read_data_aux();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Enable mouse.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Documentation is unclear at this point.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Some recommend to wait for response, some claim there's none.</span><br><span style="color: hsl(120, 100%, 40%);">+ * No response on Lenovo H8 EC.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Ignore it ... */</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = i8042_cmd(0xa8);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret == -1)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Silence mouse. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf5))</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Read mouse id. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf2))</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = i8042_wait_read_aux();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Get and enable features (scroll wheel and 5 buttons) */</span><br><span style="color: hsl(120, 100%, 40%);">+ is_intellimouse = mouse_is_intellimouse();</span><br><span style="color: hsl(120, 100%, 40%);">+ is_explorer_intellimouse = mouse_is_intellimouse_explorer();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set defaults. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf6))</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Enable data transmission. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!mouse_cmd(0xf4))</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ initialized = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Register mouse cursor driver */</span><br><span style="color: hsl(120, 100%, 40%);">+ mouse_cursor_add_input_driver(&curs);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Disable PS/2 mouse. */</span><br><span style="color: hsl(120, 100%, 40%);">+void i8042_mouse_disconnect(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If 0x64 returns 0xff, then we have no keyboard</span><br><span style="color: hsl(120, 100%, 40%);">+ * controller */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (inb(0x64) == 0xFF || !initialized)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Empty keyboard buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+ while (i8042_data_ready_aux())</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_read_data_aux();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Disable mouse. */</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_cmd(0xa7);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ initialized = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Release keyboard controller driver */</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_close();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/payloads/libpayload/drivers/mouse_cursor.c b/payloads/libpayload/drivers/mouse_cursor.c</span><br><span>index 781845c..40c8934 100644</span><br><span>--- a/payloads/libpayload/drivers/mouse_cursor.c</span><br><span>+++ b/payloads/libpayload/drivers/mouse_cursor.c</span><br><span>@@ -60,7 +60,9 @@</span><br><span> /** Init enabled mouse cursor drivers */</span><br><span> void mouse_cursor_init(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-/* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+#if IS_ENABLED(CONFIG_LP_PC_MOUSE)</span><br><span style="color: hsl(120, 100%, 40%);">+ i8042_mouse_init();</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> }</span><br><span> </span><br><span> static u32 mouse_buttons;</span><br><span>diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h</span><br><span>index 96cc5f8..c6b9447 100644</span><br><span>--- a/payloads/libpayload/include/libpayload.h</span><br><span>+++ b/payloads/libpayload/include/libpayload.h</span><br><span>@@ -204,6 +204,15 @@</span><br><span> /** @} */</span><br><span> </span><br><span> /**</span><br><span style="color: hsl(120, 100%, 40%);">+ * @defgroup i8042 PS2 Mouse functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ingroup input</span><br><span style="color: hsl(120, 100%, 40%);">+ * @{</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void i8042_mouse_init(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void i8042_mouse_disconnect(void);</span><br><span style="color: hsl(120, 100%, 40%);">+/** @} */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span> * @defgroup serial Serial functions</span><br><span> * @ingroup input</span><br><span> * @{</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/18597">change 18597</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/18597"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I4be9c74467596b94d64dfa510824d8722108fe9c </div>
<div style="display:none"> Gerrit-Change-Number: 18597 </div>
<div style="display:none"> Gerrit-PatchSet: 8 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <siro@das-labor.org> </div>
<div style="display:none"> Gerrit-Reviewer: Julius Werner <jwerner@chromium.org> </div>
<div style="display:none"> Gerrit-Reviewer: Martin Roth <martinroth@google.com> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Georgi <pgeorgi@google.com> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Rudolph <patrick.rudolph@9elements.com> </div>
<div style="display:none"> Gerrit-Reviewer: Patrick Rudolph <siro@das-labor.org> </div>
<div style="display:none"> Gerrit-Reviewer: Paul Menzel <paulepanter@users.sourceforge.net> </div>
<div style="display:none"> Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org> </div>