From bd90a226a3ea0ecaa244dbc36be9fa1dabdb352a Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 15 Feb 2022 06:33:13 +0100 Subject: [PATCH] nb/intel/ironlake: Fix sending HECI messages This code only worked when the payload (a packed struct) was 4 byte aligned. With gcc11 this happens to not be the case. Change-Id: I5bb4ca4b27f8554208b12da177c51091ea6a108f Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/61938 Tested-by: build bot (Jenkins) Reviewed-by: Elyes Haouas Reviewed-by: Nico Huber Reviewed-by: Angel Pons --- .../intel/ibexpeak/setup_heci_uma.c | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/southbridge/intel/ibexpeak/setup_heci_uma.c b/src/southbridge/intel/ibexpeak/setup_heci_uma.c index 3f8b6617c4..e490573812 100644 --- a/src/southbridge/intel/ibexpeak/setup_heci_uma.c +++ b/src/southbridge/intel/ibexpeak/setup_heci_uma.c @@ -37,19 +37,24 @@ static void wait_heci_cb_avail(int len) csr.csr.buffer_read_ptr)); } -static void send_heci_packet(struct mei_header *head, u32 *payload) +static void send_heci_packet_dword(u8 *payload, size_t length) { - int len = (head->length + 3) / 4; int i; + for (i = 0; i < length; i += sizeof(uint32_t)) { + uint32_t dword = 0; + size_t bytes = MIN(length - i, sizeof(dword)); + memcpy(&dword, payload + i, bytes); + write32(DEFAULT_HECIBAR + 0, dword); + } +} - wait_heci_cb_avail(len + 1); +static void send_heci_packet(struct mei_header *head, u8 *payload) +{ + wait_heci_cb_avail(DIV_ROUND_UP(sizeof(*head) + head->length, sizeof(u32))); - /* FIXME: handle leftovers correctly. */ - write32(DEFAULT_HECIBAR + 0, *(u32 *) head); - for (i = 0; i < len - 1; i++) - write32(DEFAULT_HECIBAR + 0, payload[i]); + send_heci_packet_dword((u8 *)head, sizeof(*head)); + send_heci_packet_dword(payload, head->length); - write32(DEFAULT_HECIBAR + 0, payload[i] & ((1 << (8 * len)) - 1)); write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 0x4); } @@ -72,7 +77,7 @@ static void send_heci_message(u8 *msg, int len, u8 hostaddress, u8 clientaddress head.reserved = 0; head.client_address = clientaddress; head.host_address = hostaddress; - send_heci_packet(&head, (u32 *) msg); + send_heci_packet(&head, msg); len -= cur; msg += cur; }