blob: 1f68e4b2d59d8a4236dc484627de64550da0d7a9 [file] [log] [blame]
Kinson Chik66552a82011-03-29 15:59:06 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2
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 Code Aurora Forum, Inc. 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 <string.h>
31#include "mmc.h"
32#include "partition_parser.h"
33
34static struct gpt_entry gpt[NUM_GPT_PARTITIONS];
35static uint32_t gpt_partition_count = 0;
36
37/*
38 * Read GPT from MMC and fill partition table
39 */
40uint32_t mmc_boot_read_gpt(struct mmc_boot_host * mmc_host,
41 struct mmc_boot_card * mmc_card){
42
43 int32_t ret = MMC_BOOT_E_SUCCESS;
44 uint32_t header_size = 0;
45 //uint32_t header_crc = 0;
46 uint64_t first_usable_lba = 0;
47 uint64_t last_usable_lba = 0;
48 uint32_t partition_count = 0;
49 uint32_t partition_entry_size = 0;
50 //uint32_t partition_array_crc;
51 uint8_t data[MMC_BOOT_RD_BLOCK_LEN];
52 uint32_t i = 0; /* Counter for each 512 block */
53 uint32_t j = 0; /* Counter for each 128 entry in the 512 block */
54
55 /* Print out the GPT first */
56 ret = mmc_boot_read_from_card( mmc_host, mmc_card,
57 PROTECTIVE_MBR_SIZE,
58 MMC_BOOT_RD_BLOCK_LEN,
59 (uint32_t *)data);
60
61 /* Check GPT Signature */
62 if( ((uint32_t *)data)[0] != GPT_SIGNATURE_2 ||
63 ((uint32_t *)data)[1] != GPT_SIGNATURE_1 )
64 {
65 dprintf(CRITICAL, "GPT: signature does not match.\n" );
66 return MMC_BOOT_E_FAILURE;
67 }
68
69 header_size = GET_LWORD_FROM_BYTE(&data[HEADER_SIZE_OFFSET]);
70 //header_crc = GET_LWORD_FROM_BYTE(&data[HEADER_CRC_OFFSET]);
71 first_usable_lba = GET_LLWORD_FROM_BYTE(&data[FIRST_USABLE_LBA_OFFSET]);
72 last_usable_lba = GET_LLWORD_FROM_BYTE(&data[LAST_USABLE_LBA_OFFSET]);
73 partition_count = GET_LWORD_FROM_BYTE(&data[PARTITION_COUNT_OFFSET]);
74 partition_entry_size = GET_LWORD_FROM_BYTE(&data[PENTRY_SIZE_OFFSET]);
75
76 /* Read GPT Entries */
77 for(i = 0; i < (partition_count/4); i++)
78 {
79 ret = mmc_boot_read_from_card( mmc_host, mmc_card,
80 PROTECTIVE_MBR_SIZE + PARTITION_TABLE_SIZE +
81 (i * MMC_BOOT_RD_BLOCK_LEN),
82 MMC_BOOT_RD_BLOCK_LEN,
83 (uint32_t *)data);
84
85 if (ret)
86 {
87 dprintf(CRITICAL, "GPT: mmc read card failed reading partition entries.\n" );
88 return ret;
89 }
90
91 for(j=0; j < 4; j++)
92 {
93 memcpy(&(gpt[j+(i*4)].partition_type_guid),
94 &data[(j * partition_entry_size)], PARTITION_TYPE_GUID_SIZE);
95
96 if (gpt[j+(i*4)].partition_type_guid[0] == 0x00 &&
97 gpt[j+(i*4)].partition_type_guid[1] == 0x00)
98 {
99 i = partition_count;
100 break;
101 }
102 gpt_partition_count++;
103
104 memcpy(&(gpt[j+(i*4)].unique_partition_guid),
105 &data[(j * partition_entry_size) + UNIQUE_GUID_OFFSET], UNIQUE_PARTITION_GUID_SIZE);
106 gpt[j+(i*4)].first_lba = GET_LLWORD_FROM_BYTE(&data[(j * partition_entry_size) +
107 FIRST_LBA_OFFSET]);
108 gpt[j+(i*4)].last_lba = GET_LLWORD_FROM_BYTE(&data[(j * partition_entry_size) +
109 LAST_LBA_OFFSET]);
110 gpt[j+(i*4)].attribute_flag = GET_LLWORD_FROM_BYTE(&data[(j * partition_entry_size) +
111 ATTRIBUTE_FLAG_OFFSET]);
112 memcpy(&(gpt[j+(i*4)].partition_name),
113 &data[(j * partition_entry_size) + PARTITION_NAME_OFFSET], MAX_GPT_NAME_SIZE);
114 }
115 }
116 return ret;
117}
118
119uint64_t gpt_lookup(uint8_t * name, unsigned type){
120 uint32_t input_string_length = strlen(name);
121 uint8_t UTF16_name[MAX_GPT_NAME_SIZE];
122 unsigned n;
123
124 memset(&UTF16_name, 0x00, MAX_GPT_NAME_SIZE);
125 /* Currently partition names in partition.xml are UTF-8 and lowercase */
126 for(n = 0; n < input_string_length && n < MAX_GPT_NAME_SIZE/2; n++){
127 UTF16_name[n*2] = name[n];
128 UTF16_name[n*2+1] = 0x00;
129 }
130 for(n = 0; n < gpt_partition_count; n++){
131 if(!memcmp(&UTF16_name, &gpt[n].partition_name, MAX_GPT_NAME_SIZE)){
132 if(type == PTN_SIZE)
133 return ((uint64_t)(gpt[n].last_lba - gpt[n].first_lba) * MMC_BOOT_RD_BLOCK_LEN);
134 else if(type == PTN_OFFSET)
135 return ((uint64_t)gpt[n].first_lba * MMC_BOOT_RD_BLOCK_LEN);
136 else
137 return 0;
138 }
139 }
140 return 0;
141}