From: Vladimir Serbinenko Date: Mon, 22 Feb 2016 20:12:50 +0000 (+0100) Subject: cros e0 fix X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40562ddf1e8a27eafb9433162e8902dfc94c9119;p=thirdparty%2Fgrub.git cros e0 fix --- diff --git a/grub-core/kern/arm/coreboot/dma.c b/grub-core/kern/arm/coreboot/dma.c new file mode 100644 index 000000000..2c2a62789 --- /dev/null +++ b/grub-core/kern/arm/coreboot/dma.c @@ -0,0 +1,59 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_pci_dma_chunk * +grub_memalign_dma32 (grub_size_t align, grub_size_t size) +{ + void *ret; + if (align < 64) + align = 64; + size = ALIGN_UP (size, align); + ret = grub_memalign (align, size); + if (!ret) + return 0; + grub_arch_sync_dma_caches (ret, size); + return ret; +} + +void +grub_dma_free (struct grub_pci_dma_chunk *ch) +{ + grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN; + grub_arch_sync_dma_caches (ch, size); + grub_free (ch); +} + +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ch; +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (grub_uint32_t) (grub_addr_t) ch; +} + diff --git a/grub-core/term/arm/cros.c b/grub-core/term/arm/cros.c index de6c3eae7..dba938a9e 100644 --- a/grub-core/term/arm/cros.c +++ b/grub-core/term/arm/cros.c @@ -34,6 +34,14 @@ struct cros_ec_keyscan old_scan; static grub_uint8_t map_code[CROS_EC_KEYSCAN_COLS][CROS_EC_KEYSCAN_ROWS]; +static grub_uint8_t e0_translate[16] = + { + 0x1c, 0x1d, 0x35, 0x00, + 0x38, 0x00, 0x47, 0x48, + 0x49, 0x4b, 0x4d, 0x4f, + 0x50, 0x51, 0x52, 0x53, + }; + /* If there is a character pending, return it; otherwise return GRUB_TERM_NO_KEY. */ static int @@ -49,13 +57,19 @@ grub_cros_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)) { grub_uint8_t code = map_code[i][j]; int ret; + grub_uint8_t brk = 0; if (!(scan.data[i] & (1 << j))) - code |= 0x80; + brk = 0x80; grub_dprintf ("cros_keyboard", "key <%d, %d> code %x\n", i, j, code); - if (code == 0) - ret = GRUB_TERM_NO_KEY; + if (code < 0x60) + ret = grub_ps2_process_incoming_byte (&ps2_state, code | brk); + else if (code >= 0x60 && code < 0x70 && e0_translate[code - 0x60]) + { + grub_ps2_process_incoming_byte (&ps2_state, 0xe0); + ret = grub_ps2_process_incoming_byte (&ps2_state, e0_translate[code - 0x60] | brk); + } else - ret = grub_ps2_process_incoming_byte (&ps2_state, code); + ret = GRUB_TERM_NO_KEY; old_scan.data[i] ^= (1 << j); if (ret != GRUB_TERM_NO_KEY) return ret; diff --git a/grub-core/term/arm/cros_ec.h b/grub-core/term/arm/cros_ec.h new file mode 100644 index 000000000..5c8f0b8d0 --- /dev/null +++ b/grub-core/term/arm/cros_ec.h @@ -0,0 +1,59 @@ +#include +/* + * Hard-code the number of columns we happen to know we have right now. It + * would be more correct to call cros_ec_mkbp_info() at startup and determine + * the actual number of keyboard cols from there. + */ +#define CROS_EC_KEYSCAN_COLS 13 +#define CROS_EC_KEYSCAN_ROWS 8 + +/* Information returned by a key scan */ +struct cros_ec_keyscan { + grub_uint8_t data[CROS_EC_KEYSCAN_COLS]; +}; + +typedef struct CrosEcBusOps +{ + int (*init)(struct CrosEcBusOps *me); + + /** + * Send a command to a ChromeOS EC device and return the reply. + * + * The device's internal input/output buffers are used. + * + * @param bus ChromeOS EC bus ops + * @param cmd Command to send (EC_CMD_...) + * @param cmd_version Version of command to send (EC_VER_...) + * @param dout Output data (may be NULL If dout_len=0) + * @param dout_len Size of output data in bytes + * @param dinp Returns pointer to response data + * @param din_len Maximum size of response in bytes + * @return number of bytes in response, or -1 on error + */ + int (*send_command)(struct CrosEcBusOps *me, grub_uint8_t cmd, + int cmd_version, + const void *dout, grub_uint32_t dout_len, + void *din, grub_uint32_t din_len); + + int (*send_packet)(struct CrosEcBusOps *me, + const void *dout, grub_uint32_t dout_len, + void *din, grub_uint32_t din_len); + + /** + * Byte I/O functions. + * + * Read or write a sequence a bytes over the desired protocol. + * Used to support protocol variants - currently only implemented + * for LPC. + * + * @param data Read / write data buffer + * @param port I/O port + * @size Number of bytes to read / write + */ + void (*read)(grub_uint8_t *data, grub_uint16_t port, int size); + void (*write)(const grub_uint8_t *data, grub_uint16_t port, int size); +} CrosEcBusOps; + +int cros_ec_set_bus(CrosEcBusOps *bus); +int cros_ec_scan_keyboard(struct cros_ec_keyscan *scan); +int cros_ec_init(void);