52 using Device_type = DEV;
60 void read(Errand::Callback
const &callback)
66 _db = _header.inout_block();
67 read_sectors(0, &Partition_reader::get_gpt);
71 {
return _num_partitions; }
75 if (idx == 0 || idx > _num_partitions)
78 unsigned secsz = _dev->sector_size();
79 auto *header = _header.template get<Gpt::Header const>(secsz);
81 Gpt::Entry *e = _parray.template get<Gpt::Entry>((idx - 1) * header->entry_size);
86 render_guid(e->partition_guid, inf->
guid);
89 std::u16string((
char16_t *)e->name,
sizeof(e->name) /
sizeof(e->name[0]));
90 inf->
name = name.substr(0, name.find((
char16_t) 0));
92 inf->
first = e->first;
94 inf->
flags = e->flags;
96 auto info = Dbg::info();
99 info.printf(
"%3zu: %10lld %10lld %5gMiB [%.37s]\n",
100 idx, e->first, e->last,
101 (e->last - e->first + 1.0) * secsz / (1 << 20),
105 info.printf(
" : Type: %s\n", render_guid(e->type_guid, buf));
108 auto warn = Dbg::warn();
112 "Invalid settings of %3zu. Last lba before first lba. Will ignore.\n",
123 void invoke_callback()
143 unsigned secsz = _dev->sector_size();
144 auto *header = _header.template get<Gpt::Header const>(secsz);
146 auto info = Dbg::info();
147 auto trace = Dbg::trace();
149 if (strncmp(header->signature,
"EFI PART", 8) != 0)
151 info.printf(
"No GUID partition header found.\n");
158 info.printf(
"GUID partition header found with up to %d partitions.\n",
159 header->partition_array_size);
161 info.printf(
"GUID: %s\n", render_guid(header->disk_guid, buf));
162 trace.printf(
"Header positions: %llx (Backup: %llx)\n",
163 header->current_lba, header->backup_lba);
164 trace.printf(
"First + last: %llx and %llx\n",
165 header->first_lba, header->last_lba);
166 trace.printf(
"Partition table at %llx\n",
167 header->partition_array_lba);
168 trace.printf(
"Size of a partition entry: %d\n",
171 info.printf(
"GUID partition header found with %d partitions.\n",
172 header->partition_array_size);
174 _num_partitions = cxx::min<l4_uint32_t>(header->partition_array_size,
177 l4_size_t arraysz = _num_partitions * header->entry_size;
178 l4_size_t numsec = (arraysz - 1 + secsz) / secsz;
181 trace.printf(
"Reading GPT table @ 0x%p\n", _parray.template get<void>(0));
183 _db = _parray.inout_block();
184 read_sectors(header->partition_array_lba, &Partition_reader::done_gpt);
203 using namespace std::placeholders;
204 auto next = std::bind(func,
this, _1, _2);
207 l4_addr_t vend = vstart + _db.num_sectors * _dev->sector_size();
210 Errand::poll(10, 10000,
213 int ret = _dev->inout_data(
215 [next, vstart, vend](
int error,
l4_size_t size)
225 [=](
bool ret) {
if (!ret) invoke_callback(); }
229 static char const *render_guid(
void const *guid_p,
char buf[])
231 auto *p =
static_cast<unsigned char const *
>(guid_p);
233 "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
234 p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6],
235 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
245 Errand::Callback _callback;