#!/usr/bin/perl

# jkob 8/11/2017

sub usage {

    print <<EOF;

NAZWA
   $name -- pokazuje wykorzystanie pamięci   

SKŁADNIA
   $name [-u k|K|m|M|g|G|t|T|p|P]  

OPIS PROGRAMU 
    Program czyta /proc/ioports i wypisuje adresy w systemie dziesiętnym zamiast
    szestnastkowym. Adresy mogą być wypisywane w KB, MB, GB, itd. (dokładniej 
    KiB, MiB, ...).

OPCJE PROGRAMU
   -u k|K adresy w KiB (adres/2^10)
  
   -u m|M adresy w MiB (adres/2^20)

   -u g|G adresy w GiB (adres/2^30)

   -u t|T adresy w TiB (adres/2^40)

   -u p|P adresy w PiB (adres/2^50)

AUTOR 
   Jacek Kobus (jkob\@fizyka.umk.pl)
  
EOF
exit;
}

$name=`basename $0`;
chop($name);

use Getopt::Std;
getopts('hu:');

if ($opt_h) {
    usage();
}

sub prtf {

    my $num=shift;
    my $unit=shift;
    my $format="%16.4f";

    if ( $unit =~ /[kK]/ ) {
	$usymb="K";
	$factor=2**10;
    }

    if ( $unit =~ /[mM]/ ) {
	$usymb="M";
	$factor=2**20;
    }

    if ( $unit =~ /[gG]/ ) {
	$usymb="G";
	$factor=2**30;
    }

    if ( $unit =~ /[tT]/ ) {
	$usymb="T";
	$factor=2**40;
    }

    if ( $unit =~ /[pP]/ ) {
	$usymb="P";
	$factor=2**50;
    }

    printf "$format $usymb",$num/$factor;
}

sub hex2dec {

    my $hex=shift;
    my @hextab=split('',$hex);
    my $dec=0;
    my $power=1;
    for (my $i=$#hextab; $i>=0; $i--) {
#	print $i,": ",$hextab[$i],"\n";
	$hextab[$i] =~ s/a/10/i;
	$hextab[$i] =~ s/b/11/i;
	$hextab[$i] =~ s/c/12/i;
	$hextab[$i] =~ s/d/13/i;
	$hextab[$i] =~ s/e/14/i;
	$hextab[$i] =~ s/f/15/i;
	$dec=$dec+$hextab[$i]*$power;
	$power=$power*16;
    }

    my $format="%20.0f";
    if (defined($opt_u)) {
	prtf ($dec,$opt_u);
    } else {
	printf "$format ",$dec;
    }
}

open (IOMEM,"cat /proc/ioports|") or die $!,"\n";

my @iomem=<IOMEM>;
close(IOMEM);

for (my $line=0; $line<=$#iomem; $line++) {
#    print $iomem[$line];

    $iomem[$line] =~ /\s*([01-9abcdef]{4})-([01-9abcdef]{4}) : (.*)/i;
    $addrLow=$1;
    $addrHigh=$2;
    $comm=$3;
    hex2dec($addrLow);hex2dec($addrHigh),print "  ",$comm,"\n";
}


