#!/usr/bin/env python3
#
# Copyright (c) 2020 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

"""Create the kernel's page tables for x86 CPUs.

For additional detail on paging and x86 memory management, please
consult the IA Architecture SW Developer Manual, volume 3a, chapter 4.

This script produces the initial page tables installed into the CPU
at early boot. These pages will have an identity mapping of the kernel
image. The script takes the 'zephyr_prebuilt.elf' as input to obtain region
sizes, certain memory addresses, and configuration values.

If CONFIG_SRAM_REGION_PERMISSIONS is not enabled, the kernel image will be
mapped with the Present and Write bits set. The linker scripts shouldn't
add page alignment padding between sections.

If CONFIG_SRAM_REGION_PERMISSIONS is enabled, the access permissions
vary:
  - By default, the Present, Write, and Execute Disable bits are
    set.
  - The _image_text region will have Present and User bits set
  - The _image_rodata region will have Present, User, and Execute
    Disable bits set
  - On x86_64, the _locore region will have Present set and
    the _lorodata region will have Present and Execute Disable set.

This script will establish a dual mapping at the address defined by
CONFIG_KERNEL_VM_BASE if it is not the same as CONFIG_SRAM_BASE_ADDRESS.

  - The double-mapping is used to transition the
    instruction pointer from a physical address at early boot to the
    virtual address where the kernel is actually linked.

  - The mapping is always double-mapped at the top-level paging structure
    and the physical/virtual base addresses must have the same alignment
    with respect to the scope of top-level paging structure entries.
    This allows the same second-level paging structure(s) to be used for
    both memory bases.

  - The double-mapping is needed so that we can still fetch instructions
    from identity-mapped physical addresses after we program this table
    into the MMU, then jump to the equivalent virtual address.
    The kernel then unlinks the identity mapping before continuing,
    the address space is purely virtual after that.

Because the set of page tables are linked together by physical address,
we must know a priori the physical address of each table. The linker
script must define a z_x86_pagetables_start symbol where the page
tables will be placed, and this memory address must not shift between
prebuilt and final ELF builds. This script will not work on systems
where the physical load address of the kernel is unknown at build time.

64-bit systems will always build IA-32e page tables. 32-bit systems
build PAE page tables if CONFIG_X86_PAE is set, otherwise standard
32-bit page tables are built.

The kernel will expect to find the top-level structure of the produced
page tables at the physical address corresponding to the symbol
z_x86_kernel_ptables. The linker script will need to set that symbol
to the end of the binary produced by this script, minus the size of the
top-level paging structure as it is written out last.
"""

import sys
import array
import argparse
import ctypes
import os
import struct
import re
import textwrap

from distutils.version import LooseVersion

import elftools
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

if LooseVersion(elftools.__version__) < LooseVersion('0.24'):
    sys.exit("pyelftools is out of date, need version 0.24 or later")


def bit(pos):
    """Get value by shifting 1 by pos"""
    return 1 << pos


# Page table entry flags
FLAG_P = bit(0)
FLAG_RW = bit(1)
FLAG_US = bit(2)
FLAG_CD = bit(4)
FLAG_SZ = bit(7)
FLAG_G = bit(8)
FLAG_XD = bit(63)

FLAG_IGNORED0 = bit(9)
FLAG_IGNORED1 = bit(10)
FLAG_IGNORED2 = bit(11)

ENTRY_RW = FLAG_RW | FLAG_IGNORED0
ENTRY_US = FLAG_US | FLAG_IGNORED1
ENTRY_XD = FLAG_XD | FLAG_IGNORED2

# PD_LEVEL and PT_LEVEL are used as list index to PtableSet.levels[]
# to get table from back of list.
PD_LEVEL = -2
PT_LEVEL = -1


def debug(text):
    """Display verbose debug message"""
    if not args.verbose:
        return
    sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n")


def verbose(text):
    """Display --verbose --verbose message"""
    if args.verbose and args.verbose > 1:
        sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n")


def error(text):
    """Display error message and exit program"""
    sys.exit(os.path.basename(sys.argv[0]) + ": " + text)


def align_check(base, size, scope=4096):
    """Make sure base and size are page-aligned"""
    if (base % scope) != 0:
        error("unaligned base address %x" % base)
    if (size % scope) != 0:
        error("Unaligned region size 0x%x for base %x" % (size, base))


def dump_flags(flags):
    """Translate page table flags into string"""
    ret = ""

    if flags & FLAG_P:
        ret += "P "

    if flags & FLAG_RW:
        ret += "RW "

    if flags & FLAG_US:
        ret += "US "

    if flags & FLAG_G:
        ret += "G "

    if flags & FLAG_XD:
        ret += "XD "

    if flags & FLAG_SZ:
        ret += "SZ "

    if flags & FLAG_CD:
        ret += "CD "

    return ret.strip()


def round_up(val, align):
    """Round up val to the next multiple of align"""
    return (val + (align - 1)) & (~(align - 1))


def round_down(val, align):
    """Round down val to the previous multiple of align"""
    return val & (~(align - 1))


# Hard-coded flags for intermediate paging levels. Permissive, we only control
# access or set caching properties at leaf levels.
INT_FLAGS = FLAG_P | FLAG_RW | FLAG_US

class MMUTable():
    """Represents a particular table in a set of page tables, at any level"""

    def __init__(self):
        self.entries = array.array(self.type_code,
                                   [0 for i in range(self.num_entries)])

    def get_binary(self):
        """Return a bytearray representation of this table"""
        # Always little-endian
        ctype = "<" + self.type_code
        entry_size = struct.calcsize(ctype)
        ret = bytearray(entry_size * self.num_entries)

        for i in range(self.num_entries):
            struct.pack_into(ctype, ret, entry_size * i, self.entries[i])
        return ret

    @property
    def supported_flags(self):
        """Class property indicating what flag bits are supported"""
        raise NotImplementedError()

    @property
    def addr_shift(self):
        """Class property for how much to shift virtual addresses to obtain
        the appropriate index in the table for it"""
        raise NotImplementedError()

    @property
    def addr_mask(self):
        """Mask to apply to an individual entry to get the physical address
        mapping"""
        raise NotImplementedError()

    @property
    def type_code(self):
        """Struct packing letter code for table entries. Either I for
        32-bit entries, or Q for PAE/IA-32e"""
        raise NotImplementedError()

    @property
    def num_entries(self):
        """Number of entries in the table. Varies by table type and paging
        mode"""
        raise NotImplementedError()

    def entry_index(self, virt_addr):
        """Get the index of the entry in this table that corresponds to the
        provided virtual address"""
        return (virt_addr >> self.addr_shift) & (self.num_entries - 1)

    def has_entry(self, virt_addr):
        """Indicate whether an entry is present in this table for the provided
        virtual address"""
        index = self.entry_index(virt_addr)

        return (self.entries[index] & FLAG_P) != 0

    def lookup(self, virt_addr):
        """Look up the physical mapping for a virtual address.

        If this is a leaf table, this is the physical address mapping. If not,
        this is the physical address of the next level table"""
        index = self.entry_index(virt_addr)

        return self.entries[index] & self.addr_mask

    def map(self, virt_addr, phys_addr, entry_flags):
        """For the table entry corresponding to the provided virtual address,
        set the corresponding physical entry in the table. Unsupported flags
        will be filtered out.

        If this is a leaf table, this is the physical address mapping. If not,
        this is the physical address of the next level table"""
        index = self.entry_index(virt_addr)

        verbose("%s: mapping 0x%x to 0x%x : %s" %
                (self.__class__.__name__,
                 phys_addr, virt_addr, dump_flags(entry_flags)))

        self.entries[index] = ((phys_addr & self.addr_mask) |
                               (entry_flags & self.supported_flags))

    def set_perms(self, virt_addr, entry_flags):
        """"For the table entry corresponding to the provided virtual address,
        update just the flags, leaving the physical mapping alone.
        Unsupported flags will be filtered out."""
        index = self.entry_index(virt_addr)

        verbose("%s: changing perm at 0x%x : %s" %
                (self.__class__.__name__,
                 virt_addr, dump_flags(entry_flags)))

        self.entries[index] = ((self.entries[index] & self.addr_mask) |
                               (entry_flags & self.supported_flags))


# Specific supported table types
class Pml4(MMUTable):
    """Page mapping level 4 for IA-32e"""
    addr_shift = 39
    addr_mask = 0x7FFFFFFFFFFFF000
    type_code = 'Q'
    num_entries = 512
    supported_flags = INT_FLAGS

class Pdpt(MMUTable):
    """Page directory pointer table for IA-32e"""
    addr_shift = 30
    addr_mask = 0x7FFFFFFFFFFFF000
    type_code = 'Q'
    num_entries = 512
    supported_flags = INT_FLAGS | FLAG_SZ | FLAG_CD

class PdptPAE(Pdpt):
    """Page directory pointer table for PAE"""
    num_entries = 4

class Pd(MMUTable):
    """Page directory for 32-bit"""
    addr_shift = 22
    addr_mask = 0xFFFFF000
    type_code = 'I'
    num_entries = 1024
    supported_flags = INT_FLAGS | FLAG_SZ | FLAG_CD

class PdXd(Pd):
    """Page directory for either PAE or IA-32e"""
    addr_shift = 21
    addr_mask = 0x7FFFFFFFFFFFF000
    num_entries = 512
    type_code = 'Q'

class Pt(MMUTable):
    """Page table for 32-bit"""
    addr_shift = 12
    addr_mask = 0xFFFFF000
    type_code = 'I'
    num_entries = 1024
    supported_flags = (FLAG_P | FLAG_RW | FLAG_US | FLAG_G | FLAG_CD |
                       FLAG_IGNORED0 | FLAG_IGNORED1)

class PtXd(Pt):
    """Page table for either PAE or IA-32e"""
    addr_mask = 0x07FFFFFFFFFFF000
    type_code = 'Q'
    num_entries = 512
    supported_flags = (FLAG_P | FLAG_RW | FLAG_US | FLAG_G | FLAG_XD | FLAG_CD |
                       FLAG_IGNORED0 | FLAG_IGNORED1 | FLAG_IGNORED2)


class PtableSet():
    """Represents a complete set of page tables for any paging mode"""

    def __init__(self, pages_start):
        """Instantiate a set of page tables which will be located in the
        image starting at the provided physical memory location"""
        self.toplevel = self.levels[0]()
        self.page_pos = pages_start

        debug("%s starting at physical address 0x%x" %
              (self.__class__.__name__, self.page_pos))

        # Database of page table pages. Maps physical memory address to
        # MMUTable objects, excluding the top-level table which is tracked
        # separately. Starts out empty as we haven't mapped anything and
        # the top-level table is tracked separately.
        self.tables = {}

    def get_new_mmutable_addr(self):
        """If we need to instantiate a new MMUTable, return a physical
        address location for it"""
        ret = self.page_pos
        self.page_pos += 4096
        return ret

    @property
    def levels(self):
        """Class hierarchy of paging levels, with the first entry being
        the toplevel table class, and the last entry always being
        some kind of leaf page table class (Pt or PtXd)"""
        raise NotImplementedError()

    def is_mapped(self, virt_addr, level):
        """
        Return True if virt_addr has already been mapped.

        level_from_last == 0 only searches leaf level page tables.
        level_from_last == 1 searches both page directories and page tables.

        """
        table = self.toplevel
        num_levels = len(self.levels) + level + 1
        has_mapping = False

        # Create and link up intermediate tables if necessary
        for depth in range(0, num_levels):
            # Create child table if needed
            if table.has_entry(virt_addr):
                if depth == num_levels:
                    has_mapping = True
                else:
                    table = self.tables[table.lookup(virt_addr)]

            if has_mapping:
                # pylint doesn't like break in the above if-block
                break

        return has_mapping

    def is_region_mapped(self, virt_base, size, level=PT_LEVEL):
        """Find out if a region has been mapped"""
        align_check(virt_base, size)
        for vaddr in range(virt_base, virt_base + size, 4096):
            if self.is_mapped(vaddr, level):
                return True

        return False

    def new_child_table(self, table, virt_addr, depth):
        """Create a new child table"""
        new_table_addr = self.get_new_mmutable_addr()
        new_table = self.levels[depth]()
        debug("new %s at physical addr 0x%x"
                      % (self.levels[depth].__name__, new_table_addr))
        self.tables[new_table_addr] = new_table
        table.map(virt_addr, new_table_addr, INT_FLAGS)

        return new_table

    def map_page(self, virt_addr, phys_addr, flags, reserve, level=PT_LEVEL):
        """Map a virtual address to a physical address in the page tables,
        with provided access flags"""
        table = self.toplevel

        num_levels = len(self.levels) + level + 1

        # Create and link up intermediate tables if necessary
        for depth in range(1, num_levels):
            # Create child table if needed
            if not table.has_entry(virt_addr):
                table = self.new_child_table(table, virt_addr, depth)
            else:
                table = self.tables[table.lookup(virt_addr)]

        # Set up entry in leaf page table
        if not reserve:
            table.map(virt_addr, phys_addr, flags)

    def reserve(self, virt_base, size, to_level=PT_LEVEL):
        """Reserve page table space with already aligned virt_base and size"""
        debug("Reserving paging structures for 0x%x (0x%x)" %
              (virt_base, size))

        align_check(virt_base, size)

        # How much memory is covered by leaf page table
        scope = 1 << self.levels[PD_LEVEL].addr_shift

        if virt_base % scope != 0:
            error("misaligned virtual address space, 0x%x not a multiple of 0x%x" %
                  (virt_base, scope))

        for addr in range(virt_base, virt_base + size, scope):
            self.map_page(addr, 0, 0, True, to_level)

    def reserve_unaligned(self, virt_base, size, to_level=PT_LEVEL):
        """Reserve page table space with virt_base and size alignment"""
        # How much memory is covered by leaf page table
        scope = 1 << self.levels[PD_LEVEL].addr_shift

        mem_start = round_down(virt_base, scope)
        mem_end = round_up(virt_base + size, scope)
        mem_size = mem_end - mem_start

        self.reserve(mem_start, mem_size, to_level)

    def map(self, phys_base, virt_base, size, flags, level=PT_LEVEL):
        """Map an address range in the page tables provided access flags.
        If virt_base is None, identity mapping using phys_base is done.
        """
        is_identity_map = virt_base is None or virt_base == phys_base

        if virt_base is None:
            virt_base = phys_base

        scope = 1 << self.levels[level].addr_shift

        debug("Mapping 0x%x (0x%x) to 0x%x: %s" %
                (phys_base, size, virt_base, dump_flags(flags)))

        align_check(phys_base, size, scope)
        align_check(virt_base, size, scope)
        for paddr in range(phys_base, phys_base + size, scope):
            if is_identity_map and paddr == 0 and level == PT_LEVEL:
                # Never map the NULL page at page table level.
                continue

            vaddr = virt_base + (paddr - phys_base)

            self.map_page(vaddr, paddr, flags, False, level)

    def identity_map_unaligned(self, phys_base, size, flags, level=PT_LEVEL):
        """Identity map a region of memory"""
        scope = 1 << self.levels[level].addr_shift

        phys_aligned_base = round_down(phys_base, scope)
        phys_aligned_end = round_up(phys_base + size, scope)
        phys_aligned_size = phys_aligned_end - phys_aligned_base

        self.map(phys_aligned_base, None, phys_aligned_size, flags, level)

    def map_region(self, name, flags, virt_to_phys_offset, level=PT_LEVEL):
        """Map a named region"""
        if not isdef(name + "_start"):
            # Region may not exists
            return

        region_start = syms[name + "_start"]
        region_end = syms[name + "_end"]
        region_size = region_end - region_start

        region_start_phys = region_start

        if virt_to_phys_offset is not None:
            region_start_phys += virt_to_phys_offset

        self.map(region_start_phys, region_start, region_size, flags, level)

    def set_region_perms(self, name, flags, level=PT_LEVEL):
        """Set access permissions for a named region that is already mapped

        The bounds of the region will be looked up in the symbol table
        with _start and _size suffixes. The physical address mapping
        is unchanged and this will not disturb any double-mapping."""
        if not isdef(name + "_start"):
            # Region may not exists
            return

        # Doesn't matter if this is a virtual address, we have a
        # either dual mapping or it's the same as physical
        base = syms[name + "_start"]

        if isdef(name + "_size"):
            size = syms[name + "_size"]
        else:
            region_end = syms[name + "_end"]
            size = region_end - base

        if size == 0:
            return

        debug("change flags for %s at 0x%x (0x%x): %s" %
              (name, base, size, dump_flags(flags)))

        num_levels = len(self.levels) + level + 1
        scope = 1 << self.levels[level].addr_shift

        align_check(base, size, scope)

        try:
            for addr in range(base, base + size, scope):
                # Never map the NULL page
                if addr == 0:
                    continue

                table = self.toplevel
                for _ in range(1, num_levels):
                    table = self.tables[table.lookup(addr)]
                table.set_perms(addr, flags)
        except KeyError:
            error("no mapping for %s region 0x%x (size 0x%x)" %
                  (name, base, size))

    def write_output(self, filename):
        """Write the page tables to the output file in binary format"""
        written_size = 0

        with open(filename, "wb") as output_fp:
            for addr in sorted(self.tables):
                mmu_table = self.tables[addr]
                mmu_table_bin = mmu_table.get_binary()
                output_fp.write(mmu_table_bin)
                written_size += len(mmu_table_bin)

            # We always have the top-level table be last. This is because
            # in PAE, the top-level PDPT has only 4 entries and is not a
            # full page in size. We do not put it in the tables dictionary
            # and treat it as a special case.
            debug("top-level %s at physical addr 0x%x" %
                  (self.toplevel.__class__.__name__,
                   self.get_new_mmutable_addr()))
            top_level_bin = self.toplevel.get_binary()
            output_fp.write(top_level_bin)
            written_size += len(top_level_bin)

        return written_size

# Paging mode classes, we'll use one depending on configuration
class Ptables32bit(PtableSet):
    """32-bit Page Tables"""
    levels = [Pd, Pt]

class PtablesPAE(PtableSet):
    """PAE Page Tables"""
    levels = [PdptPAE, PdXd, PtXd]

class PtablesIA32e(PtableSet):
    """Page Tables under IA32e mode"""
    levels = [Pml4, Pdpt, PdXd, PtXd]


def parse_args():
    """Parse command line arguments"""
    global args

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

    parser.add_argument("-k", "--kernel", required=True,
                        help="path to prebuilt kernel ELF binary")
    parser.add_argument("-o", "--output", required=True,
                        help="output file")
    parser.add_argument("--map", action='append',
                        help=textwrap.dedent('''\
                            Map extra memory:
                            <physical address>,<size>[,<flags:LUWXD>[,<virtual adderss>]]
                            where flags can be empty or combination of:
                                L - Large page (2MB or 4MB),
                                U - Userspace accessible,
                                W - Writable,
                                X - Executable,
                                D - Cache disabled.
                            Default is
                                small (4KB) page,
                                supervisor only,
                                read only,
                                and execution disabled.
                            '''))
    parser.add_argument("-v", "--verbose", action="count",
                        help="Print extra debugging information")
    args = parser.parse_args()
    if "VERBOSE" in os.environ:
        args.verbose = 1


def get_symbols(elf_obj):
    """Get all symbols from the ELF file"""
    for section in elf_obj.iter_sections():
        if isinstance(section, SymbolTableSection):
            return {sym.name: sym.entry.st_value
                    for sym in section.iter_symbols()}

    raise LookupError("Could not find symbol table")

def isdef(sym_name):
    """True if symbol is defined in ELF file"""
    return sym_name in syms


def find_symbol(obj, name):
    """Find symbol object from ELF file"""
    for section in obj.iter_sections():
        if isinstance(section, SymbolTableSection):
            for sym in section.iter_symbols():
                if sym.name == name:
                    return sym

    return None


def map_extra_regions(pt):
    """Map extra regions specified in command line"""
    # Extract command line arguments
    mappings = []

    for entry in args.map:
        elements = entry.split(',')

        if len(elements) < 2:
            error("Not enough arguments for --map %s" % entry)

        one_map = {}

        one_map['cmdline'] = entry
        one_map['phys'] = int(elements[0], 16)
        one_map['size']= int(elements[1], 16)
        one_map['large_page'] = False

        flags = FLAG_P | ENTRY_XD
        if len(elements) > 2:
            map_flags = elements[2]

            # Check for allowed flags
            if not bool(re.match('^[LUWXD]*$', map_flags)):
                error("Unrecognized flags: %s" % map_flags)

            flags = FLAG_P | ENTRY_XD
            if 'W' in map_flags:
                flags |= ENTRY_RW
            if 'X' in map_flags:
                flags &= ~ENTRY_XD
            if 'U' in map_flags:
                flags |= ENTRY_US
            if 'L' in map_flags:
                flags |=  FLAG_SZ
                one_map['large_page'] = True
            if 'D' in map_flags:
                flags |= FLAG_CD

        one_map['flags'] = flags

        if len(elements) > 3:
            one_map['virt'] = int(elements[3], 16)
        else:
            one_map['virt'] = one_map['phys']

        mappings.append(one_map)

    # Map the regions
    for one_map in mappings:
        phys = one_map['phys']
        size = one_map['size']
        flags = one_map['flags']
        virt = one_map['virt']
        level = PD_LEVEL if one_map['large_page'] else PT_LEVEL

        # Check if addresses have already been mapped.
        # Error out if so as they could override kernel mappings.
        if pt.is_region_mapped(virt, size, level):
            error(("Region 0x%x (%d) already been mapped "
                   "for --map %s" % (virt, size, one_map['cmdline'])))

        # Reserve space in page table, and map the region
        pt.reserve_unaligned(virt, size, level)
        pt.map(phys, virt, size, flags, level)


def main():
    """Main program"""
    global syms
    parse_args()

    with open(args.kernel, "rb") as elf_fp:
        kernel = ELFFile(elf_fp)
        syms = get_symbols(kernel)

        sym_dummy_pagetables = find_symbol(kernel, "dummy_pagetables")
        if sym_dummy_pagetables:
            reserved_pt_size = sym_dummy_pagetables['st_size']
        else:
            reserved_pt_size = None

    if isdef("CONFIG_X86_64"):
        pclass = PtablesIA32e
    elif isdef("CONFIG_X86_PAE"):
        pclass = PtablesPAE
    else:
        pclass = Ptables32bit

    debug("building %s" % pclass.__name__)

    vm_base = syms["CONFIG_KERNEL_VM_BASE"]
    vm_size = syms["CONFIG_KERNEL_VM_SIZE"]
    vm_offset = syms["CONFIG_KERNEL_VM_OFFSET"]

    sram_base = syms["CONFIG_SRAM_BASE_ADDRESS"]
    sram_size = syms["CONFIG_SRAM_SIZE"] * 1024

    mapped_kernel_base = syms["z_mapped_start"]
    mapped_kernel_size = syms["z_mapped_size"]

    if isdef("CONFIG_SRAM_OFFSET"):
        sram_offset = syms["CONFIG_SRAM_OFFSET"]
    else:
        sram_offset = 0

    # Figure out if there is any need to do virtual-to-physical
    # address translation
    virt_to_phys_offset = (sram_base + sram_offset) - (vm_base + vm_offset)

    if isdef("CONFIG_ARCH_MAPS_ALL_RAM"):
        image_base = sram_base
        image_size = sram_size
    else:
        image_base = mapped_kernel_base
        image_size = mapped_kernel_size

    image_base_phys = image_base + virt_to_phys_offset

    ptables_phys = syms["z_x86_pagetables_start"] + virt_to_phys_offset

    debug("Address space: 0x%x - 0x%x size 0x%x" %
          (vm_base, vm_base + vm_size - 1, vm_size))

    debug("Zephyr image: 0x%x - 0x%x size 0x%x" %
          (image_base, image_base + image_size - 1, image_size))

    if virt_to_phys_offset != 0:
        debug("Physical address space: 0x%x - 0x%x size 0x%x" %
              (sram_base, sram_base + sram_size - 1, sram_size))

    is_perm_regions = isdef("CONFIG_SRAM_REGION_PERMISSIONS")

    if image_size >= vm_size:
        error("VM size is too small (have 0x%x need more than 0x%x)" % (vm_size, image_size))

    if is_perm_regions:
        # Don't allow execution by default for any pages. We'll adjust this
        # in later calls to pt.set_region_perms()
        map_flags = FLAG_P |  ENTRY_XD
    else:
        map_flags = FLAG_P

    pt = pclass(ptables_phys)
    # Instantiate all the paging structures for the address space
    pt.reserve(vm_base, vm_size)
    # Map the zephyr image
    pt.map(image_base_phys, image_base, image_size, map_flags | ENTRY_RW)

    if virt_to_phys_offset != 0:
        # Need to identity map the physical address space
        # as it is needed during early boot process.
        # This will be unmapped once z_x86_mmu_init()
        # is called.
        # Note that this only does the identity mapping
        # at the page directory level to minimize wasted space.
        pt.reserve_unaligned(image_base_phys, image_size, to_level=PD_LEVEL)
        pt.identity_map_unaligned(image_base_phys, image_size,
                                  FLAG_P | FLAG_RW | FLAG_SZ, level=PD_LEVEL)

    if isdef("CONFIG_X86_64"):
        # 64-bit has a special region in the first 64K to bootstrap other CPUs
        # from real mode
        locore_base = syms["_locore_start"]
        locore_size = syms["_lodata_end"] - locore_base
        debug("Base addresses: physical 0x%x size 0x%x" % (locore_base,
                                                         locore_size))
        pt.map(locore_base, None, locore_size, map_flags | ENTRY_RW)

    if isdef("CONFIG_XIP"):
        # Additionally identity-map all ROM as read-only
        pt.map(syms["CONFIG_FLASH_BASE_ADDRESS"], None,
               syms["CONFIG_FLASH_SIZE"] * 1024, map_flags)

    if isdef("CONFIG_LINKER_USE_BOOT_SECTION"):
        pt.map_region("lnkr_boot", map_flags | ENTRY_RW, virt_to_phys_offset)

    if isdef("CONFIG_LINKER_USE_PINNED_SECTION"):
        pt.map_region("lnkr_pinned", map_flags | ENTRY_RW, virt_to_phys_offset)

    # Process extra mapping requests
    if args.map:
        map_extra_regions(pt)

    # Adjust mapped region permissions if configured
    if is_perm_regions:
        # Need to accomplish the following things:
        # - Text regions need the XD flag cleared and RW flag removed
        #   if not built with gdbstub support
        # - Rodata regions need the RW flag cleared
        # - User mode needs access as we currently do not separate application
        #   text/rodata from kernel text/rodata
        if isdef("CONFIG_GDBSTUB"):
            flags = FLAG_P | ENTRY_US | ENTRY_RW

        else:
            flags = FLAG_P | ENTRY_US

        pt.set_region_perms("_image_text", flags)

        if isdef("CONFIG_LINKER_USE_BOOT_SECTION"):
            pt.set_region_perms("lnkr_boot_text", flags)

        if isdef("CONFIG_LINKER_USE_PINNED_SECTION"):
            pt.set_region_perms("lnkr_pinned_text", flags)

        flags = FLAG_P | ENTRY_US | ENTRY_XD
        pt.set_region_perms("_image_rodata", flags)

        if isdef("CONFIG_LINKER_USE_BOOT_SECTION"):
            pt.set_region_perms("lnkr_boot_rodata", flags)

        if isdef("CONFIG_LINKER_USE_PINNED_SECTION"):
            pt.set_region_perms("lnkr_pinned_rodata", flags)

        if isdef("CONFIG_COVERAGE_GCOV") and isdef("CONFIG_USERSPACE"):
            # If GCOV is enabled, user mode must be able to write to its
            # common data area
            pt.set_region_perms("__gcov_bss",
                                FLAG_P | ENTRY_RW | ENTRY_US | ENTRY_XD)

        if isdef("CONFIG_X86_64"):
            # Set appropriate permissions for locore areas much like we did
            # with the main text/rodata regions

            if isdef("CONFIG_X86_KPTI"):
                # Set the User bit for the read-only locore/lorodata areas.
                # This ensures they get mapped into the User page tables if
                # KPTI is turned on. There is no sensitive data in them, and
                # they contain text/data needed to take an exception or
                # interrupt.
                flag_user = ENTRY_US
            else:
                flag_user = 0

            pt.set_region_perms("_locore", FLAG_P | flag_user)
            pt.set_region_perms("_lorodata", FLAG_P | ENTRY_XD | flag_user)

    written_size = pt.write_output(args.output)
    debug("Written %d bytes to %s" % (written_size, args.output))

    # Warn if reserved page table is not of correct size
    if reserved_pt_size and written_size != reserved_pt_size:
        # Figure out how many extra pages needed
        size_diff = written_size - reserved_pt_size
        page_size = syms["CONFIG_MMU_PAGE_SIZE"]
        extra_pages_needed = int(round_up(size_diff, page_size) / page_size)

        if isdef("CONFIG_X86_EXTRA_PAGE_TABLE_PAGES"):
            extra_pages_kconfig = syms["CONFIG_X86_EXTRA_PAGE_TABLE_PAGES"]
            if isdef("CONFIG_X86_64"):
                extra_pages_needed += ctypes.c_int64(extra_pages_kconfig).value
            else:
                extra_pages_needed += ctypes.c_int32(extra_pages_kconfig).value

        reason = "big" if reserved_pt_size > written_size else "small"

        error(("Reserved space for page table is too %s."
               " Set CONFIG_X86_EXTRA_PAGE_TABLE_PAGES=%d") %
               (reason, extra_pages_needed))


if __name__ == "__main__":
    main()
