@@ -42,6 +42,16 @@ static struct lock flash_lock;
static struct flash *nvram_flash;
static u32 nvram_offset, nvram_size;
+bool flash_reserve(void)
+{
+ return try_lock(&flash_lock);
+}
+
+void flash_release(void)
+{
+ unlock(&flash_lock);
+}
+
static int flash_nvram_info(uint32_t *total_size)
{
int rc = OPAL_HARDWARE;
@@ -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,33 @@ int ipmi_elog_commit(struct errorlog *elog_buf)
return 0;
}
+#define ACCESS_DENIED 0x00
+#define ACCESS_GRANTED 0x01
+
+static void sel_pnor(uint8_t access)
+{
+ struct ipmi_msg *msg;
+ uint8_t granted = ACCESS_GRANTED;
+
+ switch (access) {
+ case REQUEST_PNOR:
+ prlog(PR_NOTICE, "IPMI: PNOR access requested\n");
+ granted = flash_reserve();
+
+ /* Ack the request */
+ msg = ipmi_mkmsg_simple(IPMI_PNOR_ACCESS_STATUS, &granted, 1);
+ ipmi_queue_msg(msg);
+ break;
+ case RELEASE_PNOR:
+ prlog(PR_NOTICE, "IPMI: PNOR access released\n");
+ flash_release();
+ break;
+ default:
+ prlog(PR_ERR, "IPMI: invalid PNOR access requested: %02x\n",
+ access);
+ }
+}
+
static void sel_power(uint8_t power)
{
switch (power) {
@@ -271,9 +301,11 @@ void ipmi_parse_sel(struct ipmi_msg *msg)
sel_occ_reset(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",
- sel.cmd);
+ prlog(PR_WARNING,
+ "IPMI: unknown OEM SEL command %02x received\n",
+ sel.cmd);
}
}
@@ -91,7 +91,6 @@
#define IPMI_NETFN_CHASSIS 0x00
#define IPMI_NETFN_STORAGE 0x0a
#define IPMI_NETFN_APP 0x06
-#define IPMI_NETFN_OEM 0x32
#define IPMI_WRITE_FRU IPMI_CODE(IPMI_NETFN_STORAGE, 0x12)
#define IPMI_GET_SEL_INFO IPMI_CODE(IPMI_NETFN_STORAGE, 0x40)
@@ -110,7 +109,9 @@
#define IPMI_GET_MESSAGE IPMI_CODE(IPMI_NETFN_APP, 0x33)
#define IPMI_READ_EVENT IPMI_CODE(IPMI_NETFN_APP, 0x35)
-#define IPMI_PARTIAL_ADD_ESEL IPMI_CODE(IPMI_NETFN_OEM, 0xf0)
+/* AMI OEM comamnds. AMI uses NETFN 0x3a and 0x32 */
+#define IPMI_PARTIAL_ADD_ESEL IPMI_CODE(0x32, 0xf0)
+#define IPMI_PNOR_ACCESS_STATUS IPMI_CODE(0x3a, 0x07)
/*
* IPMI response codes.
@@ -201,6 +201,9 @@ struct flash_chip;
extern int flash_register(struct flash_chip *chip, bool is_system_flash);
extern bool flash_load_resource(enum resource_id id, uint32_t subid,
void *buf, size_t *len);
+extern bool flash_reserve(void);
+extern void flash_release(void);
+
/* NVRAM support */
extern void nvram_init(void);