51 using Device_type = DEV;
59 void read(Errand::Callback
const &callback)
65 _db = _header.inout_block();
66 read_sectors(0, &Partition_reader::get_gpt);
70 {
return _num_partitions; }
74 if (idx == 0 || idx > _num_partitions)
77 unsigned secsz = _dev->sector_size();
78 auto *header = _header.template get<Gpt::Header const>(secsz);
80 Gpt::Entry *e = _parray.template get<Gpt::Entry>((idx - 1) * header->entry_size);
85 render_guid(e->partition_guid, inf->
guid);
88 std::u16string((
char16_t *)e->name,
sizeof(e->name) /
sizeof(e->name[0]));
89 inf->
name = name.substr(0, name.find((
char16_t) 0));
91 inf->
first = e->first;
93 inf->
flags = e->flags;
95 auto info = Dbg::info();
98 info.printf(
"%3zu: %10lld %10lld %5gMiB [%.37s]\n",
99 idx, e->first, e->last,
100 (e->last - e->first + 1.0) * secsz / (1 << 20),
104 info.printf(
" : Type: %s\n", render_guid(e->type_guid, buf));
107 auto warn = Dbg::warn();
111 "Invalid settings of %3zu. Last lba before first lba. Will ignore.\n",
122 void invoke_callback()
142 unsigned secsz = _dev->sector_size();
143 auto *header = _header.template get<Gpt::Header const>(secsz);
145 auto info = Dbg::info();
146 auto trace = Dbg::trace();
148 if (strncmp(header->signature,
"EFI PART", 8) != 0)
150 info.printf(
"No GUID partition header found.\n");
157 info.printf(
"GUID partition header found with up to %d partitions.\n",
158 header->partition_array_size);
160 info.printf(
"GUID: %s\n", render_guid(header->disk_guid, buf));
161 trace.printf(
"Header positions: %llx (Backup: %llx)\n",
162 header->current_lba, header->backup_lba);
163 trace.printf(
"First + last: %llx and %llx\n",
164 header->first_lba, header->last_lba);
165 trace.printf(
"Partition table at %llx\n",
166 header->partition_array_lba);
167 trace.printf(
"Size of a partition entry: %d\n",
170 info.printf(
"GUID partition header found with %d partitions.\n",
171 header->partition_array_size);
173 _num_partitions = cxx::min<l4_uint32_t>(header->partition_array_size,
176 l4_size_t arraysz = _num_partitions * header->entry_size;
177 l4_size_t numsec = (arraysz - 1 + secsz) / secsz;
180 trace.printf(
"Reading GPT table @ 0x%p\n", _parray.template get<void>(0));
182 _db = _parray.inout_block();
183 read_sectors(header->partition_array_lba, &Partition_reader::done_gpt);
202 using namespace std::placeholders;
203 auto next = std::bind(func,
this, _1, _2);
206 l4_addr_t vend = vstart + _db.num_sectors * _dev->sector_size();
209 Errand::poll(10, 10000,
212 int ret = _dev->inout_data(
214 [next, vstart, vend](
int error,
l4_size_t size)
224 [=](
bool ret) {
if (!ret) invoke_callback(); }
228 static char const *render_guid(
void const *guid_p,
char buf[])
230 auto *p =
static_cast<unsigned char const *
>(guid_p);
232 "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
233 p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6],
234 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
244 Errand::Callback _callback;