blob: 7346c0cf32a51e39279ed55cdc36297b953060db [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <boot_api.h>
10#include <debug.h>
11#include <io_driver.h>
12#include <io_dummy.h>
13#include <io_storage.h>
14#include <mmio.h>
15#include <platform.h>
16#include <platform_def.h>
17#include <stm32mp1_private.h>
18#include <stm32mp1_rcc.h>
19#include <string.h>
20#include <utils.h>
21
22/* IO devices */
23static const io_dev_connector_t *dummy_dev_con;
24static uintptr_t dummy_dev_handle;
25static uintptr_t dummy_dev_spec;
26
27static const io_block_spec_t bl32_block_spec = {
28 .offset = BL32_BASE,
29 .length = STM32MP1_BL32_SIZE
30};
31
32static const io_block_spec_t bl2_block_spec = {
33 .offset = BL2_BASE,
34 .length = STM32MP1_BL2_SIZE,
35};
36
37static int open_dummy(const uintptr_t spec);
38
39struct plat_io_policy {
40 uintptr_t *dev_handle;
41 uintptr_t image_spec;
42 int (*check)(const uintptr_t spec);
43};
44
45static const struct plat_io_policy policies[] = {
46 [BL2_IMAGE_ID] = {
47 .dev_handle = &dummy_dev_handle,
48 .image_spec = (uintptr_t)&bl2_block_spec,
49 .check = open_dummy
50 },
51 [BL32_IMAGE_ID] = {
52 .dev_handle = &dummy_dev_handle,
53 .image_spec = (uintptr_t)&bl32_block_spec,
54 .check = open_dummy
55 },
56};
57
58static int open_dummy(const uintptr_t spec)
59{
60 return io_dev_init(dummy_dev_handle, 0);
61}
62
63static void print_boot_device(boot_api_context_t *boot_context)
64{
65 switch (boot_context->boot_interface_selected) {
66 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
67 INFO("Using SDMMC\n");
68 break;
69 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
70 INFO("Using EMMC\n");
71 break;
72 default:
73 ERROR("Boot interface not found\n");
74 panic();
75 break;
76 }
77
78 if (boot_context->boot_interface_instance != 0U) {
79 INFO(" Instance %d\n", boot_context->boot_interface_instance);
80 }
81}
82
83static void print_reset_reason(void)
84{
85 uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
86
87 if (rstsr == 0U) {
88 WARN("Reset reason unknown\n");
89 return;
90 }
91
92 INFO("Reset reason (0x%x):\n", rstsr);
93
94 if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
95 if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
96 INFO("System exits from STANDBY\n");
97 return;
98 }
99
100 if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
101 INFO("MPU exits from CSTANDBY\n");
102 return;
103 }
104 }
105
106 if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
107 INFO(" Power-on Reset (rst_por)\n");
108 return;
109 }
110
111 if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
112 INFO(" Brownout Reset (rst_bor)\n");
113 return;
114 }
115
116 if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
117 INFO(" System reset generated by MPU (MPSYSRST)\n");
118 return;
119 }
120
121 if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
122 INFO(" Reset due to a clock failure on HSE\n");
123 return;
124 }
125
126 if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
127 INFO(" IWDG1 Reset (rst_iwdg1)\n");
128 return;
129 }
130
131 if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
132 INFO(" IWDG2 Reset (rst_iwdg2)\n");
133 return;
134 }
135
136 if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
137 INFO(" Pad Reset from NRST\n");
138 return;
139 }
140
141 if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
142 INFO(" Reset due to a failure of VDD_CORE\n");
143 return;
144 }
145
146 ERROR(" Unidentified reset reason\n");
147}
148
149void stm32mp1_io_setup(void)
150{
151 int io_result __unused;
152 boot_api_context_t *boot_context =
153 (boot_api_context_t *)stm32mp1_get_boot_ctx_address();
154
155 print_reset_reason();
156
157 print_boot_device(boot_context);
158
159 if ((boot_context->boot_partition_used_toboot == 1U) ||
160 (boot_context->boot_partition_used_toboot == 2U)) {
161 INFO("Boot used partition fsbl%d\n",
162 boot_context->boot_partition_used_toboot);
163 }
164
165 io_result = register_io_dev_dummy(&dummy_dev_con);
166 assert(io_result == 0);
167
168 io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
169 &dummy_dev_handle);
170 assert(io_result == 0);
171}
172
173/*
174 * Return an IO device handle and specification which can be used to access
175 * an image. Use this to enforce platform load policy.
176 */
177int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
178 uintptr_t *image_spec)
179{
180 int rc;
181 const struct plat_io_policy *policy;
182
183 assert(image_id < ARRAY_SIZE(policies));
184
185 policy = &policies[image_id];
186 rc = policy->check(policy->image_spec);
187 if (rc == 0) {
188 *image_spec = policy->image_spec;
189 *dev_handle = *(policy->dev_handle);
190 }
191
192 return rc;
193}