diff mbox

[5/5] ipmi: Disable nvram accesses when requested

Message ID 1422577911-18394-6-git-send-email-joel@jms.id.au
State Changes Requested
Headers show

Commit Message

Joel Stanley Jan. 30, 2015, 12:31 a.m. UTC
BMC based systems contain a PNOR to provide nvram storage. The host
normally has exclusive access to the PNOR, however the BMC may use IPMI
to request access to perform functions such as update the firmware.

Indicate to users of the opal_vmram_{read,write} functions that the
device is busy.

Signed-off-by: Joel Stanley <joel@jms.id.au>
---
 core/nvram.c       |  7 +++++++
 hw/ipmi/ipmi-sel.c | 22 ++++++++++++++++++++++
 include/skiboot.h  |  1 +
 3 files changed, 30 insertions(+)

Comments

Joel Stanley Jan. 30, 2015, 3:37 a.m. UTC | #1
Hi Stewart,

On Fri, Jan 30, 2015 at 11:01 AM, Joel Stanley <joel@jms.id.au> wrote:
> BMC based systems contain a PNOR to provide nvram storage. The host
> normally has exclusive access to the PNOR, however the BMC may use IPMI
> to request access to perform functions such as update the firmware.
>
> Indicate to users of the opal_vmram_{read,write} functions that the
> device is busy.

Please don't apply this one yet. I will send a replacement once we've
sorted out the IPMI reply (the TODO in the patch).

Thanks,

Joel
diff mbox

Patch

diff --git a/core/nvram.c b/core/nvram.c
index f25d6aa..bd69737 100644
--- a/core/nvram.c
+++ b/core/nvram.c
@@ -25,6 +25,13 @@  static void *nvram_image;
 static uint32_t nvram_size;
 static bool nvram_ready;
 
+/* If another device (eg. BMC) is touching the nvram, we can mark it as busy
+ * to stop access */
+void nvram_set_ready(bool state)
+{
+	nvram_ready = state;
+}
+
 static int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset)
 {
 	if (!nvram_ready)
diff --git a/hw/ipmi/ipmi-sel.c b/hw/ipmi/ipmi-sel.c
index 291f279..f25d004 100644
--- a/hw/ipmi/ipmi-sel.c
+++ b/hw/ipmi/ipmi-sel.c
@@ -41,6 +41,9 @@ 
 #define SOFT_OFF	        0x00
 #define SOFT_REBOOT	        0x01
 
+#define RELEASE_PNOR		0x00
+#define REQUEST_PNOR		0x01
+
 struct oem_sel {
 	/* SEL header */
 	uint8_t id[2];
@@ -180,6 +183,24 @@  int ipmi_elog_commit(struct errorlog *elog_buf)
 	return 0;
 }
 
+static void sel_pnor(uint8_t access)
+{
+	switch (access) {
+	case REQUEST_PNOR:
+		prlog(PR_NOTICE, "IPMI: PNOR access requested\n");
+		nvram_set_ready(false);
+		/* TODO: Ack the request */
+		break;
+	case RELEASE_PNOR:
+		prlog(PR_NOTICE, "IPMI: PNOR access released\n");
+		nvram_set_ready(true);
+		break;
+	default:
+		prlog(PR_ERR, "IPMI: invalid PNOR access requested: %02x\n",
+		      access);
+	}
+}
+
 static void sel_power(uint8_t power)
 {
 	switch (power) {
@@ -248,6 +269,7 @@  void ipmi_parse_sel(struct ipmi_msg *msg)
 		sel_power(sel.data[0]);
 		break;
 	case CMD_AMI_PNOR_ACCESS:
+		sel_pnor(sel.data[0]);
 		break;
 	default:
 		printf("IPMI: unknown OEM SEL command %02x received\n",
diff --git a/include/skiboot.h b/include/skiboot.h
index 1b55638..8a38758 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -199,6 +199,7 @@  extern void occ_fsp_init(void);
 /* NVRAM support */
 extern void nvram_init(void);
 extern void nvram_read_complete(bool success);
+extern void nvram_set_ready(bool state);
 
 /* NVRAM on flash helper */
 struct flash_chip;