blob: 1c1ea440da68e0cd5eff3c2f89cdab6a5af5eac8 [file] [log] [blame]
Brahmaji K9d635ed2017-06-23 13:10:57 +05301/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Reut Zysmanff6bab92016-02-09 14:06:31 +02002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdlib.h>
30#include <stdio.h>
31#include <stdbool.h>
32#include <debug.h>
33#include <dev/fbcon.h>
34#include <target.h>
35#include <mmc.h>
36#include <partition_parser.h>
37#include <string.h>
38#include "mdtp.h"
39#include "mdtp_fs.h"
40
41/*---------------------------------------------------------
42 * Global Variables
43 *-------------------------------------------------------*/
44static mdtp_image_t mdtp_img;
45
46/*---------------------------------------------------------
Reut Zysman3f3eccd2016-04-20 22:05:36 +030047 * Internal Functions
48 *-------------------------------------------------------*/
49
50static int mdtp_read_metadata(uint32_t offset){
51 int index = INVALID_PTN;
52 unsigned long long ptn = 0;
53 int i = 0;
54 uint32_t block_size = mmc_get_device_blocksize();
55
56 index = partition_get_index("mdtp");
57 if (index == 0) {
58 dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
59 return -1;
60 }
61
62 ptn = partition_get_offset(index);
63 mmc_set_lun(partition_get_lun(index));
64
65 if (ptn == 0) {
66 dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
67 return -1;
68 }
69
70 for(i = 0; i< MAX_PARAMS; i++) {
71 mdtp_img.meta_data.params[i] = MDTP_PARAM_UNSET_VALUE; //Initialize params for error check
72 }
73
74 uint8_t *base = memalign(block_size, ROUNDUP(MDTP_HEADER_LEN, block_size));
75 if (!base) {
76 dprintf(CRITICAL, "ERROR: mdtp malloc failed\n");
77 return -1;
78 }
79
80 // read image meta data
81 if (mmc_read(ptn+offset, (void*)base, MDTP_HEADER_LEN)) {
82 dprintf(CRITICAL, "ERROR: mdtp meta data read failed\n");
83 free(base);
84 return -1;
85 }
86
87 uint32_t params_size = MAX_PARAMS * sizeof(uint32_t);
88 uint32_t images_params_size = MAX_IMAGES*sizeof(mdtp_image_params_t);
89 memscpy(mdtp_img.meta_data.params, sizeof(mdtp_img.meta_data.params), base, params_size);
90 memscpy(mdtp_img.meta_data.image_params, META_DATA_PARTITION_LEN,
91 base + sizeof(mdtp_img.meta_data.params), images_params_size);
92
93 dprintf(INFO, "mdtp: metadata loaded\n");
94
95 free(base);
96 return 0;
97}
98
99static void mdtp_fs_set_param(mdtp_parameter_id_t param, uint32_t value){
100 mdtp_img.meta_data.params[param] = value;
101}
102
103/*---------------------------------------------------------
Reut Zysmanff6bab92016-02-09 14:06:31 +0200104 * External Functions
105 *-------------------------------------------------------*/
106
107uint32_t get_image_offset(mdtp_image_id_t img){
108 return mdtp_img.meta_data.image_params[img].offset;
109}
110
111uint32_t get_image_width(mdtp_image_id_t img){
112 return mdtp_img.meta_data.image_params[img].width;
113}
114
115uint32_t get_image_height(mdtp_image_id_t img){
116 return mdtp_img.meta_data.image_params[img].height;
117}
118
119uint32_t mdtp_fs_get_param(mdtp_parameter_id_t param){
120 return mdtp_img.meta_data.params[param];
121}
122
Reut Zysmanff6bab92016-02-09 14:06:31 +0200123int mdtp_fs_init(){
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300124 uint32_t i;
125 struct fbcon_config *fb_config = NULL;
126 mdtp_image_params_t image_params;
127 mdtp_image_t mdtp_image_sets_metadata;
128 uint32_t image_sets_num;
129 uint32_t metadata_offset = 0;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200130
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300131 // Read image sets metadata
132 if (mdtp_read_metadata(metadata_offset)){
133 dprintf(CRITICAL, "ERROR: failed to read image sets metadata\n");
134 return -1;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200135 }
136
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300137 // Verify that metadata version is supported
138 if (mdtp_fs_get_param(VERSION) != SUPPORTED_METADATA_VERSION){
139 dprintf(CRITICAL, "ERROR: metadata version is not supported: %d\n", mdtp_fs_get_param(VERSION));
140 return -1;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200141 }
142
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300143 // Verify that metadata version is as expected
144 if (mdtp_fs_get_param(TYPE) != IMAGE_SETS){
145 dprintf(CRITICAL, "ERROR: unexpected type for image sets metadata: %d\n", mdtp_fs_get_param(TYPE));
146 return -1;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200147 }
148
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300149 image_sets_num = mdtp_fs_get_param(IMAGE_SETS_NUM);
Brahmaji K9d635ed2017-06-23 13:10:57 +0530150 if ( (image_sets_num < 1) || (image_sets_num >= MAX_IMAGES) ) {
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300151 dprintf(CRITICAL, "ERROR: invalid number of image sets: %d\n", image_sets_num);
152 return -1;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200153 }
154
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300155 // Image sets are sorted by screen resolution (width, height), from low to high.
156 // We begin with the smallest image set, and check if bigger image sets also fit the screen.
157 image_params = mdtp_img.meta_data.image_params[0];
158
Reut Zysman452f07d2016-06-22 14:11:29 +0300159 // Get screen configuration
160 fb_config = fbcon_display();
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300161
Reut Zysman452f07d2016-06-22 14:11:29 +0300162 if (fb_config){
163
164 for (i=1; i<image_sets_num; i++){
165
166 //if both width and height still fit the screen, update image_params
167 if (mdtp_img.meta_data.image_params[i].width <= fb_config->width &&
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300168 mdtp_img.meta_data.image_params[i].height <= fb_config->height)
Reut Zysman452f07d2016-06-22 14:11:29 +0300169 {
170 image_params = mdtp_img.meta_data.image_params[i];
171 }
172
173 // if we reached an image set in which the width is larger than
174 // the screen width, no point in checking additional image sets.
175 else if (mdtp_img.meta_data.image_params[i].width > fb_config->width)
176 break;
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300177 }
178
Reut Zysman452f07d2016-06-22 14:11:29 +0300179 dprintf(INFO, "mdtp: image set offset: 0x%x\n", image_params.offset);
180 dprintf(INFO, "mdtp: image set width: %d, screen width: %d\n", image_params.width, fb_config->width);
181 dprintf(INFO, "mdtp: image set height: %d, screen height: %d\n", image_params.height, fb_config->height);
Reut Zysmanff6bab92016-02-09 14:06:31 +0200182 }
Reut Zysman452f07d2016-06-22 14:11:29 +0300183 else {
184 // Display configuration is not available.
185 // This will cause an actual error only when (and if) trying to display MDTP images.
186 dprintf(INFO,"mdtp: fbcon_config struct is NULL\n");
187 }
Reut Zysman3f3eccd2016-04-20 22:05:36 +0300188
189 // Backup image sets metadata for required parameters
190 mdtp_image_sets_metadata = mdtp_img;
191
192 // Read images metadata
193 if (mdtp_read_metadata(image_params.offset)){
194 dprintf(CRITICAL, "ERROR: failed to read images metadata\n");
195 return -1;
196 }
197
198 // Verify that metadata version is supported
199 if (mdtp_fs_get_param(VERSION) != SUPPORTED_METADATA_VERSION){
200 dprintf(CRITICAL, "ERROR: metadata version is not supported: %d\n", mdtp_fs_get_param(VERSION));
201 return -1;
202 }
203
204 // Verify that metadata version is as expected
205 if (mdtp_fs_get_param(TYPE) != IMAGES){
206 dprintf(CRITICAL, "ERROR: unexpected type for images metadata: %d\n", mdtp_fs_get_param(TYPE));
207 return -1;
208 }
209
210 // Copy eFuse from image sets metadata
211 mdtp_fs_set_param(VIRTUAL_FUSE, mdtp_image_sets_metadata.meta_data.params[VIRTUAL_FUSE]);
Reut Zysmanff6bab92016-02-09 14:06:31 +0200212
213 dprintf(INFO, "mdtp: mdtp_img loaded\n");
214
Reut Zysmanff6bab92016-02-09 14:06:31 +0200215 return 0;
216}
217