2 * This file is part of the coreboot project.
4 * Copyright 2017 Intel Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/early_variables.h>
17 #include <commonlib/helpers.h>
18 #include <console/console.h>
20 #include <device/pci.h>
21 #include <device/pci_ids.h>
22 #include <device/pci_ops.h>
23 #include <intelblocks/cse.h>
24 #include <soc/pci_devs.h>
28 /* default window for early boot, must be at least 12 bytes in size */
29 #define HECI1_BASE_ADDRESS 0xfed1a000
31 /* Wait up to 15 sec for HECI to get ready */
32 #define HECI_DELAY_READY (15 * 1000)
33 /* Wait up to 100 usec between circullar buffer polls */
34 #define HECI_DELAY 100
35 /* Wait up to 5 sec for CSE to chew something we sent */
36 #define HECI_SEND_TIMEOUT (5 * 1000)
37 /* Wait up to 5 sec for CSE to blurp a reply */
38 #define HECI_READ_TIMEOUT (5 * 1000)
40 #define SLOT_SIZE sizeof(uint32_t)
42 #define MMIO_CSE_CB_WW 0x00
43 #define MMIO_HOST_CSR 0x04
44 #define MMIO_CSE_CB_RW 0x08
45 #define MMIO_CSE_CSR 0x0c
47 #define CSR_IE (1 << 0)
48 #define CSR_IS (1 << 1)
49 #define CSR_IG (1 << 2)
50 #define CSR_READY (1 << 3)
51 #define CSR_RESET (1 << 4)
52 #define CSR_RP_START 8
53 #define CSR_RP (((1 << 8) - 1) << CSR_RP_START)
54 #define CSR_WP_START 16
55 #define CSR_WP (((1 << 8) - 1) << CSR_WP_START)
56 #define CSR_CBD_START 24
57 #define CSR_CBD (((1 << 8) - 1) << CSR_CBD_START)
59 #define MEI_HDR_IS_COMPLETE (1 << 31)
60 #define MEI_HDR_LENGTH_START 16
61 #define MEI_HDR_LENGTH_SIZE 9
62 #define MEI_HDR_LENGTH (((1 << MEI_HDR_LENGTH_SIZE) - 1) \
63 << MEI_HDR_LENGTH_START)
64 #define MEI_HDR_HOST_ADDR_START 8
65 #define MEI_HDR_HOST_ADDR (((1 << 8) - 1) << MEI_HDR_HOST_ADDR_START)
66 #define MEI_HDR_CSE_ADDR_START 0
67 #define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START)
75 * Initialize the device with provided temporary BAR. If BAR is 0 use a
76 * default. This is intended for pre-mem usage only where BARs haven't been
77 * assigned yet and devices are not enabled.
79 void heci_init(uintptr_t tempbar
)
81 struct cse_device
*cse
= car_get_var_ptr(&g_cse
);
82 device_t dev
= PCH_DEV_CSE
;
85 /* Assume it is already initialized, nothing else to do */
89 /* Use default pre-ram bar */
91 tempbar
= HECI1_BASE_ADDRESS
;
93 /* Assign Resources to HECI1 */
94 /* Clear BIT 1-2 of Command Register */
95 pcireg
= pci_read_config8(dev
, PCI_COMMAND
);
96 pcireg
&= ~(PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
97 pci_write_config8(dev
, PCI_COMMAND
, pcireg
);
99 /* Program Temporary BAR for HECI1 */
100 pci_write_config32(dev
, PCI_BASE_ADDRESS_0
, tempbar
);
101 pci_write_config32(dev
, PCI_BASE_ADDRESS_1
, 0x0);
103 /* Enable Bus Master and MMIO Space */
104 pcireg
= pci_read_config8(dev
, PCI_COMMAND
);
105 pcireg
|= PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
;
106 pci_write_config8(dev
, PCI_COMMAND
, pcireg
);
108 cse
->sec_bar
= tempbar
;
111 static uint32_t read_bar(uint32_t offset
)
113 struct cse_device
*cse
= car_get_var_ptr(&g_cse
);
114 return read32((void *)(cse
->sec_bar
+ offset
));
117 static void write_bar(uint32_t offset
, uint32_t val
)
119 struct cse_device
*cse
= car_get_var_ptr(&g_cse
);
120 return write32((void *)(cse
->sec_bar
+ offset
), val
);
123 static uint32_t read_cse_csr(void)
125 return read_bar(MMIO_CSE_CSR
);
128 static uint32_t read_host_csr(void)
130 return read_bar(MMIO_HOST_CSR
);
133 static void write_host_csr(uint32_t data
)
135 write_bar(MMIO_HOST_CSR
, data
);
138 static size_t filled_slots(uint32_t data
)
141 rp
= data
>> CSR_RP_START
;
142 wp
= data
>> CSR_WP_START
;
143 return (uint8_t) (wp
- rp
);
146 static size_t cse_filled_slots(void)
148 return filled_slots(read_cse_csr());
151 static size_t host_empty_slots(void)
154 csr
= read_host_csr();
156 return ((csr
& CSR_CBD
) >> CSR_CBD_START
) - filled_slots(csr
);
159 static void clear_int(void)
162 csr
= read_host_csr();
167 static uint32_t read_slot(void)
169 return read_bar(MMIO_CSE_CB_RW
);
172 static void write_slot(uint32_t val
)
174 write_bar(MMIO_CSE_CB_WW
, val
);
177 static int wait_write_slots(size_t cnt
)
181 stopwatch_init_msecs_expire(&sw
, HECI_SEND_TIMEOUT
);
182 while (host_empty_slots() < cnt
) {
184 if (stopwatch_expired(&sw
)) {
185 printk(BIOS_ERR
, "HECI: timeout, buffer not drained\n");
192 static int wait_read_slots(size_t cnt
)
196 stopwatch_init_msecs_expire(&sw
, HECI_READ_TIMEOUT
);
197 while (cse_filled_slots() < cnt
) {
199 if (stopwatch_expired(&sw
)) {
200 printk(BIOS_ERR
, "HECI: timed out reading answer!\n");
207 /* get number of full 4-byte slots */
208 static size_t bytes_to_slots(size_t bytes
)
210 return ALIGN_UP(bytes
, SLOT_SIZE
) / SLOT_SIZE
;
213 static int cse_ready(void)
216 csr
= read_cse_csr();
217 return csr
& CSR_READY
;
220 static int wait_heci_ready(void)
224 stopwatch_init_msecs_expire(&sw
, HECI_DELAY_READY
);
225 while (!cse_ready()) {
227 if (stopwatch_expired(&sw
))
234 static void host_gen_interrupt(void)
237 csr
= read_host_csr();
242 static size_t hdr_get_length(uint32_t hdr
)
244 return (hdr
& MEI_HDR_LENGTH
) >> MEI_HDR_LENGTH_START
;
248 send_one_message(uint32_t hdr
, const void *buff
)
250 size_t pend_len
, pend_slots
, remainder
, i
;
252 const uint32_t *p
= buff
;
254 /* Get space for the header */
255 if (!wait_write_slots(1))
258 /* First, write header */
261 pend_len
= hdr_get_length(hdr
);
262 pend_slots
= bytes_to_slots(pend_len
);
264 if (!wait_write_slots(pend_slots
))
267 /* Write the body in whole slots */
269 while (i
< ALIGN_DOWN(pend_len
, SLOT_SIZE
)) {
274 remainder
= pend_len
% SLOT_SIZE
;
275 /* Pad to 4 bytes not touching caller's buffer */
277 memcpy(&tmp
, p
, remainder
);
281 host_gen_interrupt();
283 /* Make sure nothing bad happened during transmission */
291 heci_send(const void *msg
, size_t len
, uint8_t host_addr
, uint8_t client_addr
)
294 size_t sent
= 0, remaining
, cb_size
, max_length
;
295 uint8_t *p
= (uint8_t *) msg
;
302 if (!wait_heci_ready()) {
303 printk(BIOS_ERR
, "HECI: not ready\n");
307 csr
= read_cse_csr();
308 cb_size
= ((csr
& CSR_CBD
) >> CSR_CBD_START
) * SLOT_SIZE
;
310 * Reserve one slot for the header. Limit max message length by 9
311 * bits that are available in the header.
313 max_length
= MIN(cb_size
, (1 << MEI_HDR_LENGTH_SIZE
) - 1) - SLOT_SIZE
;
317 * Fragment the message into smaller messages not exceeding useful
318 * circullar buffer length. Mark last message complete.
321 hdr
= MIN(max_length
, remaining
) << MEI_HDR_LENGTH_START
;
322 hdr
|= client_addr
<< MEI_HDR_CSE_ADDR_START
;
323 hdr
|= host_addr
<< MEI_HDR_HOST_ADDR_START
;
324 hdr
|= (MIN(max_length
, remaining
) == remaining
) ?
325 MEI_HDR_IS_COMPLETE
: 0;
326 sent
= send_one_message(hdr
, p
);
329 } while (remaining
> 0 && sent
!= 0);
331 return remaining
== 0;
335 recv_one_message(uint32_t *hdr
, void *buff
, size_t maxlen
)
337 uint32_t reg
, *p
= buff
;
338 size_t recv_slots
, recv_len
, remainder
, i
;
340 /* first get the header */
341 if (!wait_read_slots(1))
345 recv_len
= hdr_get_length(*hdr
);
348 printk(BIOS_WARNING
, "HECI: message is zero-sized\n");
350 recv_slots
= bytes_to_slots(recv_len
);
353 if (recv_len
> maxlen
) {
354 printk(BIOS_ERR
, "HECI: response is too big\n");
358 /* wait for the rest of messages to arrive */
359 wait_read_slots(recv_slots
);
361 /* fetch whole slots first */
362 while (i
< ALIGN_DOWN(recv_len
, SLOT_SIZE
)) {
367 remainder
= recv_len
% SLOT_SIZE
;
371 memcpy(p
, ®
, remainder
);
377 int heci_receive(void *buff
, size_t *maxlen
)
379 size_t left
, received
;
383 if (!buff
|| !maxlen
|| !*maxlen
)
390 if (!wait_heci_ready()) {
391 printk(BIOS_ERR
, "HECI: not ready\n");
396 * Receive multiple packets until we meet one marked complete or we run
397 * out of space in caller-provided buffer.
400 received
= recv_one_message(&hdr
, p
, left
);
403 /* If we read out everything ping to send more */
404 if (!(hdr
& MEI_HDR_IS_COMPLETE
) && !cse_filled_slots())
405 host_gen_interrupt();
406 } while (received
&& !(hdr
& MEI_HDR_IS_COMPLETE
) && left
> 0);
408 *maxlen
= p
- (uint8_t *) buff
;
410 /* If ME is not ready, something went wrong and we received junk */
414 return !!((hdr
& MEI_HDR_IS_COMPLETE
) && received
);
418 * Attempt to reset the device. This is useful when host and ME are out
419 * of sync during transmission or ME didn't understand the message.
425 /* Send reset request */
426 csr
= read_host_csr();
431 if (wait_heci_ready()) {
432 /* Device is back on its imaginary feet, clear reset */
433 csr
= read_host_csr();
441 printk(BIOS_CRIT
, "HECI: reset failed\n");
448 static void update_sec_bar(struct device
*dev
)
450 g_cse
.sec_bar
= find_resource(dev
, PCI_BASE_ADDRESS_0
)->base
;
453 static void cse_set_resources(struct device
*dev
)
455 if (dev
->path
.pci
.devfn
== PCH_DEVFN_CSE
)
458 pci_dev_set_resources(dev
);
461 static struct device_operations cse_ops
= {
462 .set_resources
= cse_set_resources
,
463 .read_resources
= pci_dev_read_resources
,
464 .enable_resources
= pci_dev_enable_resources
,
465 .init
= pci_dev_init
,
468 static const struct pci_driver cse_driver __pci_driver
= {
470 .vendor
= PCI_VENDOR_ID_INTEL
,
471 /* SoC/chipset needs to provide PCI device ID */
472 .device
= PCI_DEVICE_ID_INTEL_APL_CSE0
,