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