mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
Use EC LPC arbitration to prevent host writes to memmap space
Previously, the host could write to this space and corrupt the memmap data. BUG=chrome-os-partner:10210 TEST=manual From a root shell: localhost ~ # io_read32 0x960 0x574e5553 localhost ~ # io_write32 0x960 0x1234 localhost ~ # io_read32 0x960 0x574e5553 That verifies that the EC is rejecting host writes on the memmap range localhost ~ # ectool hello EC says hello! That verifies the host is still able to write to the user param range Change-Id: I8c29571f439a14f308ed73f4c641264e17f944e9 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/25115 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#define LPC_CH_CMD_DATA 2 /* Data for kernel/user-mode commands */
|
||||
#define LPC_CH_KEYBOARD 3 /* 8042 keyboard emulation */
|
||||
#define LPC_CH_USER 4 /* User-mode commands */
|
||||
#define LPC_CH_MEMMAP 5 /* Data for kernel/user-mode commands */
|
||||
#define LPC_CH_COMX 7 /* UART emulation */
|
||||
/* LPC pool offsets */
|
||||
#define LPC_POOL_OFFS_KERNEL 0 /* Kernel commands - 0=in, 1=out */
|
||||
@@ -48,7 +49,8 @@
|
||||
#define LPC_POOL_OFFS_COMX 8 /* UART emulation range - 8-15 */
|
||||
#define LPC_POOL_OFFS_KEYBOARD 16 /* Keyboard - 16=in, 17=out */
|
||||
#define LPC_POOL_OFFS_USER 20 /* User commands - 20=in, 21=out */
|
||||
#define LPC_POOL_OFFS_CMD_DATA 512 /* Data range for commands - 512-1023 */
|
||||
#define LPC_POOL_OFFS_CMD_DATA 512 /* Data range for commands - 512-767 */
|
||||
#define LPC_POOL_OFFS_MEMMAP 768 /* Data range for commands - 768-1023 */
|
||||
/* LPC pool data pointers */
|
||||
#define LPC_POOL_KERNEL (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_KERNEL)
|
||||
#define LPC_POOL_PORT80 (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_PORT80)
|
||||
@@ -56,6 +58,7 @@
|
||||
#define LPC_POOL_KEYBOARD (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_KEYBOARD)
|
||||
#define LPC_POOL_CMD_DATA (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_CMD_DATA)
|
||||
#define LPC_POOL_USER (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_USER)
|
||||
#define LPC_POOL_MEMMAP (LM4_LPC_LPCPOOL + LPC_POOL_OFFS_MEMMAP)
|
||||
/* LPC COMx I/O address (in x86 I/O address space) */
|
||||
#define LPC_COMX_ADDR 0x3f8 /* COM1 */
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ uint8_t *host_get_buffer(int slot)
|
||||
|
||||
uint8_t *lpc_get_memmap_range(void)
|
||||
{
|
||||
return (uint8_t *)LPC_POOL_CMD_DATA + EC_PARAM_SIZE * 2;
|
||||
return (uint8_t *)LPC_POOL_MEMMAP;
|
||||
}
|
||||
|
||||
|
||||
@@ -445,14 +445,13 @@ static int lpc_init(void)
|
||||
|
||||
|
||||
/* Set LPC channel 2 to I/O address 0x800, range endpoint,
|
||||
* arbitration disabled, pool bytes 512-1023. To access this from
|
||||
* x86, use the following commands to set GEN_LPC2 and GEN_LPC3:
|
||||
* arbitration disabled, pool bytes 512-767. To access this from
|
||||
* x86, use the following command to set GEN_LPC2:
|
||||
*
|
||||
* pci_write32 0 0x1f 0 0x88 0x007c0801
|
||||
* pci_write32 0 0x1f 0 0x8c 0x007c0901
|
||||
*/
|
||||
LM4_LPC_ADR(LPC_CH_CMD_DATA) = EC_LPC_ADDR_KERNEL_PARAM;
|
||||
LM4_LPC_CTL(LPC_CH_CMD_DATA) = 0x801D |
|
||||
LM4_LPC_CTL(LPC_CH_CMD_DATA) = 0x8019 |
|
||||
(LPC_POOL_OFFS_CMD_DATA << (5 - 1));
|
||||
|
||||
/* Set LPC channel 3 to I/O address 0x60 (data) / 0x64 (command),
|
||||
@@ -473,6 +472,15 @@ static int lpc_init(void)
|
||||
/* Unmask interrupt for host command writes */
|
||||
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_USER, 4);
|
||||
|
||||
/* Set LPC channel 5 to I/O address 0x900, range endpoint,
|
||||
* arbitration enabled, pool bytes 768-1023. To access this from
|
||||
* x86, use the following command to set GEN_LPC3:
|
||||
*
|
||||
* pci_write32 0 0x1f 0 0x8c 0x007c0901
|
||||
*/
|
||||
LM4_LPC_ADR(LPC_CH_MEMMAP) = EC_LPC_ADDR_MEMMAP;
|
||||
LM4_LPC_CTL(LPC_CH_MEMMAP) = 0x0019 | (LPC_POOL_OFFS_MEMMAP << (5 - 1));
|
||||
|
||||
/* Set LPC channel 7 to COM port I/O address. Note that channel 7
|
||||
* ignores the TYPE bit and is always an 8-byte range. */
|
||||
LM4_LPC_ADR(LPC_CH_COMX) = LPC_COMX_ADDR;
|
||||
@@ -498,8 +506,23 @@ static int lpc_init(void)
|
||||
(1 << LPC_CH_CMD_DATA) |
|
||||
(1 << LPC_CH_KEYBOARD) |
|
||||
(1 << LPC_CH_USER) |
|
||||
(1 << LPC_CH_MEMMAP) |
|
||||
(1 << LPC_CH_COMX);
|
||||
|
||||
/*
|
||||
* Ensure the EC (slave) has control of the memory-mapped I/O space.
|
||||
* Once the EC has won arbtration for the memory-mapped space, it will
|
||||
* keep control of it until it writes the last byte in the space.
|
||||
* (That never happens; we can't use the last byte in the space because
|
||||
* ACPI can't see it anyway.)
|
||||
*/
|
||||
while (!(LM4_LPC_ST(LPC_CH_MEMMAP) & 0x10)) {
|
||||
/* Clear HW1ST */
|
||||
LM4_LPC_ST(LPC_CH_MEMMAP) &= ~0x40;
|
||||
/* Do a dummy slave write; this should cause SW1ST to be set */
|
||||
*LPC_POOL_MEMMAP = *LPC_POOL_MEMMAP;
|
||||
}
|
||||
|
||||
/* Enable LPC interrupt */
|
||||
task_enable_irq(LM4_IRQ_LPC);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user