#!/usr/bin/env python3

import os
import sys
import struct
import parser
from collections import namedtuple
import ctypes
import argparse

############# global variables
pd_complete = ''
inputfile = ''
outputfile = ''
list_of_pde = {}
num_of_regions = 0
read_buff=''

struct_mmu_regions_tuple = {"start_addr","size","permissions"}
mmu_region_details = namedtuple("mmu_region_details", "pde_index page_entries_info")

valid_pages_inside_pde = namedtuple("valid_pages_inside_pde","start_addr size \
                                pte_valid_addr_start \
                                pte_valid_addr_end \
                                permissions")

page_tables_list = []
pd_start_addr = 0
validation_issue_memory_overlap = [False, 0, -1]
output_offset = 0
print_string_pde_list = ''
pde_pte_string = {}
FourMB = (1024*4096) #In Bytes
#############

#return the page directory number for the give address
def get_pde_number(value):
    return( (value >> 22 ) & 0x3FF)

#return the page table number for the given address
def get_pte_number(value):
    return( (value >> 12 ) & 0x3FF)


# update the tuple values for the memory regions needed
def set_pde_pte_values(pde_index, address, mem_size,
                       pte_valid_addr_start, pte_valid_addr_end, perm):

    pages_tuple = valid_pages_inside_pde(
        start_addr = address,
        size = mem_size,
        pte_valid_addr_start = pte_valid_addr_start,
        pte_valid_addr_end = pte_valid_addr_end,
        permissions = perm)

    mem_region_values = mmu_region_details(pde_index = pde_index,
                                           page_entries_info = [])

    mem_region_values.page_entries_info.append(pages_tuple)

    if pde_index in list_of_pde.keys():
        # this step adds the new page info to the exsisting pages info
        list_of_pde[pde_index].page_entries_info.append(pages_tuple)
    else:
        list_of_pde[pde_index] = mem_region_values

def print_list_of_pde(list_of_pde):
    for key, value in list_of_pde.items():
        print(key,value)
        print('\n')


# read the binary from the input file and populate a dict for
# start address of mem region
# size of the region - so page tables entries will be created with this
# read write permissions
raw_info=[]
def read_mmu_list_marshal_param():

    global read_buff
    global page_tables_list
    global pd_start_addr
    global validation_issue_memory_overlap
    read_buff = input_file.read()
    input_file.close()


    # read contents of the binary file first 2 values read are
    # num_of_regions and page directory start address both calculated and
    # populated by the linker
    num_of_regions, pd_start_addr = struct.unpack_from(header_values_format,read_buff,0);

    # a offset used to remember next location to read in the binary
    size_read_from_binary = struct.calcsize(header_values_format);

    # for each of the regions mentioned in the binary loop and populate all the
    # required parameters
    for region in range(num_of_regions):
        basic_mem_region_values = struct.unpack_from(struct_mmu_regions_format,
                                               read_buff,
                                               size_read_from_binary);
        size_read_from_binary += struct.calcsize(struct_mmu_regions_format);

        if basic_mem_region_values[1] == 0:
            continue

        #validate for memory overlap here
        for i in raw_info:
            start_location = basic_mem_region_values[0]
            end_location = basic_mem_region_values[0] + basic_mem_region_values[1]

            overlap_occurred = ( (start_location >= i[0]) and \
             (start_location <= (i[0]+i[1]))) and \
            ((end_location >= i[0]) and \
              (end_location <= i[0]+i[1]))

            if overlap_occurred:
                validation_issue_memory_overlap = [True,
                 start_location,
                 get_pde_number(start_location)]
                return

        # add the retrived info another list
        raw_info.append(basic_mem_region_values)

    for region in raw_info:
        pde_index = get_pde_number(region[0])
        pte_valid_addr_start = get_pte_number(region[0])

        # Get the end of the page table entries
        # Since a memory region can take up only a few entries in the Page
        # table, this helps us get the last valid PTE.
        pte_valid_addr_end = get_pte_number(region[0] +
                                            region[1] - 1)

        mem_size = region[1]

        # In-case the start address aligns with a page table entry other than zero
        # and the mem_size is greater than (1024*4096) i.e 4MB
        # in case where it overflows the currenty PDE's range then limit the
        # PTE to 1024 and so make the mem_size reflect the actual size taken up
        # in the current PDE
        if (region[1] + (pte_valid_addr_start * 4096) ) >= (FourMB):
            pte_valid_addr_end = 1023
            mem_size = ( (1024 - pte_valid_addr_start)*4096)

        set_pde_pte_values(pde_index, region[0], mem_size,
                           pte_valid_addr_start, pte_valid_addr_end, region[2])


        if pde_index not in page_tables_list:
                page_tables_list.append(pde_index)

        # IF the current pde couldn't fit the entire requested region size then
        # there is a need to create new PDEs to match the size.
        # Here the overflow_size represents the size that couldn't be fit inside
        # the current PDE, this is will now to used to create a new PDE/PDEs
        # so the size remaining will be
        # requested size - allocated size(in the current PDE)

        overflow_size = region[1] - mem_size


        # create all the extra PDEs needed to fit the requested size
        # this loop starts from the current pde till the last pde that is needed
        # the last pde is calcualted as the (start_addr + size) >> 22
        if overflow_size != 0:
            for extra_pde in range(pde_index+1, get_pde_number(
                    region[0] + region[1])+1):

                # new pde's start address
                # each page directory entry has a addr range of (1024 *4096)
                # thus the new PDE start address is a multiple of that number
                extra_pde_start_address = extra_pde*(FourMB)

                # the start address of and extra pde will always be 0
                # and the end address is calculated with the new pde's start address
                # and the overflow_size
                extra_pte_valid_addr_end = get_pte_number(extra_pde_start_address
                                                          + overflow_size - 1)

                # if the overflow_size couldn't be fit inside this new pde then
                # need another pde and so we now need to limit the end of the PTE
                # to 1024 and set the size of this new region to the max possible
                extra_region_size = overflow_size
                if overflow_size >= (FourMB):
                    extra_region_size = FourMB
                    extra_pte_valid_addr_end =  1023

                # load the new PDE's details

                set_pde_pte_values(extra_pde, extra_pde_start_address,
                                   extra_region_size,
                                   0, extra_pte_valid_addr_end, region[2] )


                # for the next iteration of the loop the size needs to decreased
                overflow_size -= extra_region_size

                # print(hex_32(overflow_size),extra_pde)
                if extra_pde not in page_tables_list:
                    page_tables_list.append(extra_pde)

                if overflow_size == 0:
                    break

    page_tables_list.sort()


def validate_pde_regions():
    #validation for correct page alignment of the regions
    for key, value in list_of_pde.items():
        for pages_inside_pde in value.page_entries_info:
            if pages_inside_pde.start_addr & (0xFFF) != 0:
                print("Memory Regions are not page aligned",
                      hex(pages_inside_pde.start_addr))
                sys.exit(2)

            #validation for correct page alignment of the regions
            if pages_inside_pde.size & (0xFFF) != 0:
                print("Memory Regions size is not page aligned",
                      hex(pages_inside_pde.size))
                sys.exit(2)

    #validation for spiling of the regions across various
    if validation_issue_memory_overlap[0] == True:
        print("Memory Regions are overlapping at memory address " +
              str(hex(validation_issue_memory_overlap[1]))+
              " with Page directory Entry number " +
              str(validation_issue_memory_overlap[2]))
        sys.exit(2)





# the return value will have the page address and it is assumed to be a 4096 boundary
# hence the output of this API will be a 20bit address of the page table
def address_of_page_table(page_table_number):
    global pd_start_addr

    # location from where the Page tables will be written
    PT_start_addr = pd_start_addr + 4096
    return ( (PT_start_addr + (page_tables_list.index(page_table_number)*4096) >>12))

#     union x86_mmu_pde_pt {
# 	u32_t  value;
# 	struct {
# 		u32_t p:1;
# 		u32_t rw:1;
# 		u32_t us:1;
# 		u32_t pwt:1;
# 		u32_t pcd:1;
# 		u32_t a:1;
# 		u32_t ignored1:1;
# 		u32_t ps:1;
# 		u32_t ignored2:4;
# 		u32_t page_table:20;
# 	};
# };


def check_bits(val, bits):
    for b in bits:
        if val & (1 << b):
            return 1
    return 0

def page_directory_create_binary_file():
    global output_buffer
    global output_offset
    for pde in range(1024):
        binary_value = 0 # the page directory entry is not valid

        # if i have a valid entry to populate
        if pde in sorted(list_of_pde.keys()):
            value = list_of_pde[pde]

            perms = value.page_entries_info[0].permissions

            present = 1 << 0;
            read_write = check_bits(perms, [1, 29]) << 1;
            user_mode = check_bits(perms, [2, 28]) << 2;

            pwt = 0 << 3;
            pcd = 0 << 4;
            a = 0 << 5; # this is a read only field
            ps = 0 << 7; # this is a read only field
            page_table = address_of_page_table(value.pde_index) << 12;
            binary_value = (present | read_write | user_mode | pwt | pcd | a | ps | page_table)
            pde_verbose_output(pde, binary_value)

        struct.pack_into(write_4byte_bin,output_buffer, output_offset, binary_value)
        output_offset += struct.calcsize(write_4byte_bin)


# union x86_mmu_pte {
# 	u32_t  value;
# 	struct {
# 		u32_t p:1;
# 		u32_t rw:1;
# 		u32_t us:1;
# 		u32_t pwt:1;
# 		u32_t pcd:1;
# 		u32_t a:1;
# 		u32_t d:1;
# 		u32_t pat:1;
# 		u32_t g:1;
# 		u32_t alloc:1;
# 		u32_t custom:2;
# 		u32_t page:20;
# 	};
# };

def page_table_create_binary_file():
    global output_buffer
    global output_offset

    for key, value in sorted(list_of_pde.items()):
        for pte in range(1024):
            binary_value = 0 # the page directory entry is not valid

            valid_pte = 0
            for i in value.page_entries_info:
                temp_value = ((pte >= i.pte_valid_addr_start) and (pte <= i.pte_valid_addr_end))
                if temp_value:
                    perm_for_pte = i.permissions
                valid_pte |= temp_value

            # if i have a valid entry to populate
            if valid_pte:
                present = 1 << 0;
                read_write = ( ( perm_for_pte >> 1) & 0x1) << 1;
                user_mode = ( ( perm_for_pte >> 2) & 0x1) << 2;
                pwt = 0 << 3;
                pcd = 0 << 4;
                a = 0 << 5; # this is a read only field
                d = 0 << 6; # this is a read only field
                pat = 0 << 7
                g = 0<< 8
                alloc = 1 << 9
                custom = 0 <<10

                # This points to the actual memory in the HW
                # totally 20 bits to rep the phy address
                # first 10 is the number got from pde and next 10 is pte
                page_table = ((value.pde_index <<10) |pte) << 12;

                binary_value = (present | read_write | user_mode |
                                pwt | pcd | a | d | pat | g | alloc | custom |
                                page_table)

                pte_verbose_output(key,pte,binary_value)

            struct.pack_into(write_4byte_bin, output_buffer, output_offset, binary_value)
            output_offset += struct.calcsize(write_4byte_bin)


# Read the parameters passed to the file
def parse_args():
    global args

    parser = argparse.ArgumentParser(description = __doc__,
                                     formatter_class = argparse.RawDescriptionHelpFormatter)

    parser.add_argument("-e", "--big-endian", action="store_true",
                        help="Target encodes data in big-endian format"
                        "(little endian is the default)")

    parser.add_argument("-i", "--input",
                        help="Input file from which MMU regions are read.")
    parser.add_argument("-o", "--output",
                        help="Output file into which the page tables are written.")
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="Lists all the relavent data generated.")
    args = parser.parse_args()

# the format for writing in the binary file would be decided by the
# endian selected
def set_struct_endian_format():
    endian_string = "<"
    if args.big_endian == True:
        endian_string = ">"
    global struct_mmu_regions_format
    global header_values_format
    global write_4byte_bin

    struct_mmu_regions_format = endian_string + "III"
    header_values_format = endian_string + "II"
    write_4byte_bin = endian_string + "I"


def format_string(input_str):
    output_str = '{0: <5}'.format(str(input_str))
    return(output_str)

#format for 32bit hex value
def hex_32(input_value):
    output_value ="{0:#0{1}x}".format(input_value,10)
    return(output_value)

#format for 20bit hex value
def hex_20(input_value):
    output_value ="{0:#0{1}x}".format(input_value,7)
    return(output_value)

def pde_verbose_output(pde, binary_value):
    if args.verbose == False:
        return

    global print_string_pde_list

    present = format_string(binary_value & 0x1 )
    read_write = format_string((binary_value >> 1 ) & 0x1 )
    user_mode = format_string((binary_value >> 2 ) & 0x1 )
    pwt = format_string((binary_value >> 3 ) & 0x1 )
    pcd = format_string((binary_value >> 4 ) & 0x1 )
    a = format_string((binary_value >> 5 ) & 0x1 )
    ignored1 = format_string(0)
    ps = format_string((binary_value >> 7 ) & 0x1 )
    ignored2 = format_string(0000)
    page_table_addr = format_string( hex((binary_value >> 12 ) & 0xFFFFF))

    print_string_pde_list += ( format_string(str(pde))+" | "+(present)+ " | "+\
          (read_write)+ " | "+\
          (user_mode)+ " | "+\
          (pwt)+ " | "+\
          (pcd)+ " | "+\
          (a)+ " | "+\
          (ps)+ " | "+
          page_table_addr +"\n"
    )

def pde_print_elements():
    global print_string_pde_list
    print("PAGE DIRECTORY ")
    print(format_string("PDE")+" | "+ \
          format_string('P')  +" | "+  \
          format_string('rw')   +" | "+  \
          format_string('us')  +" | "+  \
          format_string('pwt')  +" | "+  \
          format_string('pcd')  +" | "+  \
          format_string('a')  +" | "+   \
          format_string('ps')  +" | "+  \
          format_string('Addr page table'))
    print(print_string_pde_list)
    print("END OF PAGE DIRECTORY")


def pte_verbose_output(pde, pte, binary_value):
    global pde_pte_string

    present    = format_string( str((binary_value >> 0) & 0x1))
    read_write = format_string( str((binary_value >> 1) & 0x1))
    user_mode  = format_string( str((binary_value >> 2) & 0x1))
    pwt = format_string( str((binary_value >> 3) & 0x1))
    pcd = format_string( str((binary_value >> 4) & 0x1))
    a   = format_string( str((binary_value >> 5) & 0x1))
    d   = format_string( str((binary_value >> 6) & 0x1))
    pat = format_string( str((binary_value >> 7) & 0x1))
    g   = format_string( str((binary_value >> 8) & 0x1))
    alloc  = format_string( str((binary_value >> 9) & 0x1))
    custom = format_string( str((binary_value >> 10) & 0x3))
    page_table_addr = hex_20((binary_value >> 12) & 0xFFFFF)

    print_string_list = ( format_string(str(pte))+" | "+(present)+ " | "+\
          (read_write)+ " | "+\
          (user_mode)+ " | "+\
          (pwt)+ " | "+\
          (pcd)+ " | "+\
          (a)+ " | "+\
          (d)+ " | "+\
          (pat)+ " | "+\
          (g)+ " | "+\
          (alloc)+ " | "+\
          (custom)+ " | "+\
          page_table_addr +"\n"
    )

    if pde in pde_pte_string.keys():
        pde_pte_string[pde] += (print_string_list)
    else:
        pde_pte_string[pde] = print_string_list


def pte_print_elements():
    global pde_pte_string

    for pde,print_string in sorted(pde_pte_string.items()):
        print("\nPAGE TABLE "+str(pde))

        print(format_string("PTE")+" | "+ \
              format_string('P')  +" | "+  \
              format_string('rw')   +" | "+  \
              format_string('us')  +" | "+  \
              format_string('pwt')  +" | "+  \
              format_string('pcd')  +" | "+  \
              format_string('a')  +" | "+   \
              format_string('d')  +" | "+   \
              format_string('pat')  +" | "+   \
              format_string('g')  +" | "+   \
              format_string('alloc')  +" | "+   \
              format_string('custom')  +" | "+   \
              format_string('page addr'))
        print(print_string)
        print("END OF PAGE TABLE "+ str(pde))

def verbose_output():
    if args.verbose == False:
        return

    print("\nMemory Regions as defined:")
    for info in raw_info:
        print("Memory region start address = " + hex_32(info[0]) +\
              ", Memory size = " + hex_32(info[1]) +\
              ", Permission = "+ hex(info[2]))

    print("\nTotal Page directory entries " + str(len(list_of_pde.keys())))
    count =0
    for key, value in list_of_pde.items():
        for i in value.page_entries_info:
            count+=1
            print("In Page directory entry "+format_string(value.pde_index) +\
                  ": valid start address = "+ \
                  hex_32(i.start_addr) + ", end address = " + \
                  hex_32((i.pte_valid_addr_end +1 )*4096 -1 +\
                         (value.pde_index * (FourMB))))


    pde_print_elements()
    pte_print_elements()

def main():
    global output_buffer
    parse_args()

    set_struct_endian_format()

    global input_file
    input_file = open(args.input, 'rb')

    global binary_output_file
    binary_output_file = open(args.output, 'wb')

    # inputfile= file_name
    read_mmu_list_marshal_param()

    #validate the inputs
    validate_pde_regions()

    # The size of the output buffer has to match the number of bytes we write
    # this corresponds to the number of page tables gets created.
    output_buffer = ctypes.create_string_buffer((4096)+
                                                (len(list_of_pde.keys()) *
                                                 4096))

    page_directory_create_binary_file()
    page_table_create_binary_file()

    #write the binary data into the file
    binary_output_file.write(output_buffer);
    binary_output_file.close()

    # verbose output needed by the build system
    verbose_output()

if __name__ == "__main__":
     main()
