blob: 71c2f45b3f677e474a776924f88eedf9eafc828c [file] [log] [blame]
Jiafei Pan46367ad2018-03-02 07:23:30 +00001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00006
Jiafei Pan46367ad2018-03-02 07:23:30 +00007#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
9#include <platform_def.h>
10
11#include <common/debug.h>
12#include <drivers/io/io_driver.h>
13#include <drivers/io/io_fip.h>
14#include <drivers/io/io_memmap.h>
15#include <drivers/io/io_storage.h>
16#include <tools_share/firmware_image_package.h>
Jiafei Pan46367ad2018-03-02 07:23:30 +000017
18/* IO devices */
19static const io_dev_connector_t *fip_dev_con;
20static uintptr_t fip_dev_handle;
21static const io_dev_connector_t *memmap_dev_con;
22static uintptr_t memmap_dev_handle;
23
24static const io_block_spec_t fip_block_spec = {
25 .offset = PLAT_LS_FIP_BASE,
26 .length = PLAT_LS_FIP_MAX_SIZE
27};
28
29static const io_uuid_spec_t bl2_uuid_spec = {
30 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
31};
32
33static const io_uuid_spec_t bl31_uuid_spec = {
34 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
35};
36
37static const io_uuid_spec_t bl32_uuid_spec = {
38 .uuid = UUID_SECURE_PAYLOAD_BL32,
39};
40
41static const io_uuid_spec_t bl33_uuid_spec = {
42 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
43};
44
45static int open_fip(const uintptr_t spec);
46static int open_memmap(const uintptr_t spec);
47
48struct plat_io_policy {
49 uintptr_t *dev_handle;
50 uintptr_t image_spec;
51 int (*check)(const uintptr_t spec);
52};
53
54static const struct plat_io_policy policies[] = {
55 [FIP_IMAGE_ID] = {
56 &memmap_dev_handle,
57 (uintptr_t)&fip_block_spec,
58 open_memmap
59 },
60 [BL2_IMAGE_ID] = {
61 &fip_dev_handle,
62 (uintptr_t)&bl2_uuid_spec,
63 open_fip
64 },
65 [BL31_IMAGE_ID] = {
66 &fip_dev_handle,
67 (uintptr_t)&bl31_uuid_spec,
68 open_fip
69 },
70 [BL32_IMAGE_ID] = {
71 &fip_dev_handle,
72 (uintptr_t)&bl32_uuid_spec,
73 open_fip
74 },
75 [BL33_IMAGE_ID] = {
76 &fip_dev_handle,
77 (uintptr_t)&bl33_uuid_spec,
78 open_fip
79 },
80};
81
82static int open_fip(const uintptr_t spec)
83{
84 int result;
85 uintptr_t local_image_handle;
86
87 /* See if a Firmware Image Package is available */
88 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
89 if (result == 0) {
90 result = io_open(fip_dev_handle, spec, &local_image_handle);
91 if (result == 0) {
92 VERBOSE("Using FIP\n");
93 io_close(local_image_handle);
94 }
95 }
96 return result;
97}
98
99
100static int open_memmap(const uintptr_t spec)
101{
102 int result;
103 uintptr_t local_image_handle;
104
105 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
106 if (result == 0) {
107 result = io_open(memmap_dev_handle, spec, &local_image_handle);
108 if (result == 0) {
109 VERBOSE("Using Memmap\n");
110 io_close(local_image_handle);
111 }
112 }
113 return result;
114}
115
116
117void ls_io_setup(void)
118{
119 int io_result;
120
121 io_result = register_io_dev_fip(&fip_dev_con);
122 assert(io_result == 0);
123
124 io_result = register_io_dev_memmap(&memmap_dev_con);
125 assert(io_result == 0);
126
127 /* Open connections to devices and cache the handles */
128 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
129 &fip_dev_handle);
130 assert(io_result == 0);
131
132 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
133 &memmap_dev_handle);
134 assert(io_result == 0);
135
136 /* Ignore improbable errors in release builds */
137 (void)io_result;
138}
139
140void plat_ls_io_setup(void)
141{
142 ls_io_setup();
143}
144
145int plat_ls_get_alt_image_source(
146 unsigned int image_id __unused,
147 uintptr_t *dev_handle __unused,
148 uintptr_t *image_spec __unused)
149{
150 /* By default do not try an alternative */
151 return -ENOENT;
152}
153
154/*
155 * Return an IO device handle and specification which can be used to access
156 * an image. Use this to enforce platform load policy.
157 */
158int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
159 uintptr_t *image_spec)
160{
161 int result;
162 const struct plat_io_policy *policy;
163
164 assert(image_id < ARRAY_SIZE(policies));
165
166 policy = &policies[image_id];
167 result = policy->check(policy->image_spec);
168 if (result == 0) {
169 *image_spec = policy->image_spec;
170 *dev_handle = *(policy->dev_handle);
171 } else {
172 VERBOSE("Trying alternative IO\n");
173 result = plat_ls_get_alt_image_source(image_id, dev_handle,
174 image_spec);
175 }
176
177 return result;
178}