blob: 5e2e61f06d32f7217d65cb88faa557d8353f62f8 [file] [log] [blame]
Julian Hall69a25f32022-09-26 14:55:57 +01001/*
2 * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7
8#include <string>
9#include <cstring>
10#include <common/uuid/uuid.h>
11#include <service/block_storage/block_store/device/ram/ram_block_store.h>
12#include <service/block_storage/config/ref/ref_partition_configurator.h>
13#include <media/volume/index/volume_index.h>
14#include <media/volume/block_io_dev/block_io_dev.h>
15#include <media/volume/base_io_dev/base_io_dev.h>
16#include <media/disk/disk_images/ref_partition.h>
Julian Hall09a05822022-09-28 16:53:49 +010017#include <media/disk/formatter/disk_formatter.h>
Julian Hall69a25f32022-09-26 14:55:57 +010018#include <media/disk/partition_table.h>
19#include <CppUTest/TestHarness.h>
20
21TEST_GROUP(PartitionTableTests)
22{
23 void setup()
24 {
25 /* Load reference GPT image into ram block store */
26 size_t block_size = PLAT_PARTITION_BLOCK_SIZE;
27 size_t num_blocks = ref_partition_data_length / block_size;
28
29 m_block_store = ram_block_store_init(&m_ram_block_store,
30 NULL,
Julian Hall09a05822022-09-28 16:53:49 +010031 num_blocks, block_size);
Julian Hall69a25f32022-09-26 14:55:57 +010032
33 CHECK_TRUE(m_block_store);
34
35 memset(m_partition_guid.octets, 0, sizeof(m_partition_guid.octets));
36
37 m_dev_handle = 0;
38 m_volume_spec = 0;
39
40 int result = block_io_dev_init(&m_block_io_dev,
41 m_block_store, &m_partition_guid,
42 &m_dev_handle, &m_volume_spec);
43
44 LONGS_EQUAL(0, result);
45 CHECK_TRUE(m_dev_handle);
46 CHECK_TRUE(m_volume_spec);
47
Julian Hall09a05822022-09-28 16:53:49 +010048 result = disk_formatter_clone(
49 m_dev_handle, m_volume_spec,
50 ref_partition_data, ref_partition_data_length);
51
52 LONGS_EQUAL(0, result);
53
Julian Hall69a25f32022-09-26 14:55:57 +010054 volume_index_init();
55 volume_index_add(TEST_VOLUME_ID, m_dev_handle, m_volume_spec);
56 }
57
58 void teardown()
59 {
60 block_io_dev_deinit(&m_block_io_dev);
61 ram_block_store_deinit(&m_ram_block_store);
62 volume_index_clear();
63 }
64
65 void uuid_from_canonical(uuid_t *uuid, const char *canonical)
66 {
67 uuid_parse_to_octets_reversed(canonical, (uint8_t*)uuid, sizeof(uuid_t));
68 }
69
70 void corrupt_mbr()
71 {
72 /* Scribble over the protective MBR signature */
73 static const char scribble[] = "scribble";
74 psa_status_t status = ram_block_store_modify(
75 &m_ram_block_store, 510,
76 (const uint8_t*)scribble, sizeof(scribble));
77 LONGS_EQUAL(PSA_SUCCESS, status);
78 }
79
80 void corrupt_primary_gpt_header()
81 {
82 /* Scribble over the primary GPT header in block 1 */
83 static const char scribble[] = "scribble";
84 psa_status_t status = ram_block_store_modify(
85 &m_ram_block_store, PLAT_PARTITION_BLOCK_SIZE * 1,
86 (const uint8_t*)scribble, sizeof(scribble));
87 LONGS_EQUAL(PSA_SUCCESS, status);
88 }
89
90 static const unsigned int TEST_VOLUME_ID = 5;
91 static const uint32_t CLIENT_ID = 0;
92 static const size_t FIRST_USABLE_LBA = 34;
93
94 struct uuid_octets m_partition_guid;
95 struct block_store *m_block_store;
96 struct ram_block_store m_ram_block_store;
97 struct block_io_dev m_block_io_dev;
98 uintptr_t m_dev_handle;
99 uintptr_t m_volume_spec;
100};
101
102TEST(PartitionTableTests, loadRefPartitionTable)
103{
104 int result = load_partition_table(TEST_VOLUME_ID);
105 LONGS_EQUAL(0, result);
106
107 /* Check for expected partition entries */
108 const partition_entry_t *partition_entry = NULL;
109 uuid_t partition_guid;
110
111 uuid_from_canonical(&partition_guid, REF_PARTITION_1_GUID);
112 partition_entry = get_partition_entry_by_uuid(&partition_guid);
113 CHECK_TRUE(partition_entry);
114 UNSIGNED_LONGS_EQUAL(
115 FIRST_USABLE_LBA + REF_PARTITION_1_STARTING_LBA,
116 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
117 UNSIGNED_LONGS_EQUAL(
118 (REF_PARTITION_1_ENDING_LBA - REF_PARTITION_1_STARTING_LBA + 1),
119 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
120
121 uuid_from_canonical(&partition_guid, REF_PARTITION_2_GUID);
122 partition_entry = get_partition_entry_by_uuid(&partition_guid);
123 CHECK_TRUE(partition_entry);
124 UNSIGNED_LONGS_EQUAL(
125 FIRST_USABLE_LBA + REF_PARTITION_2_STARTING_LBA,
126 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
127 UNSIGNED_LONGS_EQUAL(
128 (REF_PARTITION_2_ENDING_LBA - REF_PARTITION_2_STARTING_LBA + 1),
129 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
130
131 uuid_from_canonical(&partition_guid, REF_PARTITION_3_GUID);
132 partition_entry = get_partition_entry_by_uuid(&partition_guid);
133 CHECK_TRUE(partition_entry);
134 UNSIGNED_LONGS_EQUAL(
135 FIRST_USABLE_LBA + REF_PARTITION_3_STARTING_LBA,
136 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
137 UNSIGNED_LONGS_EQUAL(
138 (REF_PARTITION_3_ENDING_LBA - REF_PARTITION_3_STARTING_LBA + 1),
139 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
140
141 uuid_from_canonical(&partition_guid, REF_PARTITION_4_GUID);
142 partition_entry = get_partition_entry_by_uuid(&partition_guid);
143 CHECK_TRUE(partition_entry);
144 UNSIGNED_LONGS_EQUAL(
145 FIRST_USABLE_LBA + REF_PARTITION_4_STARTING_LBA,
146 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
147 UNSIGNED_LONGS_EQUAL(
148 (REF_PARTITION_4_ENDING_LBA - REF_PARTITION_4_STARTING_LBA + 1),
149 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
150}
151
152TEST(PartitionTableTests, detectCorruptedMbr)
153{
154 corrupt_mbr();
155 int result = load_partition_table(TEST_VOLUME_ID);
156 LONGS_EQUAL(-ENOENT, result);
157}
158
159// Shows up defect in TF-A where failed GPT header CRC results in an assert.
160IGNORE_TEST(PartitionTableTests, detectCorruptedGptHeader)
161{
162 /* Load should be successful with a corrupted primary GPT header as
163 * backup is still available.
164 */
165 corrupt_primary_gpt_header();
166 int result = load_partition_table(TEST_VOLUME_ID);
167 LONGS_EQUAL(0, result);
168}