43class Partition_reader : 
public cxx::Ref_obj
 
   51  using Device_type = DEV;
 
   53  Partition_reader(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);
 
  200                    void (Partition_reader::*func)(
int, 
l4_size_t))
 
  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;