#!/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)

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