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

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I11ce1812a5a0aa2da6b414555374460d606e220e </div>
<div style="display:none"> Gerrit-Change-Number: 22395 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Subrata Banik <subrata.banik@intel.com> </div>