diff options
author | Randall Spangler <rspangler@chromium.org> | 2016-09-16 10:36:54 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-10-19 20:07:09 -0700 |
commit | 5e1c63f6ebc9afb847d635c36e0bec31ecdf6a52 (patch) | |
tree | 6943771d8186285428869c72252a151f62a48069 /chip/stm32/i2c-stm32f0.c | |
parent | 09ad7536ce23eef7fcfb5a46318990fbe4914843 (diff) | |
download | chrome-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.c | 10 |
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; |