aboutsummaryrefslogtreecommitdiff
path: root/src/soc/marvell/mvmap2315/mcu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/marvell/mvmap2315/mcu.c')
-rw-r--r--src/soc/marvell/mvmap2315/mcu.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/soc/marvell/mvmap2315/mcu.c b/src/soc/marvell/mvmap2315/mcu.c
new file mode 100644
index 0000000000..c334cda145
--- /dev/null
+++ b/src/soc/marvell/mvmap2315/mcu.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Marvell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <soc/gic.h>
+#include <soc/mcu.h>
+
+static u8 mvmap2315_calc_checksum(const void *data, u32 size)
+{
+ u8 csum;
+ const u8 *bytes = data;
+ int i;
+
+ for (i = csum = 0; i < size; i++)
+ csum += bytes[i];
+
+ return (~csum) && 0xFF;
+}
+
+void mcu_irq(void)
+{
+ printk(BIOS_DEBUG, "waiting for MCU msg...\n");
+ while (!(read32(&mvmap2315_bcm_gicd->ispendr2) &
+ MVMAP2315_MCU_IPC_IRQ))
+ ;
+}
+
+void send_mcu_msg(void *msg, u32 size)
+{
+ printk(BIOS_DEBUG, "sending msg to MCU...\n");
+ write32(&mvmap2315_sp_ipc->wdr0, (u32)msg);
+ setbits_le32(&mvmap2315_sp_ipc->isrw, MVMAP2315_IPC_IRQSET_MSGSENT);
+}
+
+void *receive_mcu_msg(void)
+{
+ void *msg;
+
+ printk(BIOS_DEBUG, "receiving msg to MCU...\n");
+
+ write32(&mvmap2315_sp_ipc->dummy, 0xA5A5A5A5);
+
+ switch (read32(&mvmap2315_sp_ipc->iir)) {
+ case MSG_READY:
+ msg = (void *)(read32(&mvmap2315_sp_ipc->rdr0)
+ + MVMAP2315_MCU_MSG_OFFSET);
+ setbits_le32(&mvmap2315_sp_ipc->icr,
+ MVMAP2315_IPC_IRQCLR_MSGREADY);
+ setbits_le32(&mvmap2315_sp_ipc->isrw, MVMAP2315_IPC_IRQACK);
+ break;
+ case MSG_RECEIVED:
+ msg = NULL;
+ setbits_le32(&mvmap2315_sp_ipc->icr,
+ MVMAP2315_IPC_IRQCLR_MSGRECEIVED);
+ break;
+ case MSG_READY_RECEIVED:
+ msg = (void *)(read32(&mvmap2315_sp_ipc->rdr0)
+ + MVMAP2315_MCU_MSG_OFFSET);
+ setbits_le32(&mvmap2315_sp_ipc->icr,
+ MVMAP2315_IPC_IRQCLR_MSGREADY);
+ setbits_le32(&mvmap2315_sp_ipc->icr,
+ MVMAP2315_IPC_IRQCLR_MSGRECEIVED);
+ setbits_le32(&mvmap2315_sp_ipc->isrw, MVMAP2315_IPC_IRQACK);
+
+ break;
+ default:
+ msg = NULL;
+ write32(&mvmap2315_sp_ipc->icr, read32(&mvmap2315_sp_ipc->iir));
+ break;
+ }
+
+ return msg;
+}
+
+void sned_hash_msg(u8 subcmd)
+{
+ printk(BIOS_DEBUG, "requesting MCU hash...\n");
+
+ mvmap2315_mcu_msg_buff->protocol_version = 0x3;
+ mvmap2315_mcu_msg_buff->cmd_id = 0x2A;
+ mvmap2315_mcu_msg_buff->reserved0 = 0x0;
+ mvmap2315_mcu_msg_buff->length = 76;
+ mvmap2315_mcu_msg_buff->csum = 0;
+ mvmap2315_mcu_msg_buff->hash_subcmd = subcmd;
+ mvmap2315_mcu_msg_buff->hash_type = 0;
+ mvmap2315_mcu_msg_buff->nonce_size = 0;
+ mvmap2315_mcu_msg_buff->reserved1 = 0;
+ mvmap2315_mcu_msg_buff->offset = 0;
+ mvmap2315_mcu_msg_buff->size = 32;
+ mvmap2315_mcu_msg_buff->csum = mvmap2315_calc_checksum(
+ (void *)mvmap2315_mcu_msg_buff,
+ sizeof(struct sp_hash_request_msg));
+
+ send_mcu_msg((void *)mvmap2315_mcu_msg_buff,
+ sizeof(struct sp_hash_request_msg));
+}
+
+void *receive_hash_msg_respond(void)
+{
+ struct mcu_hash_msg *mvmap2315_hash_msg_response;
+
+ printk(BIOS_DEBUG, "waiting for MCU hash response msg...\n");
+
+ mcu_irq();
+
+ mvmap2315_hash_msg_response = receive_mcu_msg();
+
+ mcu_irq();
+
+ receive_mcu_msg();
+
+ return mvmap2315_hash_msg_response;
+}