aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2018-04-23 12:13:59 +0530
committerStewart Smith <stewart@linux.ibm.com>2018-04-30 19:04:42 -0500
commit6739c890a2f298ed382b9557840a493fb97df44b (patch)
tree007c00d73f2c5aa1f75250dca25df1328956adf1 /include
parentd654f6c93bd6b2ea2db4cea68252073e6cd0fae6 (diff)
downloadskiboot-6739c890a2f298ed382b9557840a493fb97df44b.zip
skiboot-6739c890a2f298ed382b9557840a493fb97df44b.tar.gz
skiboot-6739c890a2f298ed382b9557840a493fb97df44b.tar.bz2
Add SBE driver support
SBE (Self Boot Engine) on P9 has two different jobs: - Boot the chip up to the point the core is functional - Provide various services like timer, scom, stash MPIPL, etc., at runtime OPAL can communicate to SBE via a set of data and control registers provided by the PSU block in P9 chip. - Four 8 byte registers for Host to send command packets to SBE - Four 8 byte registers for SBE to send response packets to Host - Two doorbell registers (1 on each side) to alert either party when data is placed in above mentioned data register Protocol constraints: Only one command is accepted in the command buffer until the response for the command is enqueued in the response buffer by SBE. Usage: We will use SBE for various purposes like timer, MPIPL, etc. This patch implements the SBE MBOX spec for OPAL to communicate with SBE. Design consideration: - Each chip has SBE. We need to track SBE messages per chip. Hence added per chip sbe structure and list of messages to that chip - SBE accepts only one command at a time. Hence serialized MBOX commands. - OPAL gets interrupted once SBE sets doorbell register - OPAL has to clear doorbell register after reading response - Every command class has timeout option. Timed out messages are discarded - SBE MBOX commands can be classified into four types : - Those that must be sent to the master only (ex: sending MDST/MDDT info) - Those that must be sent to slaves only (ex: continue MPIPL) - Those that must be sent to all chips (ex: close insecure window) - Those that can be sent to any chip (ex: timer) Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'include')
-rw-r--r--include/chip.h4
-rw-r--r--include/sbe-p9.h206
2 files changed, 207 insertions, 3 deletions
diff --git a/include/chip.h b/include/chip.h
index 43b5ea5..059033e 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -113,6 +113,7 @@ struct mfsi;
struct xive;
struct lpcm;
struct vas;
+struct p9_sbe;
/* Chip type */
enum proc_chip_type {
@@ -218,6 +219,9 @@ struct proc_chip {
/* location code of this chip */
const uint8_t *loc_code;
+
+ /* Used by hw/sbe-p9.c */
+ struct p9_sbe *sbe;
};
extern uint32_t pir_to_chip_id(uint32_t pir);
diff --git a/include/sbe-p9.h b/include/sbe-p9.h
index cca2100..329afff 100644
--- a/include/sbe-p9.h
+++ b/include/sbe-p9.h
@@ -1,4 +1,4 @@
-/* Copyright 2017 IBM Corp.
+/* Copyright 2017-2018 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,14 +21,214 @@
#include <ccan/list/list.h>
#include <ccan/short_types/short_types.h>
+/* Worst case command timeout value (90 sec) */
+#define SBE_CMD_TIMEOUT_MAX (90 * 1000)
+
+/* Primary response status code */
+#define SBE_STATUS_PRI_SUCCESS 0x00
+#define SBE_STATUS_PRI_INVALID_CMD 0x01
+#define SBE_STATUS_PRI_INVALID_DATA 0x02
+#define SBE_STATUS_PRI_SEQ_ERR 0x03
+#define SBE_STATUS_PRI_INTERNAL_ERR 0x04
+#define SBE_STATUS_PRI_UNSECURE_ACCESS 0x05
+#define SBE_STATUS_PRI_GENERIC_ERR 0xFE
+
+/* Secondary response status code */
+#define SBE_STATUS_SEC_SUCCESS 0x00
+#define SBE_STATUS_SEC_CMD_CLASS_UNSUPPORTED 0x01
+#define SBE_STATUS_SEC_CMD_UNSUPPORTED 0x02
+#define SBE_STATUS_SEC_INV_ADDR 0x03
+#define SBE_STATUS_SEC_INV_TARGET_TYPE 0x04
+#define SBE_STATUS_SEC_INV_CHIPLET_ID 0x05
+#define SBE_STATUS_SEC_TARGET_NOT_PRESENT 0x06
+#define SBE_STATUS_SEC_TARGET_NOT_FUNC 0x07
+#define SBE_STATUS_SEC_CMD_NOT_ALLOW 0x08
+#define SBE_STATUS_SEC_FUNC_NOT_SUPPORTED 0x09
+#define SBE_STATUS_SEC_GENERIC_ERR 0x0A
+#define SBE_STATUS_SEC_BLACKLIST_REG 0x0B
+#define SBE_STATUS_SEC_OS_FAILURE 0x0C
+#define SBE_STATUS_SEC_MBX_REG_FAILURE 0x0D
+#define SBE_STATUS_SEC_INSUFFICIENT_DATA 0x0E
+#define SBE_STATUS_SEC_EXCESS_DATA 0x0F
+#define SBE_STATUS_SEC_HW_TIMEOUT 0x10
+#define SBE_STATUS_SEC_PCBPIB_ERR 0x11
+#define SBE_STATUS_SEC_FIFO_PARITY_ERR 0x12
+#define SBE_STATUS_SEC_TIMER_EXPIRED 0x13
+#define SBE_STATUS_SEC_BLACKLISTED_MEM 0x14
+#define SBE_STATUS_SEC_UNSEC_REGION_NOT_FOUND 0x15
+#define SBE_STATUS_SEC_UNSEC_REGION_EXCEEDED 0x16
+#define SBE_STATUS_SEC_UNSEC_REGION_AMEND 0x17
+#define SBE_STATUS_SEC_INPUT_BUF_OVERFLOW 0x18
+#define SBE_STATUS_SEC_INVALID_PARAMS 0x19
+#define SBE_STATUS_SEC_BLACKLISTED_CMD 0x20
+
+/* Number of MBOX register on each side */
+#define NR_HOST_SBE_MBOX_REG 0x04
+
+/*
+ * SBE MBOX register address
+ * Reg 0 - 3 : Host to send command packets to SBE
+ * Reg 4 - 7 : SBE to send response packets to Host
+ */
+#define PSU_HOST_SBE_MBOX_REG0 0x000D0050
+#define PSU_HOST_SBE_MBOX_REG1 0x000D0051
+#define PSU_HOST_SBE_MBOX_REG2 0x000D0052
+#define PSU_HOST_SBE_MBOX_REG3 0x000D0053
+#define PSU_HOST_SBE_MBOX_REG4 0x000D0054
+#define PSU_HOST_SBE_MBOX_REG5 0x000D0055
+#define PSU_HOST_SBE_MBOX_REG6 0x000D0056
+#define PSU_HOST_SBE_MBOX_REG7 0x000D0057
+#define PSU_SBE_DOORBELL_REG_RW 0x000D0060
+#define PSU_SBE_DOORBELL_REG_AND 0x000D0061
+#define PSU_SBE_DOORBELL_REG_OR 0x000D0062
#define PSU_HOST_DOORBELL_REG_RW 0x000D0063
#define PSU_HOST_DOORBELL_REG_AND 0x000D0064
#define PSU_HOST_DOORBELL_REG_OR 0x000D0065
+/*
+ * Doorbell register to trigger SBE interrupt. Set by OPAL to inform
+ * the SBE about a waiting message in the Host/SBE mailbox registers
+ */
+#define HOST_SBE_MSG_WAITING PPC_BIT(0)
+
+/*
+ * Doorbell register for host bridge interrupt. Set by the SBE to inform
+ * host about a response message in the Host/SBE mailbox registers
+ */
+#define SBE_HOST_RESPONSE_WAITING PPC_BIT(0)
+#define SBE_HOST_MSG_READ PPC_BIT(1)
+#define SBE_HOST_STOP15_EXIT PPC_BIT(2)
+#define SBE_HOST_RESET PPC_BIT(3)
#define SBE_HOST_PASSTHROUGH PPC_BIT(4)
-#define SBE_HOST_RESPONSE_CLEAR 0x00
+#define SBE_HOST_TIMER_EXPIRY PPC_BIT(14)
+#define SBE_HOST_RESPONSE_MASK (PPC_BITMASK(0, 4) | SBE_HOST_TIMER_EXPIRY)
+
+/* SBE Target Type */
+#define SBE_TARGET_TYPE_PROC 0x00
+#define SBE_TARGET_TYPE_EX 0x01
+#define SBE_TARGET_TYPE_PERV 0x02
+#define SBE_TARGET_TYPE_MCS 0x03
+#define SBE_TARGET_TYPE_EQ 0x04
+#define SBE_TARGET_TYPE_CORE 0x05
+
+/* SBE MBOX command class */
+#define SBE_MCLASS_FIRST 0xD1
+#define SBE_MCLASS_CORE_STATE 0xD1
+#define SBE_MCLASS_SCOM 0xD2
+#define SBE_MCLASS_RING 0xD3
+#define SBE_MCLASS_TIMER 0xD4
+#define SBE_MCLASS_MPIPL 0xD5
+#define SBE_MCLASS_SECURITY 0xD6
+#define SBE_MCLASS_GENERIC 0xD7
+#define SBE_MCLASS_LAST 0xD7
+
+/*
+ * Commands are provided in xxyy form where:
+ * - xx : command class
+ * - yy : command
+ *
+ * Both request and response message uses same seq ID,
+ * command class and command.
+ */
+#define SBE_CMD_CTRL_DEADMAN_LOOP 0xD101
+#define SBE_CMD_MULTI_SCOM 0xD201
+#define SBE_CMD_PUT_RING_FORM_IMAGE 0xD301
+#define SBE_CMD_CONTROL_TIMER 0xD401
+#define SBE_CMD_GET_ARCHITECTED_REG 0xD501
+#define SBE_CMD_CLR_ARCHITECTED_REG 0xD502
+#define SBE_CMD_SET_UNSEC_MEM_WINDOW 0xD601
+#define SBE_CMD_GET_SBE_FFDC 0xD701
+#define SBE_CMD_GET_CAPABILITY 0xD702
+#define SBE_CMD_READ_SBE_SEEPROM 0xD703
+#define SBE_CMD_SET_FFDC_ADDR 0xD704
+#define SBE_CMD_QUIESCE_SBE 0xD705
+#define SBE_CMD_SET_FABRIC_ID_MAP 0xD706
+#define SBE_CMD_STASH_MPIPL_CONFIG 0xD707
+
+/* SBE MBOX control flags */
+
+/* Generic flags */
+#define SBE_CMD_CTRL_RESP_REQ 0x0100
+#define SBE_CMD_CTRL_ACK_REQ 0x0200
+
+/* Deadman loop */
+#define CTRL_DEADMAN_LOOP_START 0x0001
+#define CTRL_DEADMAN_LOOP_STOP 0x0002
+
+/* Control timer */
+#define CONTROL_TIMER_START 0x0001
+#define CONTROL_TIMER_STOP 0x0002
+
+/* SBE message state */
+enum p9_sbe_msg_state {
+ sbe_msg_unused = 0, /* Free */
+ sbe_msg_queued, /* Queued to SBE list */
+ sbe_msg_sent, /* Sent to SBE */
+ sbe_msg_wresp, /* Waiting for response */
+ sbe_msg_done, /* Complete */
+ sbe_msg_timeout, /* Message timeout */
+ sbe_msg_error, /* Failed to send message to SBE */
+};
+
+/* SBE message */
+struct p9_sbe_msg {
+ /*
+ * Reg[0] :
+ * word0 :
+ * direct cmd : reserved << 16 | ctrl flag
+ * indirect cmd: mem_addr_size_dword
+ * response : primary status << 16 | secondary status
+ *
+ * word1 : seq id << 16 | cmd class << 8 | cmd
+ *
+ * WARNING:
+ * - Don't populate reg[0].seq (byte 4,5). This will be populated by
+ * p9_sbe_queue_msg().
+ */
+ u64 reg[4];
+
+ /* cmd timout : mftb() + msecs_to_tb(SBE_CMD_TIMEOUT_MAX) */
+ u64 timeout;
+
+ /* Completion function */
+ void (*complete)(struct p9_sbe_msg *msg);
+ void *user_data;
+
+ /* Current msg state */
+ enum p9_sbe_msg_state state;
+
+ /* Set if the message expects a response */
+ bool response;
+
+ /* Response will be filled by driver when response received */
+ struct p9_sbe_msg *resp;
+
+ /* Internal queuing */
+ struct list_node link;
+} __packed;
+
+
+/* Allocate and populate p9_sbe_msg structure */
+extern struct p9_sbe_msg *p9_sbe_mkmsg(u16 cmd, u16 ctrl_flag, u64 reg1,
+ u64 reg2, u64 reg3) __warn_unused_result;
+
+/* Free p9_sbe_msg structure */
+extern void p9_sbe_freemsg(struct p9_sbe_msg *msg);
+
+/* Add new message to sbe queue */
+extern int p9_sbe_queue_msg(uint32_t chip_id, struct p9_sbe_msg *msg,
+ void (*comp)(struct p9_sbe_msg *msg)) __warn_unused_result;
+
+/* Synchronously send message to SBE */
+extern int p9_sbe_sync_msg(u32 chip_id, struct p9_sbe_msg *msg, bool autofree);
+
+/* Remove message from SBE queue, it will not remove inflight message */
+extern int p9_sbe_cancelmsg(u32 chip_id, struct p9_sbe_msg *msg);
+
+/* Initialize the SBE mailbox driver */
+extern void p9_sbe_init(void);
/* SBE interrupt */
-extern void sbe_interrupt(uint32_t chip_id);
+extern void p9_sbe_interrupt(uint32_t chip_id);
#endif /* __SBE_P9_H */