/* SPDX-License-Identifier: GPL-2.0-only */

package main

import "bufio"
import "encoding/binary"
import "encoding/csv"
import "flag"
import "fmt"
import "io"
import "log"
import "os"
import "path/filepath"
import "sort"
import "strconv"
import "strings"

// This program generates 32-bit PAE page tables based on a CSV input file.
// By default each PDPTE entry is allocated a PD page such that it's easy
// fault in new entries that are 2MiB aligned and size.

var iomapFilePtr = flag.String("iomap_file", "", "CSV file detailing page table mapping")
var ptCFilePtr = flag.String("pt_output_c_file", "", "File to write page tables to in C code")
var ptBinFilePtr = flag.String("pt_output_bin_file", "", "File to write page tables to in binary")
var pdptCFilePtr = flag.String("pdpt_output_c_file", "", "File to write PDPT to in C code")
var pdptBinFilePtr = flag.String("pdpt_output_bin_file", "", "File to write PDPT to in binary")
var pagesBaseAddress = flag.Uint64("metadata_base_address", BASE_ADDR, "Physical base address where metadata pages allocated from")

var generatedCodeLicense string =
`/*
 * Copyright 2018 Generated Code
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ` + "``" + `AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
`

const (
	PAT_UC      = 0
	PAT_WC      = 1
	PAT_WT      = 4
	PAT_WP      = 5
	PAT_WB      = 6
	PAT_UCMINUS = 7

	COMMENT_CHAR = '#'

	NUM_PDPTE = 4
	NUM_PDE   = 512
	NUM_PTE   = 512

	SIZE_4KiB = uint64(1 << 12)
	MASK_4KiB = SIZE_4KiB - 1
	SIZE_2MiB = uint64(1 << 21)
	MASK_2MiB = SIZE_2MiB - 1

	// This is a fake physical address for doing fixups when loading
	// the page tables. There's room for 4096 4KiB physical PD or PTE
	// tables. Anything with the present bit set will be pointing to an
	// offset based on this address. At runtime the entries will be fixed up
	BASE_ADDR = uint64(0xaa000000)

	// Size of PD and PT structures
	METADATA_TABLE_SIZE = 4096

	PDPTE_PRES = uint64(1 << 0)
	PDPTE_PWT  = uint64(1 << 3)
	PDPTE_PCD  = uint64(1 << 4)

	PDE_PRES = uint64(1 << 0)
	PDE_RW   = uint64(1 << 1)
	PDE_US   = uint64(1 << 2)
	PDE_PWT  = uint64(1 << 3)
	PDE_PCD  = uint64(1 << 4)
	PDE_A    = uint64(1 << 5)
	PDE_D    = uint64(1 << 6) // only valid with PS=1
	PDE_PS   = uint64(1 << 7)
	PDE_G    = uint64(1 << 8)  // only valid with PS=1
	PDE_PAT  = uint64(1 << 12) // only valid with PS=1
	PDE_XD   = uint64(1 << 63)

	PTE_PRES = uint64(1 << 0)
	PTE_RW   = uint64(1 << 1)
	PTE_US   = uint64(1 << 2)
	PTE_PWT  = uint64(1 << 3)
	PTE_PCD  = uint64(1 << 4)
	PTE_A    = uint64(1 << 5)
	PTE_D    = uint64(1 << 6)
	PTE_PAT  = uint64(1 << 7)
	PTE_G    = uint64(1 << 8)
	PTE_XD   = uint64(1 << 63)

	PDPTE_IDX_SHIFT = 30
	PDPTE_IDX_MASK  = 0x3

	PDE_IDX_SHIFT = 21
	PDE_IDX_MASK  = 0x1ff

	PTE_IDX_SHIFT = 12
	PTE_IDX_MASK  = 0x1ff
)

// Different 'writers' implement this interface.
type pageTableEntryWriter interface {
	WritePageEntry(data interface{}) error
}

// The full page objects, page directories and page tables, implement this
// interface to write their entire contents out
type pageTableWriter interface {
	WritePage(wr pageTableEntryWriter) error
}

type binaryWriter struct {
	wr io.Writer
}

func (bw *binaryWriter) WritePageEntry(data interface{}) error {
	return binary.Write(bw.wr, binary.LittleEndian, data)
}

type cWriter struct {
	name         string
	wr           io.Writer
	totalEntries uint
	currentIndex uint
}

func newCWriter(wr io.Writer, name string, nr_entries uint) *cWriter {
	cw := &cWriter{wr: wr, name: name, totalEntries: nr_entries}
	return cw
}

func (cw *cWriter) WritePageEntry(data interface{}) error {
	var entry uint64
	doPrint := false

	entry, ok := data.(uint64)
	if !ok {
		return fmt.Errorf("entry not uint64 %T", data)
	}

	if cw.currentIndex == 0 {
		if _, err := fmt.Fprint(cw.wr, generatedCodeLicense); err != nil {
			return err
		}
		if _, err := fmt.Fprintf(cw.wr, "/* Generated by:\n  util/x86/%s %s\n */\n",
			filepath.Base(os.Args[0]),
			strings.Join(os.Args[1:], " ")); err != nil {
			return err
		}
		includes := []string{
			"stdint.h",
		}
		for _, l := range includes {
			if _, err := fmt.Fprintf(cw.wr, "#include <%s>\n", l); err != nil {
				return err
			}
		}

		if _, err := fmt.Fprintf(cw.wr, "uint64_t %s[] = {\n", cw.name); err != nil {
			return err
		}
	}

	if cw.currentIndex%NUM_PTE == 0 {
		doPrint = true
		page_num := cw.currentIndex / NUM_PTE
		if _, err := fmt.Fprintf(cw.wr, "\t/* Page %d */\n", page_num); err != nil {
			return err
		}
	}

	// filter out 0 entries
	if entry != 0 || doPrint {
		_, err := fmt.Fprintf(cw.wr, "\t[%d] = %#016xULL,\n", cw.currentIndex, entry)
		if err != nil {
			return err
		}
	}

	cw.currentIndex += 1

	if cw.currentIndex == cw.totalEntries {
		if _, err := fmt.Fprintln(cw.wr, "};"); err != nil {
			return err
		}
	}

	return nil
}

// This map represents what the IA32_PAT MSR should be at runtime. The indices
// are what the linux kernel uses. Reserved entries are not used.
//  0    WB : _PAGE_CACHE_MODE_WB
//  1    WC : _PAGE_CACHE_MODE_WC
//  2    UC-: _PAGE_CACHE_MODE_UC_MINUS
//  3    UC : _PAGE_CACHE_MODE_UC
//  4    WB : Reserved
//  5    WP : _PAGE_CACHE_MODE_WP
//  6    UC-: Reserved
//  7    WT : _PAGE_CACHE_MODE_WT
// In order to use WP and WC then the IA32_PAT MSR needs to be updated
// as these are not the power on reset values.
var patMsrIndexByType = map[uint]uint{
	PAT_WB:      0,
	PAT_WC:      1,
	PAT_UCMINUS: 2,
	PAT_UC:      3,
	PAT_WP:      5,
	PAT_WT:      7,
}

type addressRange struct {
	begin uint64
	end   uint64
	pat   uint
	nx    bool
}

type addrRangeMerge func(a, b *addressRange) bool

func (ar *addressRange) Size() uint64 {
	return ar.end - ar.begin
}

func (ar *addressRange) Base() uint64 {
	return ar.begin
}

func (ar *addressRange) Pat() uint {
	return ar.pat
}

func (ar *addressRange) Nx() bool {
	return ar.nx
}

func (ar *addressRange) String() string {
	var nx string
	if ar.nx {
		nx = "NX"
	} else {
		nx = "  "
	}
	return fmt.Sprintf("%016x -- %016x %s %s", ar.begin, ar.end, patTypeToString(ar.pat), nx)
}

type pageTableEntry struct {
	physAddr uint64
	flags    uint64
}

func (pte *pageTableEntry) Encode() uint64 {
	return pte.physAddr | pte.flags
}

func ptePatFlags(base uint64, pat uint) uint64 {
	idx, ok := patMsrIndexByType[pat]
	patStr, _ := patTypesToString[pat]

	if !ok {
		log.Fatalf("Invalid pat entry for page %x: %s\n", base, patStr)
	}

	switch idx {
	case 0:
		return 0
	case 1:
		return PTE_PWT
	case 2:
		return PTE_PCD
	case 3:
		return PTE_PCD | PTE_PWT
	case 4:
		return PTE_PAT
	case 5:
		return PTE_PAT | PTE_PWT
	case 6:
		return PTE_PAT | PTE_PCD
	case 7:
		return PTE_PAT | PTE_PCD | PTE_PWT
	}

	log.Fatalf("Invalid PAT index %d for PTE %x %s\n", idx, base, patStr)
	return 0
}

func (pte *pageTableEntry) SetMapping(base uint64, pat uint, nx bool) {
	// Present and accessed
	pte.flags |= PTE_PRES | PTE_A

	// Non write protected entries mark as writable and dirty
	if pat != PAT_WP {
		pte.flags |= PTE_RW
		pte.flags |= PTE_D
	}

	if nx {
		pte.flags |= PTE_XD
	}

	pte.flags |= ptePatFlags(base, pat)
	pte.physAddr = base
}

type pageTable struct {
	ptes [NUM_PTE]pageTableEntry
}

func (pt *pageTable) WritePage(wr pageTableEntryWriter) error {
	for i := range pt.ptes {
		pte := &pt.ptes[i]
		err := wr.WritePageEntry(pte.Encode())
		if err != nil {
			return err
		}
	}
	return nil
}

type pageDirectoryEntry struct {
	physAddr uint64
	flags    uint64
	pt       *pageTable
}

func (pde *pageDirectoryEntry) Encode() uint64 {
	return pde.physAddr | pde.flags
}

func pdeTablePatFlags(pat uint) uint64 {
	idx, ok := patMsrIndexByType[pat]
	patStr, _ := patTypesToString[pat]

	if !ok || idx >= 4 {
		log.Fatalf("Invalid pat entry for PDE page table %s\n", patStr)
	}

	switch idx {
	case 0:
		return 0
	case 1:
		return PDE_PWT
	case 2:
		return PDE_PCD
	case 3:
		return PDE_PCD | PDE_PWT
	}

	log.Fatalf("Invalid PAT index %d for PDE page table %s\n", idx, patStr)
	return 0
}

func pdeLargePatFlags(base uint64, pat uint) uint64 {
	idx, ok := patMsrIndexByType[pat]
	patStr, _ := patTypesToString[pat]

	if !ok {
		log.Fatalf("Invalid pat entry for large page %x: %s\n", base, patStr)
	}

	switch idx {
	case 0:
		return 0
	case 1:
		return PDE_PWT
	case 2:
		return PDE_PCD
	case 3:
		return PDE_PCD | PDE_PWT
	case 4:
		return PDE_PAT
	case 5:
		return PDE_PAT | PDE_PWT
	case 6:
		return PDE_PAT | PDE_PCD
	case 7:
		return PDE_PAT | PDE_PCD | PDE_PWT
	}

	log.Fatalf("Invalid PAT index %d for PDE %x %s\n", idx, base, patStr)
	return 0
}

func (pde *pageDirectoryEntry) SetPageTable(pt_addr uint64, pat uint) {
	// Set writable for whole region covered by page table. Individual
	// ptes will have the correct writability flags
	pde.flags |= PDE_PRES | PDE_A | PDE_RW

	pde.flags |= pdeTablePatFlags(pat)

	pde.physAddr = pt_addr
}

func (pde *pageDirectoryEntry) SetMapping(base uint64, pat uint, nx bool) {
	// Present, accessed, and large
	pde.flags |= PDE_PRES | PDE_A | PDE_PS

	// Non write protected entries mark as writable and dirty
	if pat != PAT_WP {
		pde.flags |= PDE_RW
		pde.flags |= PDE_D
	}

	if nx {
		pde.flags |= PDE_XD
	}

	pde.flags |= pdeLargePatFlags(base, pat)
	pde.physAddr = base
}

type pageDirectory struct {
	pdes [NUM_PDE]pageDirectoryEntry
}

func (pd *pageDirectory) WritePage(wr pageTableEntryWriter) error {
	for i := range pd.pdes {
		pde := &pd.pdes[i]
		err := wr.WritePageEntry(pde.Encode())
		if err != nil {
			return nil
		}
	}
	return nil
}

type pageDirectoryPointerEntry struct {
	physAddr uint64
	flags    uint64
	pd       *pageDirectory
}

func (pdpte *pageDirectoryPointerEntry) Encode() uint64 {
	return pdpte.physAddr | pdpte.flags
}

func (pdpte *pageDirectoryPointerEntry) Init(addr uint64, pat uint) {
	idx, ok := patMsrIndexByType[pat]

	// Only 2 bits worth of PAT indexing in PDPTE
	if !ok || idx >= 4 {
		patStr, _ := patTypesToString[pat]
		log.Fatalf("Can't use type '%s' as PDPTE type.\n", patStr)
	}

	pdpte.physAddr = addr
	pdpte.flags = PDPTE_PRES

	switch idx {
	case 0:
		pdpte.flags |= 0
	case 1:
		pdpte.flags |= PDPTE_PWT
	case 2:
		pdpte.flags |= PDPTE_PCD
	case 3:
		pdpte.flags |= PDPTE_PCD | PDPTE_PWT
	default:
		log.Fatalf("Invalid PAT index %d for PDPTE\n", idx)
	}
}

type addressSpace struct {
	ranges            []*addressRange
	mergeFunc         addrRangeMerge
	metatdataBaseAddr uint64
	pdptes            [NUM_PDPTE]pageDirectoryPointerEntry
	numMetaPages      uint
	page_writers      []pageTableWriter
}

func (as *addressSpace) newPage(pw pageTableWriter) uint64 {
	v := as.metatdataBaseAddr + METADATA_TABLE_SIZE*uint64(as.numMetaPages)
	as.numMetaPages += 1
	as.page_writers = append(as.page_writers, pw)
	return v
}

func newAddrSpace(mergeFunc addrRangeMerge, metatdataBaseAddr uint64) *addressSpace {
	as := &addressSpace{mergeFunc: mergeFunc, metatdataBaseAddr: metatdataBaseAddr}
	// Fill in all PDPTEs
	for i := range as.pdptes {
		pdpte := &as.pdptes[i]
		pdpte.pd = &pageDirectory{}
		// fetch paging structures as WB
		pdpte.Init(as.newPage(pdpte.pd), PAT_WB)
	}
	return as
}

func (as *addressSpace) deleteEntries(indices []int) {
	// deletions need to be processed in reverse order so as not
	// delete the wrong entries
	sort.Sort(sort.Reverse(sort.IntSlice(indices)))
	for _, i := range indices {
		as.ranges = append(as.ranges[:i], as.ranges[i+1:]...)
	}
}

func (as *addressSpace) mergeRanges() {
	var toRemove []int
	var prev *addressRange

	for i, cur := range as.ranges {
		if prev == nil {
			prev = cur
			continue
		}

		// merge previous with current
		if as.mergeFunc(prev, cur) {
			prev.end = cur.end
			toRemove = append(toRemove, i)
			cur = prev
		}
		prev = cur
	}

	as.deleteEntries(toRemove)
}

type addressRangeSlice []*addressRange

func (p addressRangeSlice) Len() int {
	return len(p)
}

func (p addressRangeSlice) Less(i, j int) bool {
	return !p[i].After(p[j])
}

func (p addressRangeSlice) Swap(i, j int) {
	p[i], p[j] = p[j], p[i]
}

func (as *addressSpace) insertRange(r *addressRange) {
	as.ranges = append(as.ranges, r)
	sort.Sort(addressRangeSlice(as.ranges))
}

// Remove complete entries or trim existing ones
func (as *addressSpace) trimRanges(r *addressRange) {
	var toRemove []int

	// First remove all entries that are completely overlapped
	for i, cur := range as.ranges {
		if r.FullyOverlaps(cur) {
			toRemove = append(toRemove, i)
			continue
		}
	}
	as.deleteEntries(toRemove)

	var ar *addressRange

	// Process partial overlaps
	for _, cur := range as.ranges {
		// Overlapping may be at beginning, middle, end. Only the
		// middle overlap needs to create a new range since the
		// beginning and end overlap can just adjust the current
		// range.
		if r.Overlaps(cur) {

			// beginning overlap
			if r.begin <= cur.begin {
				cur.begin = r.end
				continue
			}

			// end overlap
			if r.end >= cur.end {
				cur.end = r.begin
				continue
			}

			// middle overlap. create new entry from the hole
			// punched in the current entry. There's nothing
			// further to do after this
			begin := r.end
			end := cur.end
			pat := cur.pat
			nx := cur.nx

			// current needs new ending
			cur.end = r.begin

			ar = newAddrRange(begin, end, pat, nx)

			break
		}
	}

	if ar != nil {
		as.insertRange(ar)
	}
}

func (as *addressSpace) PrintEntries() {
	for _, cur := range as.ranges {
		log.Println(cur)
	}
}

func (as *addressSpace) AddRange(r *addressRange) {
	as.trimRanges(r)
	as.insertRange(r)
	as.mergeRanges()
}

func (as *addressSpace) insertMapping(base uint64, size uint64, pat uint, nx bool) {
	pdpteIndex := (base >> PDPTE_IDX_SHIFT) & PDPTE_IDX_MASK
	pdeIndex := (base >> PDE_IDX_SHIFT) & PDE_IDX_MASK
	pteIndex := (base >> PTE_IDX_SHIFT) & PTE_IDX_MASK

	pd := as.pdptes[pdpteIndex].pd
	pde := &pd.pdes[pdeIndex]

	if size == SIZE_2MiB {
		pde.SetMapping(base, pat, nx)
		return
	}

	if pde.pt == nil {
		pde.pt = &pageTable{}
		// Fetch paging structures as WB
		pde.SetPageTable(as.newPage(pde.pt), PAT_WB)
	}

	pte := &pde.pt.ptes[pteIndex]
	pte.SetMapping(base, pat, nx)
}

func (as *addressSpace) CreatePageTables() {
	var size uint64
	var base uint64

	for _, r := range as.ranges {
		size = r.Size()
		base = r.Base()
		pat := r.Pat()
		nx := r.Nx()

		numSmallEntries := 0
		numBigEntries := 0

		for size != 0 {
			mappingSize := SIZE_4KiB

			if (base&MASK_2MiB) == 0 && size >= SIZE_2MiB {
				mappingSize = SIZE_2MiB
				numBigEntries += 1
			} else {
				numSmallEntries += 1
			}

			as.insertMapping(base, mappingSize, pat, nx)

			base += mappingSize
			size -= mappingSize

		}

		log.Printf("%s : %d big %d small\n", r, numBigEntries, numSmallEntries)
	}
}

func (as *addressSpace) PageTableSize() uint {
	return as.numMetaPages * METADATA_TABLE_SIZE
}

func (as *addressSpace) NumPages() uint {
	return as.numMetaPages
}

func (as *addressSpace) WritePageTable(ptew pageTableEntryWriter) error {
	for _, pw := range as.page_writers {
		err := pw.WritePage(ptew)
		if err != nil {
			return err
		}
	}

	return nil
}

func (as *addressSpace) WritePageDirectoryPointerTable(ptew pageTableEntryWriter) error {
	for i := range as.pdptes {
		err := ptew.WritePageEntry(as.pdptes[i].Encode())
		if err != nil {
			return err
		}
	}

	return nil
}

var pat_types_from_str = map[string]uint{
	"UC":  PAT_UC,
	"WC":  PAT_WC,
	"WT":  PAT_WT,
	"WP":  PAT_WP,
	"WB":  PAT_WB,
	"UC-": PAT_UCMINUS,
}

var patTypesToString = map[uint]string{
	PAT_UC:      "UC",
	PAT_WC:      "WC",
	PAT_WT:      "WT",
	PAT_WP:      "WP",
	PAT_WB:      "WB",
	PAT_UCMINUS: "UC-",
}

func openCsvFile(file string) (*csv.Reader, error) {
	f, err := os.Open(file)

	if err != nil {
		return nil, err
	}

	csvr := csv.NewReader(f)
	csvr.Comment = COMMENT_CHAR
	csvr.TrimLeadingSpace = true
	return csvr, nil
}

// After returns true if ar beings at or after other.end.
func (ar addressRange) After(other *addressRange) bool {
	return ar.begin >= other.end
}

func (ar addressRange) FullyOverlaps(other *addressRange) bool {
	return ar.begin <= other.begin && ar.end >= other.end
}

func (ar addressRange) Overlaps(other *addressRange) bool {
	if other.end <= ar.begin || other.begin >= ar.end {
		return false
	}
	return true
}

func MergeByPat(a, b *addressRange) bool {
	// 'b' is assumed to be following 'a'
	if a.end != b.begin {
		return false
	}

	if a.pat != b.pat {
		return false
	}

	return true
}

func MergeByNx(a, b *addressRange) bool {
	// 'b' is assumed to be following 'a'
	if a.end != b.begin {
		return false
	}

	if a.nx != b.nx {
		return false
	}

	return true
}

func MergeByPatNx(a, b *addressRange) bool {
	return MergeByPat(a, b) && MergeByNx(a, b)
}

func hexNumber(s string) (uint64, error) {
	return strconv.ParseUint(strings.TrimSpace(s), 0, 0)
}

func patTypeToString(pat uint) string {
	return patTypesToString[pat]
}

func patTypeFromString(s string) (uint, error) {
	s1 := strings.TrimSpace(s)
	v, ok := pat_types_from_str[s1]

	if !ok {
		return 0, fmt.Errorf("No PAT type '%s'", s1)
	}

	return v, nil
}

func removeComment(field, comment string) string {
	str_slice := strings.Split(field, comment)
	return strings.TrimSpace(str_slice[0])
}

func newAddrRange(begin, end uint64, pat uint, nx bool) *addressRange {
	return &addressRange{begin: begin, end: end, pat: pat, nx: nx}
}

func readRecords(csvr *csv.Reader, as *addressSpace) {
	i := 0
	for true {
		fields, err := csvr.Read()
		i++

		if err == io.EOF {
			break
		}

		if err != nil {
			log.Fatal(err)
		}

		if len(fields) < 3 {
			log.Fatal("Need at least 3 fields: begin, end, PAT\n")
		}

		begin, err := hexNumber(fields[0])

		if err != nil {
			log.Fatal(err)
		}

		end, err := hexNumber(fields[1])

		if err != nil {
			log.Fatal(err)
		}

		if begin&MASK_4KiB != 0 {
			log.Fatalf("begin %x must be at least 4KiB aligned\n", begin)
		}

		if end&MASK_4KiB != 0 {
			log.Fatalf("end %x must be at least 4KiB aligned\n", end)
		}
		if begin >= end {
			log.Fatalf("%x must be < %x at record %d\n", begin, end, i)
		}

		pat, err := patTypeFromString(fields[2])

		if err != nil {
			log.Fatal(err)
		}

		var nx bool = false

		if len(fields) > 3 && len(removeComment(fields[3], string(COMMENT_CHAR))) > 0 {
			nx = true
		}

		as.AddRange(newAddrRange(begin, end, pat, nx))
	}
}

func main() {
	log.SetFlags(0)
	flag.Parse()
	var ptWriters []pageTableEntryWriter
	var pdptWriters []pageTableEntryWriter

	if *iomapFilePtr == "" {
		log.Fatal("No iomap_file provided.\n")
	}

	csvr, err := openCsvFile(*iomapFilePtr)
	if err != nil {
		log.Fatal(err)
	}

	as := newAddrSpace(MergeByPatNx, *pagesBaseAddress)
	readRecords(csvr, as)

	log.Println("Merged address space:")
	as.CreatePageTables()
	log.Println()
	log.Printf("Total Pages of page tables: %d\n", as.NumPages())
	log.Println()
	log.Printf("Pages linked using base address of %#x.\n", *pagesBaseAddress)

	if *ptCFilePtr != "" {
		f, err := os.Create(*ptCFilePtr)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		bwr := bufio.NewWriter(f)
		defer bwr.Flush()
		cw := newCWriter(bwr, "page_tables", as.NumPages()*NUM_PTE)
		ptWriters = append(ptWriters, cw)
	}

	if *ptBinFilePtr != "" {
		f, err := os.Create(*ptBinFilePtr)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		bwr := bufio.NewWriter(f)
		defer bwr.Flush()
		bw := &binaryWriter{wr: bwr}
		ptWriters = append(ptWriters, bw)
	}

	if *pdptCFilePtr != "" {
		f, err := os.Create(*pdptCFilePtr)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		bwr := bufio.NewWriter(f)
		defer bwr.Flush()
		cw := newCWriter(bwr, "pdptes", NUM_PDPTE)
		pdptWriters = append(pdptWriters, cw)
	}

	if *pdptBinFilePtr != "" {
		f, err := os.Create(*pdptBinFilePtr)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		bwr := bufio.NewWriter(f)
		defer bwr.Flush()
		bw := &binaryWriter{wr: bwr}
		pdptWriters = append(pdptWriters, bw)
	}

	// Write out page tables
	for _, w := range ptWriters {
		err = as.WritePageTable(w)
		if err != nil {
			log.Fatal(err)
		}
	}

	// Write out pdptes
	for _, w := range pdptWriters {
		err = as.WritePageDirectoryPointerTable(w)
		if err != nil {
			log.Fatal(err)
		}
	}
}
