#!/usr/bin/perl -w

use Fcntl qw (:seek);

# open the file
my $filename = "dist/prototype_x86_64-linux/RVM.rmap.image";
open(RMAP,$filename) or die "Unable to open $filename:$!\n";
binmode RMAP, ":bytes";

my $BYTES_IN_ADDRESS = 4;
my $LOG_CHUNK_BYTES = 12;
my $CHUNK_BYTES = 1<<$LOG_CHUNK_BYTES;
my $LONG_MASK = 0x1;
my $RUN_MASK = 0x2;
my $MAX_RUN = (1<<8)-1;
my $LONG_OFFSET_BYTES = 4;
my $GUARD_REGION = $LONG_OFFSET_BYTES + 1;

sub processChunk {
  my ($chunkStart, $imageStart, $mapStart, $mapEnd) = @_;
  seek RMAP, $chunkStart - $mapStart, SEEK_SET;
  my $data;
  my $offset = 0;
  while (read(RMAP,$data,1)) {
    my $value = unpack "C", $data;
    if (($value & 0xFF) == 0) {
      return;
    }
    if (($value & $LONG_MASK) != 0) {
      $offset = $value & 0xFC;
      read(RMAP,$data,1);
      my $value2 = unpack "C", $data;
      $offset |= ($value2 << 8) & 0xFF00;
      read(RMAP,$data,1);
      $value2 = unpack "C", $data;
      $offset |= ($value2 << 16) & 0xFF0000;
      read(RMAP,$data,1);
      $value2 = unpack "C", $data;
      $offset |= ($value2 << 24) & 0xFF000000;
    } else {
      $offset += $value & 0xFC;
    }
    my $runlength=0;
    if (($value & $RUN_MASK) != 0) {
      read(RMAP,$data,1);
      $runlength = unpack "C", $data;
    }
    my $slot = $imageStart + $offset;
    printf "0x%08X, 0x%08X\n", $slot & ~4095, $slot & 4095;
    if ($runlength != 0) {
      for (my $i=0; $i < $runlength; $i++) {
        $offset = $offset + $BYTES_IN_ADDRESS;
        $slot = $imageStart + $offset;
        printf "0x%08X, 0x%08X\n", $slot & ~4095, $slot & 4095;
      }
    }
  }
}

sub processBootImage {
  my ($mapStart, $mapEnd, $imageStart) = @_;
  for (my $cursor = $mapStart; $cursor < $mapEnd; $cursor += $CHUNK_BYTES) {
    processChunk($cursor, $imageStart, $mapStart, $mapEnd);
  }
}
 
processBootImage(0x67000000, 0x67084ac9, 0x60000000);
# close the file
close(RMAP);

