#!/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 __text_region region will have Present and User bits set
  - The __rodata_region 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 packaging import version

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

if version.parse(elftools.__version__) < version.parse('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, allow_abbrev=False)

    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 address>]]
                            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], 0)
        one_map['size']= int(elements[1], 0)
        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")

    # Are pages in non-boot, non-pinned sections present at boot.
    is_generic_section_present = isdef("CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT")

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

    map_flags = 0

    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 = ENTRY_XD

    pt = pclass(ptables_phys)
    # Instantiate all the paging structures for the address space
    pt.reserve(vm_base, vm_size)
    # Map the zephyr image
    if is_generic_section_present:
        map_flags = map_flags | FLAG_P
        pt.map(image_base_phys, image_base, image_size, map_flags | ENTRY_RW)
    else:
        # When generic linker sections are not present in physical memory,
        # the corresponding virtual pages should not be mapped to non-existent
        # physical pages. So simply identity map them to create the page table
        # entries but without the present bit set.
        # Boot and pinned sections (if configured) will be mapped to
        # physical memory below.
        pt.map(image_base, 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 | FLAG_P | 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 | FLAG_P)

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

    if isdef("CONFIG_LINKER_USE_PINNED_SECTION"):
        pt.map_region("lnkr_pinned", map_flags | FLAG_P | 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 = ENTRY_US | ENTRY_RW
        else:
            flags = ENTRY_US

        if is_generic_section_present:
            flags = flags | FLAG_P

        pt.set_region_perms("__text_region", flags)

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

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

        flags = ENTRY_US | ENTRY_XD
        if is_generic_section_present:
            flags = flags | FLAG_P

        pt.set_region_perms("__rodata_region", flags)

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

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

        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()
