[coreboot-gerrit] Change in coreboot[master]: soc/intel/skylake: Make use of common CSE code for skylake
Subrata Banik (Code Review)
gerrit at coreboot.org
Thu Nov 9 10:39:13 CET 2017
Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/22395
Change subject: soc/intel/skylake: Make use of common CSE code for skylake
......................................................................
soc/intel/skylake: Make use of common CSE code for skylake
TEST=Ensures global reset could able to reset system.
Change-Id: I11ce1812a5a0aa2da6b414555374460d606e220e
Signed-off-by: Subrata Banik <subrata.banik at intel.com>
---
M src/soc/intel/skylake/Kconfig
M src/soc/intel/skylake/bootblock/pch.c
M src/soc/intel/skylake/me.c
3 files changed, 20 insertions(+), 319 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/95/22395/1
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index f830f54..c4957ae 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -54,6 +54,7 @@
select SOC_INTEL_COMMON_BLOCK
select SOC_INTEL_COMMON_BLOCK_CPU
select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT
+ select SOC_INTEL_COMMON_BLOCK_CSE
select SOC_INTEL_COMMON_BLOCK_EBDA
select SOC_INTEL_COMMON_BLOCK_FAST_SPI
select SOC_INTEL_COMMON_BLOCK_GPIO
diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c
index fdc88f5..34cfaa3 100644
--- a/src/soc/intel/skylake/bootblock/pch.c
+++ b/src/soc/intel/skylake/bootblock/pch.c
@@ -18,6 +18,7 @@
#include <chip.h>
#include <device/device.h>
#include <device/pci_def.h>
+#include <intelblocks/cse.h>
#include <intelblocks/fast_spi.h>
#include <intelblocks/itss.h>
#include <intelblocks/lpc_lib.h>
@@ -157,27 +158,6 @@
outw(tcocnt, tcobase + TCO1_CNT);
}
-static void enable_heci(void)
-{
- device_t dev = PCH_DEV_CSE;
- u8 pcireg;
-
- /* Assign Resources to HECI1 */
- /* Clear BIT 1-2 of Command Register */
- pcireg = pci_read_config8(dev, PCI_COMMAND);
- pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
- pci_write_config8(dev, PCI_COMMAND, pcireg);
-
- /* Program Temporary BAR for HECI1 */
- pci_write_config32(dev, PCI_BASE_ADDRESS_0, HECI1_BASE_ADDRESS);
- pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0x0);
-
- /* Enable Bus Master and MMIO Space */
- pcireg = pci_read_config8(dev, PCI_COMMAND);
- pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config8(dev, PCI_COMMAND, pcireg);
-}
-
void pch_early_iorange_init(void)
{
/* IO Decode Range */
@@ -216,5 +196,6 @@
enable_rtc_upper_bank();
- enable_heci();
+ /* initialize Heci interface */
+ heci_init(HECI1_BASE_ADDRESS);
}
diff --git a/src/soc/intel/skylake/me.c b/src/soc/intel/skylake/me.c
index f4df831..9a6d9b0 100644
--- a/src/soc/intel/skylake/me.c
+++ b/src/soc/intel/skylake/me.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2016 Intel Corporation.
+ * Copyright (C) 2016-2017 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,18 +15,19 @@
#include <arch/io.h>
#include <commonlib/helpers.h>
+#include <compiler.h>
#include <console/console.h>
+#include <delay.h>
#include <device/pci.h>
#include <device/pci_def.h>
#include <device/pci_ids.h>
+#include <intelblocks/cse.h>
+#include <soc/iomap.h>
+#include <soc/me.h>
+#include <soc/pci_devs.h>
#include <stdint.h>
-#include <compiler.h>
#include <stdlib.h>
#include <string.h>
-#include <soc/iomap.h>
-#include <soc/pci_devs.h>
-#include <soc/me.h>
-#include <delay.h>
#include <timer.h>
static inline u32 me_read_config32(int offset)
@@ -368,291 +369,6 @@
}
}
-/*
-* Aligning a byte length to length in dwords.
-*/
-static u32 get_dword_length(u32 byte_length)
-{
- return ALIGN_UP(byte_length, sizeof(uint32_t)) / sizeof(uint32_t);
-}
-
-/*
-* Get remaining message count in dword from circular buffer based on
-* write and read offset.
-*/
-static u32 get_cb_msg_count(u32 data)
-{
- u8 read_offset = data >> 8;
- u8 write_offset = data >> 16;
-
- return get_dword_length(write_offset - read_offset);
-}
-
-static int wait_heci_ready(void)
-{
- struct stopwatch sw;
- int timeout = 0;
- union me_csr csr;
-
- stopwatch_init_msecs_expire(&sw, HECI_TIMEOUT);
- while (1) {
- do {
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- if (csr.fields.host_ready)
- return 0;
- } while (!(timeout = stopwatch_expired(&sw)));
-
- printk(BIOS_ERR, "ME_RDY bit is not set after 15 sec");
- return -1;
- }
-}
-
-static int wait_heci_cb_avail(u32 len)
-{
- struct stopwatch sw;
- union host_csr csr;
-
- csr.data = me_read_mmio32(MMIO_HOST_CSR);
- /*
- * if timeout has happened, return failure as
- * the circular buffer is not empty
- */
- stopwatch_init_msecs_expire(&sw, HECI_SEND_TIMEOUT);
- /* Must have room for message and message header */
- while (len > (get_dword_length(csr.fields.me_cir_depth) -
- get_cb_msg_count(csr.data))) {
- if (stopwatch_expired(&sw)) {
- printk(BIOS_ERR,
- "Circular Buffer never emptied within 5 sec");
- return -1;
- }
- /* wait before trying again */
- udelay(HECI_DELAY);
- /* read HOST_CSR for next iteration */
- csr.data = me_read_mmio32(MMIO_HOST_CSR);
- }
- return 0;
-}
-
-static int send_heci_packet(union mei_header *head, u32 len, u32 *payload)
-{
- int sts;
- int index;
- union me_csr csr;
- union host_csr hcsr;
-
- /*
- * wait until there is sufficient room in CB
- */
- sts = wait_heci_cb_avail(len + 1);
- if (sts != 0)
- return -1;
-
- /* Write message header */
- me_write_mmio32(MMIO_ME_CB_WW, head->data);
-
- /* Write message body */
- for (index = 0; index < len; index++)
- me_write_mmio32(MMIO_ME_CB_WW, payload[index]);
-
- /* Set Interrupt Generate bit */
- hcsr.data = me_read_mmio32(MMIO_HOST_CSR);
- hcsr.fields.int_gen = 1;
- me_write_mmio32(MMIO_HOST_CSR, hcsr.data);
-
- /* Check if ME Ready bit is set, if set to 0 then return fatal error */
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- if (csr.fields.host_ready)
- return 0;
- else
- return -1;
-}
-
-static int recv_heci_packet(union mei_header *head, u32 *packet,
- u32 *packet_size)
-{
- union me_csr csr;
- union host_csr hcsr;
- int rec_msg = 0;
- struct stopwatch sw;
- u32 length, index;
-
- /* Clear Interrupt Status bit */
- hcsr.data = me_read_mmio32(MMIO_HOST_CSR);
- hcsr.fields.int_sts = 1;
- me_write_mmio32(MMIO_HOST_CSR, hcsr.data);
-
- /* Check if circular buffer overflow
- * if yes then return fatal error
- */
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- if (get_cb_msg_count(csr.data) >
- get_dword_length(csr.fields.me_cir_buff))
- return -1;
- /*
- * if timeout has happened, return failure as
- * the circular buffer is not empty
- */
- stopwatch_init_msecs_expire(&sw, HECI_READ_TIMEOUT);
- /* go until we got message pkt */
- do {
- if (stopwatch_expired(&sw)) {
- printk(BIOS_ERR,
- "Circular Buffer not filled within 5 sec");
- *packet_size = 0;
- return -1;
- }
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- /* Read one message from HECI buffer */
- if (get_cb_msg_count(csr.data) > 0) {
- head->data = me_read_mmio32(MMIO_ME_CB_RW);
- /* calculate the message length in dword */
- length = get_dword_length(head->fields.length);
- if (head->fields.length == 0) {
- *packet_size = 0;
- goto SET_IG;
- }
- /* Make sure, we have enough space to catch all */
- if (head->fields.length <= *packet_size) {
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- /* get complete message into circular buffer */
- while (length > get_cb_msg_count(csr.data)) {
- udelay(HECI_DELAY);
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- }
- /* here is the message */
- for (index = 0; index < length; index++)
- packet[index] =
- me_read_mmio32(MMIO_ME_CB_RW);
-
- rec_msg = 1;
- *packet_size = head->fields.length;
- } else {
- /* Too small buffer */
- *packet_size = 0;
- return -1;
- }
- }
- } while (!rec_msg);
-
- /*
- * Check if ME Ready bit is set, if set to 0 then return fatal error
- * because ME might have reset during transaction and we might have
- * read a junk data from CB
- */
- csr.data = me_read_mmio32(MMIO_ME_CSR);
- if (!(csr.fields.host_ready))
- return -1;
-SET_IG:
- /* Set Interrupt Generate bit */
- hcsr.data = me_read_mmio32(MMIO_HOST_CSR);
- hcsr.fields.int_gen = 1;
- me_write_mmio32(MMIO_HOST_CSR, hcsr.data);
- return 0;
-}
-
-static int
-send_heci_message(void *msg, int len, u8 hostaddress, u8 clientaddress)
-{
- u8 retry;
- int status = -1;
- u32 cir_buff_depth;
- union host_csr csr;
- union mei_header head;
- int cur = 0;
- u32 slength, rlength;
-
- for (retry = 0; retry < MAX_HECI_MESSAGE; retry++) {
- if (wait_heci_ready() != 0)
- continue;
- /* HECI is ready */
- csr.data = me_read_mmio32(MMIO_HOST_CSR);
- cir_buff_depth = csr.fields.me_cir_depth;
- head.fields.client_address = clientaddress;
- head.fields.host_address = hostaddress;
- while (len > cur) {
- rlength = get_dword_length(len - cur);
- /*
- * Set the message complete bit if this is last packet
- * in message needs to be "less than" to account for
- * the header OR needs to be exact equal to CB depth
- */
- if (rlength <= cir_buff_depth)
- head.fields.is_complete = 1;
- else
- head.fields.is_complete = 0;
- /*
- * calculate length for message header
- * header length = smaller of CB buffer or
- * remaining message
- */
- slength = ((cir_buff_depth <= rlength)
- ? ((cir_buff_depth - 1) * 4)
- : (len - cur));
- head.fields.length = slength;
- head.fields.reserved = 0;
- /*
- * send the current packet
- * (cur should be treated as index for message)
- */
- status = send_heci_packet(&head,
- get_dword_length(head.fields.length), msg);
- if (status != 0)
- break;
- /* update the length information */
- cur += slength;
- msg += cur;
- }
- if (!status)
- break;
- }
- return status;
-}
-
-static int
-recv_heci_message(void *message, u32 *message_size)
-{
- union mei_header head;
- int cur = 0;
- u8 retry;
- int status = -1;
- int msg_complete = 0;
- u32 pkt_buff;
-
- for (retry = 0; retry < MAX_HECI_MESSAGE; retry++) {
- if (wait_heci_ready() != 0)
- continue;
- /* HECI is ready */
- while ((cur < *message_size) && (msg_complete == 0)) {
- pkt_buff = *message_size - cur;
- status = recv_heci_packet(&head, message + (cur >> 2),
- &pkt_buff);
- if (status == -1) {
- *message_size = 0;
- break;
- }
- msg_complete = head.fields.is_complete;
- if (pkt_buff == 0) {
- /* if not in middle of msg and msg complete bit
- * is set then this is a valid zero length msg
- */
- if ((cur == 0) && (msg_complete == 1))
- status = 0;
- else
- status = -1;
- *message_size = 0;
- break;
- }
- cur += pkt_buff;
- }
- if (!status) {
- *message_size = cur;
- break;
- }
- }
- return status;
-}
-
static int send_heci_reset_message(void)
{
int status;
@@ -672,20 +388,23 @@
} __packed;
struct reset_message msg = {
.cmd = MKHI_GLOBAL_RESET,
+ .group_id = 0,
+ .reserved = 0,
+ .result = 0,
.req_origin = GR_ORIGIN_BIOS_POST,
.reset_type = GLOBAL_RST_TYPE
};
- u32 reply_size;
+ size_t reply_size;
- status = send_heci_message(&msg, sizeof(msg),
- BIOS_HOST_ADD, HECI_MKHI_ADD);
- if (status != 0)
+ heci_reset();
+
+ status = heci_send(&msg, sizeof(msg), BIOS_HOST_ADD, HECI_MKHI_ADD);
+ if (status != 1)
return -1;
reply_size = sizeof(reply);
memset(&reply, 0, reply_size);
- if (recv_heci_message(&reply, &reply_size) == -1)
- return -1;
+ heci_receive(&reply, &reply_size);
/* get reply result from HECI MSG */
if (reply.result != 0) {
printk(BIOS_DEBUG, "%s: Exit with Failure\n", __func__);
--
To view, visit https://review.coreboot.org/22395
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I11ce1812a5a0aa2da6b414555374460d606e220e
Gerrit-Change-Number: 22395
Gerrit-PatchSet: 1
Gerrit-Owner: Subrata Banik <subrata.banik at intel.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171109/13b8925d/attachment-0001.html>
More information about the coreboot-gerrit
mailing list