From f727c7ce38cc58eaf24c55d440e885a1b24a26a1 Mon Sep 17 00:00:00 2001 From: Hakim Giydan Date: Thu, 8 Sep 2016 10:59:15 -0700 Subject: soc/marvell/mvmap2315: Add MCU driver Testing: booted successfully. Change-Id: I003f6929b00476d46be931773cd35418fe6622a6 Signed-off-by: Hakim Giydan Reviewed-on: https://review.coreboot.org/15529 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/marvell/mvmap2315/Makefile.inc | 1 + src/soc/marvell/mvmap2315/bootblock.c | 8 ++ src/soc/marvell/mvmap2315/include/soc/addressmap.h | 2 + src/soc/marvell/mvmap2315/include/soc/mcu.h | 118 +++++++++++++++++++ src/soc/marvell/mvmap2315/mcu.c | 130 +++++++++++++++++++++ src/soc/marvell/mvmap2315/pmic.c | 9 +- 6 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 src/soc/marvell/mvmap2315/include/soc/mcu.h create mode 100644 src/soc/marvell/mvmap2315/mcu.c (limited to 'src/soc/marvell') diff --git a/src/soc/marvell/mvmap2315/Makefile.inc b/src/soc/marvell/mvmap2315/Makefile.inc index a4a92d31fd..d30ab68e95 100644 --- a/src/soc/marvell/mvmap2315/Makefile.inc +++ b/src/soc/marvell/mvmap2315/Makefile.inc @@ -26,6 +26,7 @@ bootblock-y += gic.c bootblock-y += gpio.c bootblock-y += flash.c bootblock-y += load_validate.c +bootblock-y += mcu.c bootblock-y += media.c bootblock-y += nvm.c bootblock-y += pinmux.c diff --git a/src/soc/marvell/mvmap2315/bootblock.c b/src/soc/marvell/mvmap2315/bootblock.c index c1de1e7536..6b0a333333 100644 --- a/src/soc/marvell/mvmap2315/bootblock.c +++ b/src/soc/marvell/mvmap2315/bootblock.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -64,6 +65,13 @@ void bootblock_soc_init(void) boot_path = get_boot_path(); } else { printk(BIOS_DEBUG, "Low power restart. Skip MCU code load.\n"); + + sned_hash_msg(GET_HASH); + receive_hash_msg_respond(); + + printk(BIOS_DEBUG, + "MCU hash validation not currently implemented\n"); + boot_path = get_boot_path(); } diff --git a/src/soc/marvell/mvmap2315/include/soc/addressmap.h b/src/soc/marvell/mvmap2315/include/soc/addressmap.h index 198e8d4374..25bf9d8d1a 100644 --- a/src/soc/marvell/mvmap2315/include/soc/addressmap.h +++ b/src/soc/marvell/mvmap2315/include/soc/addressmap.h @@ -33,6 +33,8 @@ #define MVMAP2315_GPIOH_BASE 0xE0142200 #define MVMAP2315_WDT0_BASE 0XE1010000 #define MVMAP2315_WDT1_BASE 0XE1020000 +#define MVMAP2315_SP_IPC_BASE 0xED0C2000 +#define MVMAP2315_MCU_MSG_BUFF_BASE 0xEE03FF8C #define MVMAP2315_A2BUS_BANKED_BASE 0xF0000000 #define MVMAP2315_A2BUS_ALIAS6_BASE 0xF0002000 diff --git a/src/soc/marvell/mvmap2315/include/soc/mcu.h b/src/soc/marvell/mvmap2315/include/soc/mcu.h new file mode 100644 index 0000000000..99fc5f3d00 --- /dev/null +++ b/src/soc/marvell/mvmap2315/include/soc/mcu.h @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#ifndef __SOC_MARVELL_MVMAP2315_MCU_H__ +#define __SOC_MARVELL_MVMAP2315_MCU_H__ + +#include + +#include +#include + +#define MVMAP2315_MCU_MSG_OFFSET 0xCE000000 + +enum { + GET_HASH = 0x0, + ABORT_HASH = 0x1, + START_HASH = 0x2, + SYNC_HASH = 0x3, +}; + +enum { + ABORT = 0x0, + FINISHED = 0x1, + BUSY = 0x2 +}; + +enum { + MSG_READY = 1, + MSG_RECEIVED = 8, + MSG_READY_RECEIVED = 9, +}; + +struct sp_hash_request_msg { + u8 protocol_version; + u8 csum; + u16 cmd_id; + u8 cmd_version; + u8 reserved0; + u16 length; + u8 hash_subcmd; + u8 hash_type; + u8 nonce_size; + u8 reserved1; + u32 offset; + u32 size; + u8 nonce_data[64]; +}; + +check_member(sp_hash_request_msg, nonce_data, 0x14); +static struct sp_hash_request_msg * const mvmap2315_mcu_msg_buff + = (void *)MVMAP2315_MCU_MSG_BUFF_BASE; + +struct mcu_hash_msg { + u8 protocol_version; + u8 csum; + u16 result; + u16 length; + u8 status; + u8 type; + u8 digest_size; + u8 reserved0; + u32 offset; + u32 size; + u8 digest_data[64]; +}; + +struct mcu_pwr_status_msg { + u8 protocol_version; + u8 csum; + u16 cmd_id; + u8 cmd_version; + u8 reserved; + u16 length; + u8 status; +}; + +#define MVMAP2315_IPC_IRQSET_MSGSENT BIT(0) +#define MVMAP2315_IPC_IRQCLR_MSGREADY BIT(0) +#define MVMAP2315_IPC_IRQCLR_MSGRECEIVED BIT(3) +#define MVMAP2315_IPC_IRQACK BIT(3) +#define MVMAP2315_MCU_IPC_IRQ BIT(6) +struct mvmap2315_ipc_regs { + u32 isrr; + u32 wdr0; + u32 wdr1; + u32 isrw; + u32 icr; + u32 iir; + u32 rdr0; + u32 rdr1; + u32 maj_mid_rev; + u32 cfg_rev; + u32 dummy; +}; + +check_member(mvmap2315_ipc_regs, dummy, 0x28); +static struct mvmap2315_ipc_regs * const mvmap2315_sp_ipc + = (void *)MVMAP2315_SP_IPC_BASE; + +void mcu_irq(void); +void send_mcu_msg(void *msg, u32 size); +void *receive_mcu_msg(void); +void sned_hash_msg(u8 subcmd); +void *receive_hash_msg_respond(void); + +#endif /* __SOC_MARVELL_MVMAP2315_MCU_H__ */ 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 +#include +#include + +#include +#include +#include +#include + +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; +} diff --git a/src/soc/marvell/mvmap2315/pmic.c b/src/soc/marvell/mvmap2315/pmic.c index f263804795..89ea5ebb60 100644 --- a/src/soc/marvell/mvmap2315/pmic.c +++ b/src/soc/marvell/mvmap2315/pmic.c @@ -22,6 +22,7 @@ #include #include #include +#include #include static void syspwr_init(void) @@ -121,5 +122,11 @@ void mcu_start(void) u32 get_boot_path(void) { - return FULL_BOOT; + struct mcu_pwr_status_msg *msg; + + mcu_irq(); + + msg = receive_mcu_msg(); + + return msg->status; } -- cgit v1.2.3