diff options
author | Hakim Giydan <hgiydan@marvell.com> | 2016-09-08 10:59:15 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-09-13 16:59:08 +0200 |
commit | f727c7ce38cc58eaf24c55d440e885a1b24a26a1 (patch) | |
tree | f03978e1169d8683d45bec9254ede78eff2cda39 /src/soc/marvell | |
parent | 34c835db307666385374670123477434c99473ec (diff) | |
download | coreboot-f727c7ce38cc58eaf24c55d440e885a1b24a26a1.tar.xz |
soc/marvell/mvmap2315: Add MCU driver
Testing: booted successfully.
Change-Id: I003f6929b00476d46be931773cd35418fe6622a6
Signed-off-by: Hakim Giydan <hgiydan@marvell.com>
Reviewed-on: https://review.coreboot.org/15529
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/marvell')
-rw-r--r-- | src/soc/marvell/mvmap2315/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/marvell/mvmap2315/bootblock.c | 8 | ||||
-rw-r--r-- | src/soc/marvell/mvmap2315/include/soc/addressmap.h | 2 | ||||
-rw-r--r-- | src/soc/marvell/mvmap2315/include/soc/mcu.h | 118 | ||||
-rw-r--r-- | src/soc/marvell/mvmap2315/mcu.c | 130 | ||||
-rw-r--r-- | src/soc/marvell/mvmap2315/pmic.c | 9 |
6 files changed, 267 insertions, 1 deletions
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 <soc/bdb.h> #include <soc/gic.h> #include <soc/load_validate.h> +#include <soc/mcu.h> #include <soc/pmic.h> #include <soc/uart.h> @@ -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 <stdint.h> + +#include <soc/addressmap.h> +#include <types.h> + +#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 <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; +} 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 <console/console.h> #include <soc/apmu.h> #include <soc/clock.h> +#include <soc/mcu.h> #include <soc/pmic.h> 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; } |