From d00cfcb0a1ec3669fdf3833cb3f2d11920bd622e Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Mon, 14 Feb 2022 12:55:31 +0100 Subject: nb/intel/ironlake/raminit_heci.c: Move to southbridge scope HECI stuff is in the southbridge, so put the code in there. Rename the file to match the name of the function it provides. Change-Id: I71de1234547dbd46a9b4959c619d2ae194da620a Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/61931 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/northbridge/intel/ironlake/Makefile.inc | 1 - src/northbridge/intel/ironlake/raminit.h | 2 - src/northbridge/intel/ironlake/raminit_heci.c | 223 ------------------------ src/southbridge/intel/ibexpeak/Makefile.inc | 1 + src/southbridge/intel/ibexpeak/me.h | 2 + src/southbridge/intel/ibexpeak/setup_heci_uma.c | 223 ++++++++++++++++++++++++ 6 files changed, 226 insertions(+), 226 deletions(-) delete mode 100644 src/northbridge/intel/ironlake/raminit_heci.c create mode 100644 src/southbridge/intel/ibexpeak/setup_heci_uma.c (limited to 'src') diff --git a/src/northbridge/intel/ironlake/Makefile.inc b/src/northbridge/intel/ironlake/Makefile.inc index 126b6eb5f5..afca10c589 100644 --- a/src/northbridge/intel/ironlake/Makefile.inc +++ b/src/northbridge/intel/ironlake/Makefile.inc @@ -11,7 +11,6 @@ ramstage-y += gma.c romstage-y += memmap.c romstage-y += raminit.c -romstage-y += raminit_heci.c romstage-y += raminit_tables.c romstage-y += early_init.c romstage-y += romstage.c diff --git a/src/northbridge/intel/ironlake/raminit.h b/src/northbridge/intel/ironlake/raminit.h index 6dd07b3f24..edfce51125 100644 --- a/src/northbridge/intel/ironlake/raminit.h +++ b/src/northbridge/intel/ironlake/raminit.h @@ -106,6 +106,4 @@ u16 get_max_timing(struct raminfo *info, int channel); void early_quickpath_init(struct raminfo *info, const u8 x2ca8); void late_quickpath_init(struct raminfo *info, const int s3resume); -void setup_heci_uma(u64 heci_uma_addr, unsigned int heci_uma_size); - #endif /* RAMINIT_H */ diff --git a/src/northbridge/intel/ironlake/raminit_heci.c b/src/northbridge/intel/ironlake/raminit_heci.c deleted file mode 100644 index e54b05867c..0000000000 --- a/src/northbridge/intel/ironlake/raminit_heci.c +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -#define HECIDEV PCI_DEV(0, 0x16, 0) - -/* FIXME: add timeout. */ -static void wait_heci_ready(void) -{ - while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)) // = 0x8000000c - ; - - write32((DEFAULT_HECIBAR + 0x4), (read32(DEFAULT_HECIBAR + 0x4) & ~0x10) | 0xc); -} - -/* FIXME: add timeout. */ -static void wait_heci_cb_avail(int len) -{ - union { - struct mei_csr csr; - u32 raw; - } csr; - - while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)) - ; - - do { - csr.raw = read32(DEFAULT_HECIBAR + 0x4); - } while (len > csr.csr.buffer_depth - (csr.csr.buffer_write_ptr - - csr.csr.buffer_read_ptr)); -} - -static void send_heci_packet(struct mei_header *head, u32 *payload) -{ - int len = (head->length + 3) / 4; - int i; - - wait_heci_cb_avail(len + 1); - - /* FIXME: handle leftovers correctly. */ - write32(DEFAULT_HECIBAR + 0, *(u32 *) head); - for (i = 0; i < len - 1; i++) - write32(DEFAULT_HECIBAR + 0, payload[i]); - - write32(DEFAULT_HECIBAR + 0, payload[i] & ((1 << (8 * len)) - 1)); - write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 0x4); -} - -static void send_heci_message(u8 *msg, int len, u8 hostaddress, u8 clientaddress) -{ - struct mei_header head; - int maxlen; - - wait_heci_ready(); - maxlen = (read32(DEFAULT_HECIBAR + 0x4) >> 24) * 4 - 4; - - while (len) { - int cur = len; - if (cur > maxlen) { - cur = maxlen; - head.is_complete = 0; - } else - head.is_complete = 1; - head.length = cur; - head.reserved = 0; - head.client_address = clientaddress; - head.host_address = hostaddress; - send_heci_packet(&head, (u32 *) msg); - len -= cur; - msg += cur; - } -} - -/* FIXME: Add timeout. */ -static int recv_heci_packet(struct mei_header *head, u32 *packet, u32 *packet_size) -{ - union { - struct mei_csr csr; - u32 raw; - } csr; - int i = 0; - - write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 2); - do { - csr.raw = read32(DEFAULT_HECIBAR + 0xc); - } while (csr.csr.buffer_write_ptr == csr.csr.buffer_read_ptr); - - *(u32 *) head = read32(DEFAULT_HECIBAR + 0x8); - if (!head->length) { - write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 2); - *packet_size = 0; - return 0; - } - if (head->length + 4 > 4 * csr.csr.buffer_depth || head->length > *packet_size) { - *packet_size = 0; - return -1; - } - - do { - csr.raw = read32(DEFAULT_HECIBAR + 0xc); - } while (((head->length + 3) >> 2) > - (csr.csr.buffer_write_ptr - csr.csr.buffer_read_ptr)); - - for (i = 0; i < (head->length + 3) >> 2; i++) - packet[i++] = read32(DEFAULT_HECIBAR + 0x8); - *packet_size = head->length; - if (!csr.csr.ready) - *packet_size = 0; - write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 4); - return 0; -} - -union uma_reply { - struct { - u8 group_id; - u8 command; - u8 reserved; - u8 result; - u8 field2; - u8 unk3[0x48 - 4 - 1]; - }; - u32 dwords[0x48 / sizeof(u32)]; -} __packed; - -/* FIXME: Add timeout. */ -static int recv_heci_message(union uma_reply *message, u32 *message_size) -{ - struct mei_header head; - int current_position; - - current_position = 0; - while (1) { - u32 current_size; - current_size = *message_size - current_position; - if (recv_heci_packet - (&head, &message->dwords[current_position / sizeof(u32)], - ¤t_size) == -1) - break; - if (!current_size) - break; - current_position += current_size; - if (head.is_complete) { - *message_size = current_position; - return 0; - } - - if (current_position >= *message_size) - break; - } - *message_size = 0; - return -1; -} - -static void send_heci_uma_message(const u64 heci_uma_addr, const unsigned int heci_uma_size) -{ - union uma_reply reply; - - struct uma_message { - u8 group_id; - u8 cmd; - u8 reserved; - u8 result; - u32 c2; - u64 heci_uma_addr; - u32 heci_uma_size; - u16 c3; - } __packed msg = { - .group_id = 0, - .cmd = MKHI_SET_UMA, - .reserved = 0, - .result = 0, - .c2 = 0x82, - .heci_uma_addr = heci_uma_addr, - .heci_uma_size = heci_uma_size, - .c3 = 0, - }; - u32 reply_size; - - send_heci_message((u8 *) &msg, sizeof(msg), 0, 7); - - reply_size = sizeof(reply); - if (recv_heci_message(&reply, &reply_size) == -1) - return; - - if (reply.command != (MKHI_SET_UMA | (1 << 7))) - die("HECI init failed\n"); -} - -void setup_heci_uma(u64 heci_uma_addr, unsigned int heci_uma_size) -{ - if (!heci_uma_size && !(pci_read_config32(HECIDEV, 0x40) & 0x20)) - return; - - if (heci_uma_size) { - dmibar_clrbits32(DMIVC0RCTL, 1 << 7); - RCBA32(0x14) &= ~0x80; - dmibar_clrbits32(DMIVC1RCTL, 1 << 7); - RCBA32(0x20) &= ~0x80; - dmibar_clrbits32(DMIVCPRCTL, 1 << 7); - RCBA32(0x30) &= ~0x80; - dmibar_clrbits32(DMIVCMRCTL, 1 << 7); - RCBA32(0x40) &= ~0x80; - - RCBA32(0x40) = 0x87000080; // OK - dmibar_write32(DMIVCMRCTL, 0x87000080); // OK - - while ((RCBA16(0x46) & 2) && dmibar_read16(DMIVCMRSTS) & VCMNP) - ; - } - - mchbar_write32(0x24, 0x10000 + heci_uma_size); - - send_heci_uma_message(heci_uma_addr, heci_uma_size); - - pci_write_config32(HECIDEV, 0x10, 0x0); - pci_write_config8(HECIDEV, 0x4, 0x0); -} diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc index c8c96a8dfa..b33252fea4 100644 --- a/src/southbridge/intel/ibexpeak/Makefile.inc +++ b/src/southbridge/intel/ibexpeak/Makefile.inc @@ -33,6 +33,7 @@ romstage-y += early_thermal.c romstage-y += ../bd82x6x/early_rcba.c romstage-y += early_cir.c romstage-y += early_usb.c +romstage-y += setup_heci_uma.c CPPFLAGS_common += -I$(src)/southbridge/intel/ibexpeak/include diff --git a/src/southbridge/intel/ibexpeak/me.h b/src/southbridge/intel/ibexpeak/me.h index 4eea0af2d5..8ff5ca7fa4 100644 --- a/src/southbridge/intel/ibexpeak/me.h +++ b/src/southbridge/intel/ibexpeak/me.h @@ -231,6 +231,8 @@ int intel_early_me_init(void); int intel_early_me_uma_size(void); int intel_early_me_init_done(u8 status); +void setup_heci_uma(u64 heci_uma_addr, unsigned int heci_uma_size); + typedef struct { u32 major_version : 16; u32 minor_version : 16; diff --git a/src/southbridge/intel/ibexpeak/setup_heci_uma.c b/src/southbridge/intel/ibexpeak/setup_heci_uma.c new file mode 100644 index 0000000000..70219e1adb --- /dev/null +++ b/src/southbridge/intel/ibexpeak/setup_heci_uma.c @@ -0,0 +1,223 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#define HECIDEV PCI_DEV(0, 0x16, 0) + +/* FIXME: add timeout. */ +static void wait_heci_ready(void) +{ + while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)) // = 0x8000000c + ; + + write32((DEFAULT_HECIBAR + 0x4), (read32(DEFAULT_HECIBAR + 0x4) & ~0x10) | 0xc); +} + +/* FIXME: add timeout. */ +static void wait_heci_cb_avail(int len) +{ + union { + struct mei_csr csr; + u32 raw; + } csr; + + while (!(read32(DEFAULT_HECIBAR + 0xc) & 8)) + ; + + do { + csr.raw = read32(DEFAULT_HECIBAR + 0x4); + } while (len > csr.csr.buffer_depth - (csr.csr.buffer_write_ptr - + csr.csr.buffer_read_ptr)); +} + +static void send_heci_packet(struct mei_header *head, u32 *payload) +{ + int len = (head->length + 3) / 4; + int i; + + wait_heci_cb_avail(len + 1); + + /* FIXME: handle leftovers correctly. */ + write32(DEFAULT_HECIBAR + 0, *(u32 *) head); + for (i = 0; i < len - 1; i++) + write32(DEFAULT_HECIBAR + 0, payload[i]); + + write32(DEFAULT_HECIBAR + 0, payload[i] & ((1 << (8 * len)) - 1)); + write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 0x4); +} + +static void send_heci_message(u8 *msg, int len, u8 hostaddress, u8 clientaddress) +{ + struct mei_header head; + int maxlen; + + wait_heci_ready(); + maxlen = (read32(DEFAULT_HECIBAR + 0x4) >> 24) * 4 - 4; + + while (len) { + int cur = len; + if (cur > maxlen) { + cur = maxlen; + head.is_complete = 0; + } else + head.is_complete = 1; + head.length = cur; + head.reserved = 0; + head.client_address = clientaddress; + head.host_address = hostaddress; + send_heci_packet(&head, (u32 *) msg); + len -= cur; + msg += cur; + } +} + +/* FIXME: Add timeout. */ +static int recv_heci_packet(struct mei_header *head, u32 *packet, u32 *packet_size) +{ + union { + struct mei_csr csr; + u32 raw; + } csr; + int i = 0; + + write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 2); + do { + csr.raw = read32(DEFAULT_HECIBAR + 0xc); + } while (csr.csr.buffer_write_ptr == csr.csr.buffer_read_ptr); + + *(u32 *) head = read32(DEFAULT_HECIBAR + 0x8); + if (!head->length) { + write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 2); + *packet_size = 0; + return 0; + } + if (head->length + 4 > 4 * csr.csr.buffer_depth || head->length > *packet_size) { + *packet_size = 0; + return -1; + } + + do { + csr.raw = read32(DEFAULT_HECIBAR + 0xc); + } while (((head->length + 3) >> 2) > + (csr.csr.buffer_write_ptr - csr.csr.buffer_read_ptr)); + + for (i = 0; i < (head->length + 3) >> 2; i++) + packet[i++] = read32(DEFAULT_HECIBAR + 0x8); + *packet_size = head->length; + if (!csr.csr.ready) + *packet_size = 0; + write32(DEFAULT_HECIBAR + 0x4, read32(DEFAULT_HECIBAR + 0x4) | 4); + return 0; +} + +union uma_reply { + struct { + u8 group_id; + u8 command; + u8 reserved; + u8 result; + u8 field2; + u8 unk3[0x48 - 4 - 1]; + }; + u32 dwords[0x48 / sizeof(u32)]; +} __packed; + +/* FIXME: Add timeout. */ +static int recv_heci_message(union uma_reply *message, u32 *message_size) +{ + struct mei_header head; + int current_position; + + current_position = 0; + while (1) { + u32 current_size; + current_size = *message_size - current_position; + if (recv_heci_packet + (&head, &message->dwords[current_position / sizeof(u32)], + ¤t_size) == -1) + break; + if (!current_size) + break; + current_position += current_size; + if (head.is_complete) { + *message_size = current_position; + return 0; + } + + if (current_position >= *message_size) + break; + } + *message_size = 0; + return -1; +} + +static void send_heci_uma_message(const u64 heci_uma_addr, const unsigned int heci_uma_size) +{ + union uma_reply reply; + + struct uma_message { + u8 group_id; + u8 cmd; + u8 reserved; + u8 result; + u32 c2; + u64 heci_uma_addr; + u32 heci_uma_size; + u16 c3; + } __packed msg = { + .group_id = 0, + .cmd = MKHI_SET_UMA, + .reserved = 0, + .result = 0, + .c2 = 0x82, + .heci_uma_addr = heci_uma_addr, + .heci_uma_size = heci_uma_size, + .c3 = 0, + }; + u32 reply_size; + + send_heci_message((u8 *) &msg, sizeof(msg), 0, 7); + + reply_size = sizeof(reply); + if (recv_heci_message(&reply, &reply_size) == -1) + return; + + if (reply.command != (MKHI_SET_UMA | (1 << 7))) + die("HECI init failed\n"); +} + +void setup_heci_uma(u64 heci_uma_addr, unsigned int heci_uma_size) +{ + if (!heci_uma_size && !(pci_read_config32(HECIDEV, 0x40) & 0x20)) + return; + + if (heci_uma_size) { + dmibar_clrbits32(DMIVC0RCTL, 1 << 7); + RCBA32(0x14) &= ~0x80; + dmibar_clrbits32(DMIVC1RCTL, 1 << 7); + RCBA32(0x20) &= ~0x80; + dmibar_clrbits32(DMIVCPRCTL, 1 << 7); + RCBA32(0x30) &= ~0x80; + dmibar_clrbits32(DMIVCMRCTL, 1 << 7); + RCBA32(0x40) &= ~0x80; + + RCBA32(0x40) = 0x87000080; // OK + dmibar_write32(DMIVCMRCTL, 0x87000080); // OK + + while ((RCBA16(0x46) & 2) && dmibar_read16(DMIVCMRSTS) & VCMNP) + ; + } + + mchbar_write32(0x24, 0x10000 + heci_uma_size); + + send_heci_uma_message(heci_uma_addr, heci_uma_size); + + pci_write_config32(HECIDEV, 0x10, 0x0); + pci_write_config8(HECIDEV, 0x4, 0x0); +} -- cgit v1.2.3