2 //uefi patition can see http://en.wikipedia.org/wiki/GUID_Partition_Table for more information
8 #include "diskconfig.h"
11 //big end and little end will different
13 //#define WORDS_BIGENDIAN
20 #define _GET_BYTE(x, n) ( ((x) >> (8 * (n))) & 0xff )
22 #define _PED_SWAP16(x) ( (_GET_BYTE(x, 0) << 8) \
23 + (_GET_BYTE(x, 1) << 0) )
25 #define _PED_SWAP32(x) ( (_GET_BYTE(x, 0) << 24) \
26 + (_GET_BYTE(x, 1) << 16) \
27 + (_GET_BYTE(x, 2) << 8) \
28 + (_GET_BYTE(x, 3) << 0) )
30 #define _PED_SWAP64(x) ( (_GET_BYTE(x, 0) << 56) \
31 + (_GET_BYTE(x, 1) << 48) \
32 + (_GET_BYTE(x, 2) << 40) \
33 + (_GET_BYTE(x, 3) << 32) \
34 + (_GET_BYTE(x, 4) << 24) \
35 + (_GET_BYTE(x, 5) << 16) \
36 + (_GET_BYTE(x, 6) << 8) \
37 + (_GET_BYTE(x, 7) << 0) )
39 #define PED_SWAP16(x) ((unsigned short int) _PED_SWAP16( (unsigned short int) (x) ))
40 #define PED_SWAP32(x) ((unsigned long int) _PED_SWAP32( (unsigned long int) (x) ))
41 #define PED_SWAP64(x) ((unsigned long long int) _PED_SWAP64( (unsigned long long int) (x) ))
48 #ifdef WORDS_BIGENDIAN
50 #define PED_CPU_TO_LE16(x) PED_SWAP16(x)
51 #define PED_CPU_TO_BE16(x) (x)
52 #define PED_CPU_TO_LE32(x) PED_SWAP32(x)
53 #define PED_CPU_TO_BE32(x) (x)
54 #define PED_CPU_TO_LE64(x) PED_SWAP64(x)
55 #define PED_CPU_TO_BE64(x) (x)
57 #define PED_LE16_TO_CPU(x) PED_SWAP16(x)
58 #define PED_BE16_TO_CPU(x) (x)
59 #define PED_LE32_TO_CPU(x) PED_SWAP32(x)
60 #define PED_BE32_TO_CPU(x) (x)
61 #define PED_LE64_TO_CPU(x) PED_SWAP64(x)
62 #define PED_BE64_TO_CPU(x) (x)
64 #else /* !WORDS_BIGENDIAN */
66 #define PED_CPU_TO_LE16(x) (x)
67 #define PED_CPU_TO_BE16(x) PED_SWAP16(x)
68 #define PED_CPU_TO_LE32(x) (x)
69 #define PED_CPU_TO_BE32(x) PED_SWAP32(x)
70 #define PED_CPU_TO_LE64(x) (x)
71 #define PED_CPU_TO_BE64(x) PED_SWAP64(x)
73 #define PED_LE16_TO_CPU(x) (x)
74 #define PED_BE16_TO_CPU(x) PED_SWAP16(x)
75 #define PED_LE32_TO_CPU(x) (x)
76 #define PED_BE32_TO_CPU(x) PED_SWAP32(x)
77 #define PED_LE64_TO_CPU(x) (x)
78 #define PED_BE64_TO_CPU(x) PED_SWAP64(x)
80 #endif /* !WORDS_BIGENDIAN */
82 typedef struct _gpt_entry_block
84 gpt_entry _gpt_entry[MAX_PARTITION_INFO];
85 } __attribute__ ((packed)) gpt_entry_block;
87 gpt_entry_block g_gpt_entry_block = {0};
90 typedef struct _align_pmbr
92 unsigned char dummy[2];
94 } __attribute__ ((packed)) align_pmbr;
97 align_pmbr pmbr __attribute__ ((aligned(4))) = {0};
98 gpt_header gpt_head __attribute__ ((aligned(4))) = {0};
100 static unsigned long long int _cur_lba_num = 0;
101 static unsigned long long int all_used_size = 0;
103 /* Convert char[2] in little endian format to the host format integer
105 static inline unsigned short le16_to_int(unsigned char *le16)
107 return ((le16[1] << 8) + le16[0]);
110 /* Convert char[4] in little endian format to the host format integer
112 static inline unsigned long le32_to_int(unsigned char *le32)
114 return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
117 /* Convert char[8] in little endian format to the host format integer
119 static inline unsigned long long le64_to_int(unsigned char *le64)
121 return (((unsigned long long)le64[7] << 56) +
122 ((unsigned long long)le64[6] << 48) +
123 ((unsigned long long)le64[5] << 40) +
124 ((unsigned long long)le64[4] << 32) +
125 ((unsigned long long)le64[3] << 24) +
126 ((unsigned long long)le64[2] << 16) +
127 ((unsigned long long)le64[1] << 8) +
128 (unsigned long long)le64[0]);
135 static inline unsigned long uefi_crc32(const void *buf, unsigned long len)
137 return crc32(0, buf, len);
143 * some internal function for partition
146 int _gen_pmbr_part(struct partition *part)
148 part->boot_ind = 0x80;
149 part->sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
151 part->end_head = 0xFF;
152 part->end_sector = 0xFF;
153 part->end_cyl = 0xFF;
155 *(unsigned long int*) part->start_sect = PED_CPU_TO_LE32(1UL);
157 //must get device sector number
158 if ( emmc_part_device.total_sector > 0xFFFFFFF)
160 *(unsigned long int*) part->nr_sects = PED_CPU_TO_LE32(0xFFFFFFE);
164 *(unsigned long int*) part->nr_sects = PED_CPU_TO_LE32(emmc_part_device.total_sector);
169 int _gen_pmbr(legacy_mbr *pmbr)
171 memset(pmbr->partition_record, 0, sizeof(pmbr->partition_record));
173 *(unsigned short int*)pmbr->signature = PED_CPU_TO_LE16(MSDOS_MBR_SIGNATURE);
174 _gen_pmbr_part(&pmbr->partition_record[0]);
180 unsigned int _write_pmbr(legacy_mbr *pmbr)
183 emmc_part_device._device_io->_write(0,1,(unsigned char *)pmbr);
187 efi_guid_t _gen_guid(int part_index)
189 efi_guid_t new_guid = EFI_GUID(0x11111111,0x2222,0x3333,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0+part_index);
193 unsigned int _gen_gpt_entry(int part_index , gpt_entry *g_entry,PARTITION_CFG *p_partition_cfg)
198 if( PARTITION_RAW == p_partition_cfg[part_index].partition_attr)
199 g_entry->partition_type_guid = PARTITION_BASIC_DATA_GUID;
200 else if( PARTITION_EXT4 == p_partition_cfg[part_index].partition_attr)
201 g_entry->partition_type_guid = PARTITION_BASIC_DATA_GUID;
203 g_entry->partition_type_guid = PARTITION_BASIC_DATA_GUID;
206 g_entry->unique_partition_guid =_gen_guid(part_index+1) ;
208 *(unsigned long long int*)g_entry->starting_lba = _cur_lba_num;
210 //judge if user data partition
211 if( MAX_SIZE_FLAG == p_partition_cfg[part_index].partition_size)
213 _cur_lba_num = _cur_lba_num + (emmc_part_device.total_sector-STARTING_LBA_OF_FIRST_PARTITION-MAX_PARTITION_INFO/4-1-all_used_size*2);
214 _cur_lba_num = (_cur_lba_num/STARTING_LBA_OF_FIRST_PARTITION)*STARTING_LBA_OF_FIRST_PARTITION;
215 *(unsigned long long int*)g_entry->ending_lba = _cur_lba_num-1;
218 _cur_lba_num = _cur_lba_num + p_partition_cfg[part_index].partition_size * 2;
219 *(unsigned long long int*)g_entry->ending_lba = _cur_lba_num - 1;
222 memset (&g_entry->attributes, 0, sizeof (gpt_entry_attributes));
224 for (i = 0; i < MAX_UTF_PARTITION_NAME_LEN; i++)
225 g_entry->partition_name[i] = (efi_char16_t) PED_CPU_TO_LE16 (p_partition_cfg[part_index].partition_name[i]);
230 unsigned int _parser_cfg(unsigned int *total_partition,PARTITION_CFG *p_partition_cfg)
233 for(count=0;count<MAX_PARTITION_INFO;count++)
235 if(0 == p_partition_cfg[count].partition_size)
237 *total_partition = count;
241 if( MAX_SIZE_FLAG != p_partition_cfg[count].partition_size)
242 all_used_size += p_partition_cfg[count].partition_size;
248 unsigned int _gen_gpt(gpt_header *g_header,PARTITION_CFG *p_partition_cfg)
250 printf("write gpt header \n");
251 int i = 0 ,gpt_partition_number = 0;
252 unsigned long crc = 0;
253 _parser_cfg(&gpt_partition_number,p_partition_cfg);
255 *(unsigned long long int*)g_header->signature = PED_CPU_TO_LE64 (GPT_HEADER_SIGNATURE);
257 *(unsigned long int*)g_header->revision = PED_CPU_TO_LE32 (GPT_HEADER_REVISION_V1);
259 *(unsigned long int*)g_header->header_size = PED_CPU_TO_LE32(92UL);
261 *(unsigned long int*)g_header->reserved1 = PED_CPU_TO_LE32(0);
263 *(unsigned long long int*)g_header->my_lba = PED_CPU_TO_LE64 (1);
265 *(unsigned long long int*)g_header->alternate_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-1);
267 *(unsigned long long int*)g_header->first_usable_lba = PED_CPU_TO_LE64 (MAX_PARTITION_INFO/4 + 2);
269 *(unsigned long long int*)g_header->last_usable_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-2-MAX_PARTITION_INFO/4);
271 g_header->disk_guid = _gen_guid(0);
273 *(unsigned long long int*)g_header->partition_entry_lba = PED_CPU_TO_LE64 (2);
275 *(unsigned long int*)g_header->num_partition_entries = PED_CPU_TO_LE32(gpt_partition_number);
277 *(unsigned long int*)g_header->sizeof_partition_entry = PED_CPU_TO_LE32(sizeof(gpt_entry));
279 memset(g_header->reserved2,0,GPT_BLOCK_SIZE - 92);
281 //_cur_lba_num = MAX_PARTITION_INFO/4 + 2;
282 _cur_lba_num = STARTING_LBA_OF_FIRST_PARTITION;
284 printf("write gpt partition \n");
285 for(i=0;i<gpt_partition_number;i++)
287 _gen_gpt_entry(i,&g_gpt_entry_block._gpt_entry[i],p_partition_cfg);
290 //*(unsigned long int*)g_header->partition_entry_array_crc32 = ;
291 crc = uefi_crc32(&g_gpt_entry_block,(le32_to_int(g_header->num_partition_entries)) *(le32_to_int( g_header->sizeof_partition_entry)));
292 *(unsigned long int*)g_header->partition_entry_array_crc32 = PED_CPU_TO_LE32(crc);
295 crc = uefi_crc32(g_header,le32_to_int(g_header->header_size));
296 *(unsigned long int*)g_header->header_crc32 = PED_CPU_TO_LE32(crc);
301 unsigned int _gen_backup_gpt(gpt_header *g_header,PARTITION_CFG *p_partition_cfg)
303 unsigned long crc = 0;
304 *(unsigned long long int*)g_header->my_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-1);
305 *(unsigned long long int*)g_header->alternate_lba = PED_CPU_TO_LE64 (1);
306 *(unsigned long long int*)g_header->partition_entry_lba = PED_CPU_TO_LE64 (emmc_part_device.total_sector-1-MAX_PARTITION_INFO/4);
307 *(unsigned long int*)g_header->header_crc32 = 0;
308 crc = uefi_crc32(g_header,le32_to_int(g_header->header_size));
309 *(unsigned long int*)g_header->header_crc32 = PED_CPU_TO_LE32(crc);
313 unsigned int _write_gpt(gpt_header *g_header)
316 emmc_part_device._device_io->_write(1,1,(unsigned char*)g_header);
318 emmc_part_device._device_io->_write(2,MAX_PARTITION_INFO/4,(unsigned char*)&g_gpt_entry_block);
320 printf("write gpt entry success \n");
324 unsigned int _write_backup_gpt(gpt_header *g_header)
327 emmc_part_device._device_io->_write((emmc_part_device.total_sector-1),1,(unsigned char*)g_header);
329 emmc_part_device._device_io->_write((emmc_part_device.total_sector-1-MAX_PARTITION_INFO/4),MAX_PARTITION_INFO/4,(unsigned char*)&g_gpt_entry_block);
330 printf("write gpt entry success \n");
336 * UEFI partition interface
349 unsigned int read_uefi_partition_table(PARTITION_TABLE *p_partition_table)
354 #ifdef CONFIG_EBR_PARTITION
355 int write_mbr_partition_table(void)
357 printf("write mbr partition \n");
358 emmc_part_device_init();
360 struct disk_info *device_disk_info;
361 if (!(device_disk_info = load_diskconfig())) {
362 printf("Errors encountered while loading disk partation\n");
365 /* First, partition the drive */
366 if (apply_disk_config(device_disk_info))
367 printf("write partition list success\n");
373 unsigned int write_uefi_partition_table(PARTITION_CFG *p_partition_cfg)
377 memset(&gpt_head, 0x0, GPT_BLOCK_SIZE);
378 emmc_part_device_init();
380 printf("write gpt \n");
382 _gen_pmbr(&pmbr.pmbr);
383 _write_pmbr(&pmbr.pmbr);
385 if( NULL == p_partition_cfg )
390 _gen_gpt(&gpt_head,p_partition_cfg);
391 _write_gpt(&gpt_head);
394 _gen_backup_gpt(&gpt_head,p_partition_cfg);
395 _write_backup_gpt(&gpt_head);
396 printf("write gpt success\n");
400 unsigned int get_uefi_partition_info(int partition_index,PARTITION_INFO *p_partition_info)
407 * UEFI partition test unit
410 unsigned int uefi_unit_test(int test_case)
415 case 1: //write partition test
417 case 2: //read partition test call part_efi.c function
420 ;//first write partition than read partition.