1 /*
2  * Copyright (c) 2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <drivers/arm/css/css_mhu_doorbell.h>
9 #include <drivers/arm/css/scmi.h>
10 #include <drivers/arm/css/sds.h>
11 #include <lib/cassert.h>
12 #include <plat/arm/common/plat_arm.h>
13 
14 #include "morello_def.h"
15 #include <platform_def.h>
16 
17 /*
18  * Platform information structure stored in SDS.
19  * This structure holds information about platform's DDR
20  * size which is an information about multichip setup
21  *	- Local DDR size in bytes, DDR memory in master board
22  *	- Remote DDR size in bytes, DDR memory in slave board
23  *	- slave_count
24  *	- multichip mode
25  */
26 struct morello_plat_info {
27 	uint64_t local_ddr_size;
28 	uint64_t remote_ddr_size;
29 	uint8_t slave_count;
30 	bool multichip_mode;
31 } __packed;
32 
33 /* Compile time assertion to ensure the size of structure is 18 bytes */
34 CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
35 		assert_invalid_plat_info_size);
36 /*
37  * BL33 image information structure stored in SDS.
38  * This structure holds the source & destination addresses and
39  * the size of the BL33 image which will be loaded by BL31.
40  */
41 struct morello_bl33_info {
42 	uint32_t bl33_src_addr;
43 	uint32_t bl33_dst_addr;
44 	uint32_t bl33_size;
45 };
46 
47 static scmi_channel_plat_info_t morello_scmi_plat_info = {
48 	.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
49 	.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
50 	.db_preserve_mask = 0xfffffffe,
51 	.db_modify_mask = 0x1,
52 	.ring_doorbell = &mhu_ring_doorbell
53 };
54 
plat_css_get_scmi_info(int channel_id)55 scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
56 {
57 	return &morello_scmi_plat_info;
58 }
59 
plat_arm_psci_override_pm_ops(plat_psci_ops_t * ops)60 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
61 {
62 	return css_scmi_override_pm_ops(ops);
63 }
64 
copy_bl33(uint32_t src,uint32_t dst,uint32_t size)65 static void copy_bl33(uint32_t src, uint32_t dst, uint32_t size)
66 {
67 	unsigned int i;
68 
69 	INFO("Copying BL33 to DDR memory...\n");
70 	for (i = 0U; i < size; (i = i + 8U))
71 		mmio_write_64((dst + i), mmio_read_64(src + i));
72 
73 	for (i = 0U; i < size; (i = i + 8U)) {
74 		if (mmio_read_64(src + i) != mmio_read_64(dst + i)) {
75 			ERROR("Copy failed!\n");
76 			panic();
77 		}
78 	}
79 	INFO("done\n");
80 }
81 
bl31_platform_setup(void)82 void bl31_platform_setup(void)
83 {
84 	int ret;
85 	struct morello_plat_info plat_info;
86 	struct morello_bl33_info bl33_info;
87 	struct morello_plat_info *copy_dest;
88 
89 	ret = sds_init();
90 	if (ret != SDS_OK) {
91 		ERROR("SDS initialization failed. ret:%d\n", ret);
92 		panic();
93 	}
94 
95 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
96 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
97 				&plat_info,
98 				MORELLO_SDS_PLATFORM_INFO_SIZE,
99 				SDS_ACCESS_MODE_NON_CACHED);
100 	if (ret != SDS_OK) {
101 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
102 		panic();
103 	}
104 
105 	/* Validate plat_info SDS */
106 	if ((plat_info.local_ddr_size == 0U)
107 		|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
108 		|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
109 		|| (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) {
110 		ERROR("platform info SDS is corrupted\n");
111 		panic();
112 	}
113 
114 	arm_bl31_platform_setup();
115 
116 	ret = sds_struct_read(MORELLO_SDS_BL33_INFO_STRUCT_ID,
117 				MORELLO_SDS_BL33_INFO_OFFSET,
118 				&bl33_info,
119 				MORELLO_SDS_BL33_INFO_SIZE,
120 				SDS_ACCESS_MODE_NON_CACHED);
121 	if (ret != SDS_OK) {
122 		ERROR("Error getting BL33 info from SDS. ret:%d\n", ret);
123 		panic();
124 	}
125 	copy_bl33(bl33_info.bl33_src_addr,
126 			bl33_info.bl33_dst_addr,
127 			bl33_info.bl33_size);
128 	/*
129 	 * Pass platform information to BL33. This method is followed as
130 	 * currently there is no BL1/BL2 involved in boot flow of MORELLO.
131 	 * When TBBR is implemented for MORELLO, this method should be removed
132 	 * and platform information should be passed to BL33 using NT_FW_CONFIG
133 	 * passing mechanism.
134 	 */
135 	copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
136 	*copy_dest = plat_info;
137 }
138