Cr50: Remove CONFIG_HOSTCMD_SPS support

This config option allowed us to disable the TPM protocol on the
SPI slave bus and replace it with our EC-style host command
protocol. We only used this for early testing and don't need it
anymore, so we can get rid of it completely for this SoC.

BUG=none
BRANCH=none
TEST=make buildall; test on cr50

Change-Id: I2126537e8bcc78e583cf426a3a83962c9ff1a121
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/334762
Reviewed-by: Scott Collyer <scollyer@chromium.org>
This commit is contained in:
Bill Richardson
2016-03-21 18:09:35 -07:00
parent cb38156bbc
commit fabb15c706
3 changed files with 1 additions and 311 deletions

View File

@@ -6,7 +6,7 @@
#ifndef __CROS_EC_BOARD_H
#define __CROS_EC_BOARD_H
/* Features that we don't want just yet */
/* Features that we don't want */
#undef CONFIG_CMD_LID_ANGLE
#undef CONFIG_CMD_POWERINDEBUG
#undef CONFIG_DMA_DEFAULT_HANDLERS
@@ -31,7 +31,6 @@
/* Enable SPI Slave (SPS) module */
#define CONFIG_SPS
#define CONFIG_HOSTCMD_SPS
#define CONFIG_TPM_SPS
/* We don't need to send events to the AP */

View File

@@ -40,7 +40,6 @@ chip-$(CONFIG_SPI_MASTER)+=spi_master.o
chip-y+= pmu.o
chip-y+= trng.o
chip-$(CONFIG_SPS)+= sps.o
chip-$(CONFIG_HOSTCMD_SPS)+=sps_hc.o
chip-$(CONFIG_TPM_SPS)+=sps_tpm.o
chip-$(CONFIG_WATCHDOG)+=watchdog.o

View File

@@ -1,308 +0,0 @@
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "common.h"
#include "console.h"
#include "hooks.h"
#include "host_command.h"
#include "sps.h"
#include "util.h"
/*
* This implements EC host commands over the SPI bus, using the Cr50 SPS (SPI
* slave) controller.
*
* Host commands are communicated using software flow-control, because most of
* the embedded controllers either aren't fast enough or don't have any support
* for hardware flow-control.
*
* Every SPI transaction is bi-directional, so when the AP sends commands to
* the EC, a default "dummy" byte is returned at the same time. The EC
* preconfigures that default response byte to indicate its status (ready,
* busy, waiting for more input, etc). Once the AP has sent a complete command
* message, it continues clocking bytes to the EC (which the EC ignores) and
* just looks at the response byte that comes back. Once the EC has parsed the
* command and is ready to reply, it sends a "start of frame" byte, followed by
* the actual response. The AP continues to read and ignore bytes from the EC
* until it sees the start of frame byte, and then it knows that the EC's
* response is starting with the next byte. Refer to include/ec_commands.h for
* more details.
*/
/* Console output macros */
#define CPUTS(outstr) cputs(CC_HOSTCMD, outstr)
#define CPRINTS(format, args...) cprints(CC_HOSTCMD, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_HOSTCMD, format, ## args)
/*
* Incoming messages are collected here until they're ready to process. The
* buffer will start with a struct ec_host_request, followed by whatever data
* is sent by the master.
*/
#define RXBUF_MAX 512 /* chosen arbitrarily */
static uint8_t rxbuf[RXBUF_MAX];
static unsigned int rxbuf_count; /* num bytes received */
static unsigned int rxbuf_needed; /* num bytes we'd like */
/*
* Outgoing messages are shoved in here. We need a preamble byte to mark the
* start of the data stream before the data itself.
*/
#define TXBUF_MAX 512 /* chosen arbitrarily */
static uint8_t txbuf[1 + TXBUF_MAX];
static enum spi_state {
/* SPI not enabled (initial state, and when chipset is off) */
SPI_STATE_DISABLED = 0,
/* Ready to receive next request */
SPI_STATE_READY_TO_RX,
/* Receiving request */
SPI_STATE_RECEIVING_HEADER,
SPI_STATE_RECEIVING_BODY,
/* Processing request */
SPI_STATE_PROCESSING,
/* Sending response */
SPI_STATE_SENDING,
/*
* Received bad data - transaction started before we were ready, or
* packet header from the master didn't parse properly. Ignoring
* received data.
*/
SPI_STATE_RX_BAD,
} state;
/* If the chip select is disabled, don't transmit response */
static int discard_response;
/* Callback to send our response to the master */
static void cb_send_response_packet(struct host_packet *pkt)
{
uint8_t *bufptr;
size_t data_size = pkt->response_size;
/* Chip Select was deasserted before we got here */
if (discard_response) {
discard_response = 0;
state = SPI_STATE_READY_TO_RX;
sps_tx_status(EC_SPI_RX_READY);
return;
}
/*
* The pkt->response will start at txbuf[1], which means that
* pkt->response_size doesn't include the preamble byte. We need to
* initialize it and start sending from there.
*/
txbuf[0] = EC_SPI_FRAME_START;
data_size++;
bufptr = txbuf;
state = SPI_STATE_SENDING;
/* There's probably still a race condition somewhere... */
while (data_size && state == SPI_STATE_SENDING) {
size_t cnt = sps_transmit(bufptr, data_size);
data_size -= cnt;
bufptr += cnt;
}
/* Clock out the end-of-packet marker when we're done. */
sps_tx_status(EC_SPI_PAST_END);
}
static int req_header_looks_good(const struct ec_host_request *req)
{
return (req->struct_version == EC_HOST_REQUEST_VERSION) &&
(req->reserved == 0) &&
(sizeof(*req) + req->data_len <= RXBUF_MAX);
}
/* RX FIFO handler (runs in interrupt context) */
static void hc_rx_handler(uint8_t *data, size_t data_size, int cs_disabled)
{
struct ec_host_request *req = (struct ec_host_request *)rxbuf;
static struct host_packet rx_packet;
size_t i;
if (cs_disabled) {
if (state == SPI_STATE_PROCESSING) {
/*
* A task is preparing a response, but the master has
* stopped caring. Set a flag so when the response is
* ready we'll just throw it away and reset everything.
*/
discard_response = 1;
return;
}
/* Otherwise, just go back to waiting for new input */
state = SPI_STATE_READY_TO_RX;
sps_tx_status(EC_SPI_RX_READY);
return;
}
/* No data == nothing to do */
if (!data_size)
return;
switch (state) {
case SPI_STATE_READY_TO_RX:
/* Starting a new RX transaction. */
rxbuf_count = 0;
state = SPI_STATE_RECEIVING_HEADER;
sps_tx_status(EC_SPI_RECEIVING);
/* Need a header first (proto v3 only) */
rxbuf_needed = sizeof(*req);
break;
case SPI_STATE_RECEIVING_HEADER:
case SPI_STATE_RECEIVING_BODY:
/* still gathering bytes */
break;
case SPI_STATE_DISABLED:
/*
* The master started a transaction but we weren't ready for it.
* Tell it we weren't ready, and ignore the incoming data until
* the master gives up.
*/
CPRINTS("SPI not ready (in state %d)", state);
sps_tx_status(EC_SPI_NOT_READY);
state = SPI_STATE_RX_BAD;
return;
default:
/* Anything else doesn't need us to look at the input */
return;
}
/* Collect incoming bytes */
if (rxbuf_count + data_size > RXBUF_MAX)
goto spi_event_error;
memcpy(rxbuf + rxbuf_count, data, data_size);
rxbuf_count += data_size;
/* Wait until we have enough */
if (rxbuf_count < rxbuf_needed)
return;
switch (state) {
case SPI_STATE_RECEIVING_HEADER:
/* Got the header - is it okay? */
if (!req_header_looks_good(req))
goto spi_event_error;
/* Yep, now need the body */
state = SPI_STATE_RECEIVING_BODY;
rxbuf_needed += req->data_len;
/* Still need more bytes? */
if (rxbuf_count < rxbuf_needed)
return;
/* FALLTHROUGH */
case SPI_STATE_RECEIVING_BODY:
/* We have all the data we need. */
state = SPI_STATE_PROCESSING;
sps_tx_status(EC_SPI_PROCESSING);
/* Hand it off to the host command task for processing */
rx_packet.send_response = cb_send_response_packet;
rx_packet.request = rxbuf;
rx_packet.request_temp = NULL;
rx_packet.request_max = RXBUF_MAX;
rx_packet.request_size = rxbuf_count;
rx_packet.response = txbuf + 1; /* skip preamble byte */
rx_packet.response_max = TXBUF_MAX;
rx_packet.response_size = 0;
rx_packet.driver_result = EC_RES_SUCCESS;
host_packet_receive(&rx_packet);
break;
default:
/* shouldn't get here */
goto spi_event_error;
}
return;
spi_event_error:
/* Error, timeout, or protocol we can't handle. Ignore data. */
sps_tx_status(EC_SPI_RX_BAD_DATA);
state = SPI_STATE_RX_BAD;
CPRINTS("SPI RX BAD DATA");
CPRINTF("[rxbuf (%d): ", rxbuf_count);
for (i = 0; i < rxbuf_count; i++)
CPRINTF("%02x ", rxbuf[i]);
CPRINTF("]\n");
}
static void sps_hc_enable(void)
{
/* I'm not listening, la la la la la ... */
sps_tx_status(EC_SPI_NOT_READY);
/* We are no longer actively processing a transaction */
state = SPI_STATE_DISABLED;
/* Ready to receive */
sps_register_rx_handler(SPS_GENERIC_MODE, hc_rx_handler, 0);
/* Here we go */
discard_response = 0;
state = SPI_STATE_READY_TO_RX;
sps_tx_status(EC_SPI_RX_READY);
}
static void sps_hc_disable(void)
{
sps_unregister_rx_handler();
/* We are no longer actively processing a transaction */
state = SPI_STATE_DISABLED;
}
static int sps_get_protocol_info(struct host_cmd_handler_args *args)
{
struct ec_response_get_protocol_info *r = args->response;
r->protocol_versions = (1 << 3);
r->max_request_packet_size = RXBUF_MAX;
r->max_response_packet_size = TXBUF_MAX;
r->flags = 0;
args->response_size = sizeof(*r);
return EC_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_GET_PROTOCOL_INFO,
sps_get_protocol_info,
EC_VER_MASK(0));
static int command_sps(int argc, char **argv)
{
if (argc > 1) {
if (0 != strcasecmp(argv[1], "off"))
return EC_ERROR_PARAM1;
sps_hc_disable();
ccprintf("SPS host commands disabled\n");
return EC_SUCCESS;
}
sps_hc_enable();
ccprintf("SPS host commands enabled\n");
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(spshc, command_sps,
"[off]",
"Enable (default) or disable SPS host commands",
NULL);