blob: c02e7a9ff964b670164c63403c9cc08c71e30939 [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>
17#include <media/disk/partition_table.h>
18#include <CppUTest/TestHarness.h>
19
20TEST_GROUP(PartitionTableTests)
21{
22 void setup()
23 {
24 /* Load reference GPT image into ram block store */
25 size_t block_size = PLAT_PARTITION_BLOCK_SIZE;
26 size_t num_blocks = ref_partition_data_length / block_size;
27
28 m_block_store = ram_block_store_init(&m_ram_block_store,
29 NULL,
30 num_blocks, block_size, ref_partition_data);
31
32 CHECK_TRUE(m_block_store);
33
34 memset(m_partition_guid.octets, 0, sizeof(m_partition_guid.octets));
35
36 m_dev_handle = 0;
37 m_volume_spec = 0;
38
39 int result = block_io_dev_init(&m_block_io_dev,
40 m_block_store, &m_partition_guid,
41 &m_dev_handle, &m_volume_spec);
42
43 LONGS_EQUAL(0, result);
44 CHECK_TRUE(m_dev_handle);
45 CHECK_TRUE(m_volume_spec);
46
47 volume_index_init();
48 volume_index_add(TEST_VOLUME_ID, m_dev_handle, m_volume_spec);
49 }
50
51 void teardown()
52 {
53 block_io_dev_deinit(&m_block_io_dev);
54 ram_block_store_deinit(&m_ram_block_store);
55 volume_index_clear();
56 }
57
58 void uuid_from_canonical(uuid_t *uuid, const char *canonical)
59 {
60 uuid_parse_to_octets_reversed(canonical, (uint8_t*)uuid, sizeof(uuid_t));
61 }
62
63 void corrupt_mbr()
64 {
65 /* Scribble over the protective MBR signature */
66 static const char scribble[] = "scribble";
67 psa_status_t status = ram_block_store_modify(
68 &m_ram_block_store, 510,
69 (const uint8_t*)scribble, sizeof(scribble));
70 LONGS_EQUAL(PSA_SUCCESS, status);
71 }
72
73 void corrupt_primary_gpt_header()
74 {
75 /* Scribble over the primary GPT header in block 1 */
76 static const char scribble[] = "scribble";
77 psa_status_t status = ram_block_store_modify(
78 &m_ram_block_store, PLAT_PARTITION_BLOCK_SIZE * 1,
79 (const uint8_t*)scribble, sizeof(scribble));
80 LONGS_EQUAL(PSA_SUCCESS, status);
81 }
82
83 static const unsigned int TEST_VOLUME_ID = 5;
84 static const uint32_t CLIENT_ID = 0;
85 static const size_t FIRST_USABLE_LBA = 34;
86
87 struct uuid_octets m_partition_guid;
88 struct block_store *m_block_store;
89 struct ram_block_store m_ram_block_store;
90 struct block_io_dev m_block_io_dev;
91 uintptr_t m_dev_handle;
92 uintptr_t m_volume_spec;
93};
94
95TEST(PartitionTableTests, loadRefPartitionTable)
96{
97 int result = load_partition_table(TEST_VOLUME_ID);
98 LONGS_EQUAL(0, result);
99
100 /* Check for expected partition entries */
101 const partition_entry_t *partition_entry = NULL;
102 uuid_t partition_guid;
103
104 uuid_from_canonical(&partition_guid, REF_PARTITION_1_GUID);
105 partition_entry = get_partition_entry_by_uuid(&partition_guid);
106 CHECK_TRUE(partition_entry);
107 UNSIGNED_LONGS_EQUAL(
108 FIRST_USABLE_LBA + REF_PARTITION_1_STARTING_LBA,
109 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
110 UNSIGNED_LONGS_EQUAL(
111 (REF_PARTITION_1_ENDING_LBA - REF_PARTITION_1_STARTING_LBA + 1),
112 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
113
114 uuid_from_canonical(&partition_guid, REF_PARTITION_2_GUID);
115 partition_entry = get_partition_entry_by_uuid(&partition_guid);
116 CHECK_TRUE(partition_entry);
117 UNSIGNED_LONGS_EQUAL(
118 FIRST_USABLE_LBA + REF_PARTITION_2_STARTING_LBA,
119 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
120 UNSIGNED_LONGS_EQUAL(
121 (REF_PARTITION_2_ENDING_LBA - REF_PARTITION_2_STARTING_LBA + 1),
122 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
123
124 uuid_from_canonical(&partition_guid, REF_PARTITION_3_GUID);
125 partition_entry = get_partition_entry_by_uuid(&partition_guid);
126 CHECK_TRUE(partition_entry);
127 UNSIGNED_LONGS_EQUAL(
128 FIRST_USABLE_LBA + REF_PARTITION_3_STARTING_LBA,
129 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
130 UNSIGNED_LONGS_EQUAL(
131 (REF_PARTITION_3_ENDING_LBA - REF_PARTITION_3_STARTING_LBA + 1),
132 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
133
134 uuid_from_canonical(&partition_guid, REF_PARTITION_4_GUID);
135 partition_entry = get_partition_entry_by_uuid(&partition_guid);
136 CHECK_TRUE(partition_entry);
137 UNSIGNED_LONGS_EQUAL(
138 FIRST_USABLE_LBA + REF_PARTITION_4_STARTING_LBA,
139 partition_entry->start / PLAT_PARTITION_BLOCK_SIZE);
140 UNSIGNED_LONGS_EQUAL(
141 (REF_PARTITION_4_ENDING_LBA - REF_PARTITION_4_STARTING_LBA + 1),
142 partition_entry->length / PLAT_PARTITION_BLOCK_SIZE);
143}
144
145TEST(PartitionTableTests, detectCorruptedMbr)
146{
147 corrupt_mbr();
148 int result = load_partition_table(TEST_VOLUME_ID);
149 LONGS_EQUAL(-ENOENT, result);
150}
151
152// Shows up defect in TF-A where failed GPT header CRC results in an assert.
153IGNORE_TEST(PartitionTableTests, detectCorruptedGptHeader)
154{
155 /* Load should be successful with a corrupted primary GPT header as
156 * backup is still available.
157 */
158 corrupt_primary_gpt_header();
159 int result = load_partition_table(TEST_VOLUME_ID);
160 LONGS_EQUAL(0, result);
161}