summaryrefslogtreecommitdiff
path: root/chip/stm32/i2c-stm32f0.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2016-09-16 10:36:54 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-10-19 20:07:09 -0700
commit5e1c63f6ebc9afb847d635c36e0bec31ecdf6a52 (patch)
tree6943771d8186285428869c72252a151f62a48069 /chip/stm32/i2c-stm32f0.c
parent09ad7536ce23eef7fcfb5a46318990fbe4914843 (diff)
downloadchrome-ec-5e1c63f6ebc9afb847d635c36e0bec31ecdf6a52.tar.gz
Support alignment for EC host command structures
The host command parameter and response buffers should be explicitly aligned by the LPC/SPI/I2C drivers. But the host command handlers don't know that, and the structs are all __packed, so the compiler generates horribly inefficient ARM Cortex-M code to cope with unaligned accesses. Add __ec_align{1,2,4} to force the param / response structs to be aligned. Use it in a few structs now which were straightforward to test. It should be added to more structs as space is needed, but that would make this change unwieldy to review and test. Add CONFIG_HOSTCMD_ALIGNED to enable the additional alignment. Currently, this is enabled only for LM4 and samus_pd, so that EC code can be tested without affecting other non-samus ToT development (none of which uses LM4). Fix the two handlers that weren't actually aligned (despite one of them having comments to the contrary). Also, add a CHROMIUM_EC define that can be used to determine if a file is being compiled for an EC target. We need that so that we only force structure alignment for EC binaries. On the AP side, buffers may not be aligned, so we should not force alignment. BUG=chromium:647727 BRANCH=none TEST=Flash samus and samus_pd. Boot samus and run a bunch of ectool commands (with and without --dev=1, so it tests both EC and PD). System boots and all commands return expected results. Change-Id: I4537d61a75cf087647e24281288392eb85f22eba Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/387126
Diffstat (limited to 'chip/stm32/i2c-stm32f0.c')
-rw-r--r--chip/stm32/i2c-stm32f0.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/chip/stm32/i2c-stm32f0.c b/chip/stm32/i2c-stm32f0.c
index d33941d5b5..5b58cb3e45 100644
--- a/chip/stm32/i2c-stm32f0.c
+++ b/chip/stm32/i2c-stm32f0.c
@@ -193,9 +193,11 @@ defined(CONFIG_LOW_POWER_IDLE) && \
/* Host command slave */
/*
* Buffer for received host command packets (including prefix byte on request,
- * and result/size on response)
+ * and result/size on response). After any protocol-specific headers, the
+ * buffers must be 32-bit aligned.
*/
-static uint8_t host_buffer[I2C_MAX_HOST_PACKET_SIZE + 2];
+static uint8_t host_buffer_padded[I2C_MAX_HOST_PACKET_SIZE + 4] __aligned(4);
+static uint8_t * const host_buffer = host_buffer_padded + 2;
static uint8_t params_copy[I2C_MAX_HOST_PACKET_SIZE] __aligned(4);
static int host_i2c_resp_port;
static int tx_pending;
@@ -248,7 +250,9 @@ static void i2c_process_command(void)
/*
* Stuff response at buff[2] to leave the first two bytes of
- * buffer available for the result and size to send over i2c.
+ * buffer available for the result and size to send over i2c. Note
+ * that this 2-byte offset and the 2-byte offset from host_buffer
+ * add up to make the response buffer 32-bit aligned.
*/
i2c_packet.response = (void *)(&buff[2]);
i2c_packet.response_max = I2C_MAX_HOST_PACKET_SIZE;